GTK+ Widgets II
last modified October 18, 2023
In this part of the GTK+ programming tutorial, we continue covering various GTK+ widgets.
GktComboBoxText
GktComboBoxText
is a widget that allows the user to choose
from a list of options. The options are strings.
#include <gtk/gtk.h> void combo_selected(GtkWidget *widget, gpointer window) { gchar *text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); gtk_label_set_text(GTK_LABEL(window), text); g_free(text); } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *hbox; GtkWidget *vbox; GtkWidget *combo; GtkWidget *label; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "GtkComboBox"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_container_set_border_width(GTK_CONTAINER(window), 15); gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); hbox = gtk_hbox_new(FALSE, 0); vbox = gtk_vbox_new(FALSE, 15); combo = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Ubuntu"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Arch"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Fedora"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Mint"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Gentoo"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Debian"); gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 0); label = gtk_label_new("..."); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); gtk_container_add(GTK_CONTAINER(window), hbox); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(G_OBJECT(combo), "changed", G_CALLBACK(combo_selected), (gpointer) label); gtk_widget_show_all(window); gtk_main(); return 0; }
The example shows a combo box and a label. The combo box has a list of six options. These are the names of Linux distros. The label widget shows the selected option from the combo box.
combo = gtk_combo_box_text_new();
The gtk_combo_box_text_new
function creates a simple text-only
combo box.
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Ubuntu");
The gtk_combo_box_text_append_text
function appends a string
to the list of strings stored in the combo box.
label = gtk_label_new("-");
A new label widget is created.
gchar *text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); gtk_label_set_text(GTK_LABEL(window), text); g_free(text);
We get the selected text and set the label text to it.
The gtk_combo_box_get_active_text
function returns the
currently active string in the combo box. We set the string to the label with
the gtk_label_set_text
function.
GtkHSeparator
The GtkHSeparator
is a horizontal separator.
It is a kind of an ornament widget. There is also a sister
GtkVSeparator
widget.
#include <gtk/gtk.h> int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *label1; GtkWidget *label2; GtkWidget *hseparator; GtkWidget *vbox; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_title(GTK_WINDOW(window), "GtkHSeparator"); gtk_window_set_resizable(GTK_WINDOW(window), FALSE); gtk_container_set_border_width(GTK_CONTAINER(window), 10); label1 = gtk_label_new("Zinc is a moderately reactive, blue gray metal \ that tarnishes in moist air and burns in air with a bright bluish-green flame,\ giving off fumes of zinc oxide. It reacts with acids, alkalis and other non-metals.\ If not completely pure, zinc reacts with dilute acids to release hydrogen."); gtk_label_set_line_wrap(GTK_LABEL(label1), TRUE); label2 = gtk_label_new("Copper is an essential trace nutrient to all high \ plants and animals. In animals, including humans, it is found primarily in \ the bloodstream, as a co-factor in various enzymes, and in copper-based pigments. \ However, in sufficient amounts, copper can be poisonous and even fatal to organisms."); gtk_label_set_line_wrap(GTK_LABEL(label2), TRUE); vbox = gtk_vbox_new(FALSE, 10); gtk_container_add(GTK_CONTAINER(window), vbox); hseparator = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(vbox), label1, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), hseparator, FALSE, TRUE, 10); gtk_box_pack_start(GTK_BOX(vbox), label2, FALSE, TRUE, 0); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window)); gtk_widget_show_all(window); gtk_main(); return 0; }
The code example shows definitions of two chemical elements; they are separated by a horizontal separator. This makes the example more visually appealing.
label1 = gtk_label_new("Zinc is a moderately reactive, blue gray metal \ that tarnishes in moist air and burns in air with a bright bluish-green flame,\ giving off fumes of zinc oxide. It reacts with acids, alkalis and other non-metals.\ If not completely pure, zinc reacts with dilute acids to release hydrogen.");
We create the first label, the definition of the Zinc element.
gtk_label_set_line_wrap(GTK_LABEL(label2), TRUE);
The gtk_label_set_line_wrap
function break lines if text exceeds
the widget's size.
hseparator = gtk_hseparator_new();
The gtk_hseparator_new
creates a new GtkHSeparator
.
gtk_box_pack_start(GTK_BOX(vbox), label1, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), hseparator, FALSE, TRUE, 10); gtk_box_pack_start(GTK_BOX(vbox), label2, FALSE, TRUE, 0);
We place the separator between the labels.
GtkEntry
GtkEntry
is a single line text entry field.
This widget is used to enter textual data.
#include <gtk/gtk.h> int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *table; GtkWidget *label1; GtkWidget *label2; GtkWidget *label3; GtkWidget *entry1; GtkWidget *entry2; GtkWidget *entry3; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_title(GTK_WINDOW(window), "GtkEntry"); gtk_container_set_border_width(GTK_CONTAINER(window), 10); table = gtk_table_new(3, 2, FALSE); gtk_container_add(GTK_CONTAINER(window), table); label1 = gtk_label_new("Name"); label2 = gtk_label_new("Age"); label3 = gtk_label_new("Occupation"); gtk_table_attach(GTK_TABLE(table), label1, 0, 1, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), label2, 0, 1, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), label3, 0, 1, 2, 3, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); entry1 = gtk_entry_new(); entry2 = gtk_entry_new(); entry3 = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), entry1, 1, 2, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), entry2, 1, 2, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), entry3, 1, 2, 2, 3, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_widget_show_all(window); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_main(); return 0; }
In our example we show three text entries and three labels.
table = gtk_table_new(3, 2, FALSE); gtk_container_add(GTK_CONTAINER(window), table);
To organise our widgets, we use the table container widget.
entry1 = gtk_entry_new();
The gtk_entry_new
function creates a new GtkEntry
.
gtk_table_attach(GTK_TABLE(table), entry1, 1, 2, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), entry2, 1, 2, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), entry3, 1, 2, 2, 3, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
We attach the widgets to the table widget.
GtkImage
GtkImage
is a widget used to display an image.
#include <gtk/gtk.h> int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *image; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_title(GTK_WINDOW(window), "Red Rock"); image = gtk_image_new_from_file("redrock.jpg"); gtk_container_add(GTK_CONTAINER(window), image); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; }
In our example we show an image of a castle.
image = gtk_image_new_from_file("redrock.png");
The gtk_image_new_from_file
creates a new GtkImage
from the
specified filename . If the file is not found or cannot be loaded, the resulting
GtkImage
displays a "broken image" icon.
gtk_container_add(GTK_CONTAINER(window), image);
The image is added to the window container.
GtkStatusbar
GtkStatusbar
displays status information.
It is placed at the bottom of the application window.
#include <gtk/gtk.h> void button_pressed(GtkWidget *widget, gpointer window) { gchar *str; str = g_strdup_printf("%s button clicked", gtk_button_get_label(GTK_BUTTON(widget))); gtk_statusbar_push(GTK_STATUSBAR(window), gtk_statusbar_get_context_id(GTK_STATUSBAR(window), str), str); g_free(str); } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *hbox; GtkWidget *vbox; GtkWidget *halign; GtkWidget *balign; GtkWidget *button1; GtkWidget *button2; GtkWidget *statusbar; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); gtk_window_set_title(GTK_WINDOW(window), "GtkStatusbar"); vbox = gtk_vbox_new(FALSE, 0); hbox = gtk_hbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(window), vbox); halign = gtk_alignment_new(0, 0, 0, 0); gtk_container_add(GTK_CONTAINER(halign), hbox); gtk_box_pack_start(GTK_BOX(vbox), halign, TRUE, TRUE, 5); button1 = gtk_button_new_with_label("OK"); gtk_widget_set_size_request(button1, 70, 30 ); button2 = gtk_button_new_with_label("Apply"); gtk_widget_set_size_request(button2, 70, 30 ); gtk_box_pack_start(GTK_BOX(hbox), button1, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), button2, FALSE, FALSE, 0); balign = gtk_alignment_new(0, 1, 1, 0); statusbar = gtk_statusbar_new(); gtk_container_add(GTK_CONTAINER(balign), statusbar); gtk_box_pack_start(GTK_BOX(vbox), balign, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(button1), "clicked", G_CALLBACK(button_pressed), G_OBJECT(statusbar)); g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(button_pressed), G_OBJECT(statusbar)); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; }
In the code example, there are two buttons and a statusbar. If we click on the button, a message is displayed in the statusbar. It says which button was pressed.
gchar *str; str = g_strdup_printf("Button %s clicked", gtk_button_get_label(GTK_BUTTON(widget)));
The message is built with the g_strdup_printf
function.
We get the label of the button with the gtk_button_get_label
function.
gtk_statusbar_push(GTK_STATUSBAR(window), gtk_statusbar_get_context_id(GTK_STATUSBAR(window), str), str);
We show the message in the statusbar. The gtk_statusbar_push
function pushes a new
message onto a statusbar’s stack. The function requires a context id, which is returned
by the gtk_statusbar_get_context_id
function.
statusbar = gtk_statusbar_new();
The gtk_statusbar_new
function creates a new GtkStatusbar
widget.
GtkIconView
GtkIconView
is a widget which displays a list of icons in a grid.
It uses a GtkListStore
to store its data.
#include <gtk/gtk.h> #include <assert.h> enum { COL_DISPLAY_NAME, COL_PIXBUF, NUM_COLS }; GtkTreeModel *init_model(void) { GtkListStore *list_store; GdkPixbuf *p1, *p2, *p3, *p4; GtkTreeIter iter; GError *err = NULL; p1 = gdk_pixbuf_new_from_file("ubuntu.png", &err); p2 = gdk_pixbuf_new_from_file("gnumeric.png", &err); p3 = gdk_pixbuf_new_from_file("blender.png", &err); p4 = gdk_pixbuf_new_from_file("inkscape.png", &err); assert(err==NULL); list_store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, GDK_TYPE_PIXBUF); gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COL_DISPLAY_NAME, "Ubuntu", COL_PIXBUF, p1, -1); gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COL_DISPLAY_NAME, "Gnumeric", COL_PIXBUF, p2, -1); gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COL_DISPLAY_NAME, "Blender", COL_PIXBUF, p3, -1); gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COL_DISPLAY_NAME, "Inkscape", COL_PIXBUF, p4, -1); g_object_unref(p1); g_object_unref(p2); g_object_unref(p3); g_object_unref(p4); return GTK_TREE_MODEL(list_store); } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *icon_view; GtkWidget *sw; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "IconView"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_container_set_border_width(GTK_CONTAINER(window), 10); gtk_window_set_default_size(GTK_WINDOW(window), 350, 300); sw = gtk_scrolled_window_new(NULL, NULL); gtk_container_add(GTK_CONTAINER(window), sw); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); icon_view = gtk_icon_view_new_with_model(init_model()); gtk_container_add(GTK_CONTAINER(sw), icon_view); gtk_icon_view_set_text_column(GTK_ICON_VIEW(icon_view), COL_DISPLAY_NAME); gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(icon_view), COL_PIXBUF); gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(icon_view), GTK_SELECTION_MULTIPLE); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; }
The example displays 4 icons. The icons represent four prominent open source projects.
p1 = gdk_pixbuf_new_from_file("ubuntu.png", &err); p2 = gdk_pixbuf_new_from_file("gnumeric.png", &err); p3 = gdk_pixbuf_new_from_file("blender.png", &err); p4 = gdk_pixbuf_new_from_file("inkscape.png", &err);
We load four images from the disk using the gdk_pixbuf_new_from_file
function.
list_store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, GDK_TYPE_PIXBUF);
The gtk_list_store_new
function creates a GtkListStore
, which is a
list model for the GtkTreeView
and GtkIconView
widgets.
We store textual and pixbuf data.
gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COL_DISPLAY_NAME, "ubuntu", COL_PIXBUF, p1, -1);
This code adds a new row into the model.
icon_view = gtk_icon_view_new_with_model(init_model());
The gtk_icon_view_new_with_model
creates a new
GtkIconView
widget with a GtkTreeModel
.
gtk_container_add(GTK_CONTAINER(sw), icon_view);
The GtkIconView
is a container widget. We add
it into the GtkScrolledWindow
.
gtk_icon_view_set_text_column(GTK_ICON_VIEW(icon_view), COL_DISPLAY_NAME);
The gtk_icon_view_set_text_column
function sets
which column is a string column.
gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(icon_view), COL_PIXBUF);
The gtk_icon_view_set_pixbuf_column
function sets
which is the column with pixbufs.
gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(icon_view), GTK_SELECTION_MULTIPLE);
The gtk_icon_view_set_selection_mode
sets the
selection mode of the GtkIconView
. Choosing the GTK_SELECTION_MULTIPLE
mode, it is possible to choose multiple icons.
In this part of the GTK+ tutorial, we have continued covering GTK+ widgets.