I've answered these questions too many times so here's the definitive FAQ. (Last updated in 2001, though afaik the answers have not changed much as of 2007.)

Short answer: how to set the color of a widget

In GTK+ 1.2:

  GtkRcStyle *rc_style;
  GdkColor color;

  /* There are two good ways to fill in a color */

  /* 1) Initialize r/g/b components, they are 16-bit values */
  color.red = 65535;
  color.green = 0;
  color.blue = 0;

  /* 2) Parse a color string; an HTML color spec such as "#FF0000"
   * is allowed here too
   */
  gdk_color_parse ("red", &color);


  /* After filling in your GdkColor, create a GtkRcStyle */

  rc_style = gtk_rc_style_new ();

  /* Set foreground (fg) color in normal state to red */
  rc_style->fg[GTK_STATE_NORMAL] = color;

  /* Indicate which colors the GtkRcStyle will affect; 
   * unflagged colors will follow the theme
   */
  rc_style->color_flags[GTK_STATE_NORMAL] |= GTK_RC_FG;

  gtk_widget_modify_style (widget, rc_style);

  gtk_rc_style_unref (rc_style);

In GTK+ 2.0:

  GdkColor color;

  gdk_color_parse ("red", &color);

  gtk_widget_modify_fg (widget, GTK_STATE_NORMAL, &color);

There's at least one other good way to set the color of a widget, which is to use a resource file; read on. If you have problems, look at the FAQs below.

Lecture

<lecture> Because colors in GTK+ represent a theme the user has chosen, you should never set colors purely for aesthetic reasons. If users don't like GTK+ gray, they can change it themselves to their favorite shade of orange. </lecture>

Overview

People often want to set the color of a GTK+ widget. It isn't quite that simple; widgets have a number of colors. There's the color for the foreground, for the background, for the selection, when the widget is prelighted, and so on.

These colors come from the currently-active theme. Themes are prepackaged bundles of appearance settings chosen by the user. In a GTK+ program, the current theme is represented by an object called the "style." Each widget has a style, stored in widget->style. A group of widgets may share the same style; styles may change while the program is running, if the user changes themes.

Themes are implemented as rc files. That is, themes are resource files containing descriptions of widget styles including colors; when parsed, such a description is stored in a GtkRcStyle object. One or more GtkRcStyle objects can apply to a given widget. When the theme changes, or when GTK+ starts up, resource files are parsed, and a GtkStyle will be derived from a widget's list of GtkRcStyle and stored in widget->style. This will determine the widget's colors.

How can I set the color from a resource file?

Step one is to set the name of the widget you want to affect. For example:

  gtk_widget_set_name (widget, "myapp-special-widget");

Then create an rc file with contents along these lines:

style "my-special-style"
{
  fg[NORMAL] = { 1.0, 0, 0 }
}

widget "myapp-special-widget" style "my-special-style"

Then you need to arrange to parse the rc file with gtk_rc_parse() or gtk_rc_add_default_file(), which probably means you need to arrange to install the rc file. But this isn't a Makefile FAQ so I won't explain how to do that.

You could also just parse the above rc file text with gtk_rc_parse_string(), to avoid having to install/parse a file.

Believe it or not, there's documentation on all this; see GTK+ 2.0 rc files docs or GTK+ 1.2 rc files docs.

Why use a resource file rather than gtk_widget_modify_style() or gtk_widget_modify_fg()?

The main reason is that users could override your chosen color with their own rc file, ~/.gtkrc (or ~/.gtkrc-2.0 for GTK+ 2.0).

What are the available colors and widget states, and what do they mean?

Briefly, the colors are:

  • text: text for entries and text widgets (although in GTK 1.2 sometimes fg gets used, this is more or less a bug and fixed in GTK 2.0).
  • base: background when using text, colored white in the default theme.
  • fg: foreground for drawing GtkLabel
  • bg: the usual background color, gray by default

The states are:

  • normal: normal state.
  • active: pressed-in or activated; e.g. buttons while the mouse button is held down.
  • prelight: color when the mouse is over an activatable widget.
  • insensitive: color when the widget is disabled (gtk_widget_set_sensitive() disables a widget).
  • selected: color when something is selected, e.g. when selecting some text to cut/copy.

These are also in the API documentation, with more details; see GTK+ 2.0 rc files docs or GTK+ 1.2 rc files docs.

Why doesn't setting the color work for me?

  • One possible reason is that the GUI element you want to affect is actually drawn with the text, base, etc. color instead of whatever color you are setting.
  • Another possible reason is that you are setting the color on the wrong widget; for example, to change the text color of a button, you need to set the color of the label inside the button, not the color of the button itself, because the label actually draws the text.
  • Yet another possible reason is that some widgets don't have backgrounds; e.g. label widgets. They merely display the background of their parent (i.e. they are transparent). So set the background on their parent; if you want to set the background of a rectangular area around a label, try placing the label in a GtkEventBox widget and setting the background on that.

Shouldn't this be easier?

Probably so, we gave it a good shot in GTK+ 2.0 with gtk_widget_modify_fg(), gtk_widget_modify_bg(), and so on replacing the pesky messing around with GtkRcStyle.