I have written a C language program with many GtkEntry
's for data input. I have created the UI using Glade and the GtkEntry
s emit an on_entry#_changed()
signal when modified. My program checks the validity of the input, which has certain requirements. e.g., must be valid hexadecimal.
I would like the background of a GtkEntry
to go red while it is invalid, and turn back to the original color when acceptable. The original color is dependent upon the desktop style set by the user. For example, on Ubuntu, I'm using a "Dark" style, so the box is dark gray.
What is the best way to implement this background color switching so that it applies to an individual GtkEntry
and renders the user's chosen style color when the data is ok? I see a lot of discussion out there but it is often using deprecated functions.
You can use the error
style class to mark the entry as having error. The following is a minimal example that checks if an entry has a valid hex digit and updates the entry style:
/* main.c
*
* Compile: cc -ggdb main.c -o main $(pkg-config --cflags --libs gtk+-3.0) -o main
* Run: ./main
*
* Author: Mohammed Sadiq <www.sadiqpk.org>
*
* SPDX-License-Identifier: LGPL-2.1-or-later OR CC0-1.0
*/
#include <gtk/gtk.h>
static void
entry_changed_cb (GtkEntry *entry)
{
GtkStyleContext *style;
const char *text;
gboolean empty;
g_assert (GTK_IS_ENTRY (entry));
style = gtk_widget_get_style_context (GTK_WIDGET (entry));
text = gtk_entry_get_text (entry);
empty = !*text;
/* Loop until we reach an invalid hex digit or the end of the string */
while (g_ascii_isxdigit (*text))
text++;
if (empty || *text)
gtk_style_context_add_class (style, "error");
else
gtk_style_context_remove_class (style, "error");
}
static void
app_activated_cb (GtkApplication *app)
{
GtkWindow *window;
GtkWidget *entry;
window = GTK_WINDOW (gtk_application_window_new (app));
entry = gtk_entry_new ();
gtk_widget_set_halign (entry, GTK_ALIGN_CENTER);
gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
gtk_widget_show (entry);
gtk_container_add (GTK_CONTAINER (window), entry);
g_signal_connect_object (entry, "changed",
G_CALLBACK (entry_changed_cb),
app, G_CONNECT_AFTER);
entry_changed_cb (GTK_ENTRY (entry));
gtk_window_present (window);
}
int
main (int argc,
char *argv[])
{
g_autoptr(GtkApplication) app = gtk_application_new (NULL, 0);
g_signal_connect (app, "activate", G_CALLBACK (app_activated_cb), NULL);
return g_application_run (G_APPLICATION (app), argc, argv);
}