Sunday, April 14, 2013

Introducing Various GTK+ widgets

Introducing Various GTK+ widgets

In this part of the GTK+ programming tutorial, we will continue introducing various GTK+ widgets.

GtkComboBox

GtkComboBox is a widget that allows the user to choose from a list of options.
#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 *fixed;
GtkWidget *combo;
GtkWidget *label;

gtk_init(&argc, &argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "GtkCombo");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);

fixed = gtk_fixed_new();

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), "Mandriva");
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_fixed_put(GTK_FIXED(fixed), combo, 50, 50);
gtk_container_add(GTK_CONTAINER(window), fixed);

label = gtk_label_new("-");
gtk_fixed_put(GTK_FIXED(fixed), label, 50, 110);

g_signal_connect_swapped(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), G_OBJECT(window));

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_new_text();
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Ubuntu");
gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Mandriva");
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");
We create a GtkComboBox and fill it with a list of Linux Distribution names.
 label = gtk_label_new("-");
We also create a label widget.
 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 documentation to the combo box says, that gtk_combo_box_get_active_text() returns a newly allocated string containing the currently active text. This means, that we must free the memory.

GktComboBox
Figure: GtkComboBox

GtkHSeparator

The GtkHSeparator is is a horizontal separator. It is a kind of an ornament widget. This widgets serves some design purposes. 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), 20);

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);
We wrap the text.
hseparator = gtk_hseparator_new();
We create a horizontal separator.
 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.

GtkHSeparator
Figure: GtkHSeparator

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(table);

gtk_widget_show(label1);
gtk_widget_show(label2);
gtk_widget_show(label3);

gtk_widget_show(entry1);
gtk_widget_show(entry2);
gtk_widget_show(entry3);

gtk_widget_show(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 organize our widgets, we use the table container widget.
 entry1 = gtk_entry_new();
entry2 = gtk_entry_new();
entry3 = gtk_entry_new();
Here we create three text entries.
 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.

GtkEntry
Figure: GtkEntry

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_default_size(GTK_WINDOW(window), 230, 150);
gtk_window_set_title(GTK_WINDOW(window), "Red Rock");
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);

gtk_container_set_border_width(GTK_CONTAINER(window), 2);

image = gtk_image_new_from_file("redrock.png");
gtk_container_add(GTK_CONTAINER(window), image);


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;
}
In our example we show an image of a castle.
 gtk_container_set_border_width(GTK_CONTAINER(window), 2);
We put a small 2px border around the picture.
 image = gtk_image_new_from_file("redrock.png");
gtk_container_add(GTK_CONTAINER(window), image);
We load an image from the file and add it into the 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("Button %s 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 *fixed;
GtkWidget *button1;
GtkWidget *button2;
GtkWidget *statusbar;
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_default_size(GTK_WINDOW(window), 280, 150);
gtk_window_set_title(GTK_WINDOW(window), "GtkStatusbar");

vbox = gtk_vbox_new(FALSE, 2);

fixed = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window), vbox);

gtk_box_pack_start(GTK_BOX(vbox), fixed, TRUE, TRUE, 1);

button1 = gtk_button_new_with_label("OK");
gtk_widget_set_size_request(button1, 80, 30 );
button2 = gtk_button_new_with_label("Apply");
gtk_widget_set_size_request(button2, 80, 30 );

gtk_fixed_put(GTK_FIXED(fixed), button1, 50, 50);
gtk_fixed_put(GTK_FIXED(fixed), button2, 150, 50);


statusbar = gtk_statusbar_new();
gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, TRUE, 1);

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_swapped(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), G_OBJECT(window));

gtk_widget_show_all(window);

gtk_main();

return 0;
}
In our code example we show two buttons and a statusbar. If we click on the button, a message is displayed in the statusbar. It says, which button we have pressed.
 gchar *str;
str = g_strdup_printf("Button %s clicked",
gtk_button_get_label(GTK_BUTTON(widget)));
We create a message.
 gtk_statusbar_push(GTK_STATUSBAR(window),
gtk_statusbar_get_context_id(GTK_STATUSBAR(window), str), str);
We show the message in the statusbar.

GtkStatusbar
Figure: GtkStatusbar

GtkIconView

The GtkIconView is a widget which displays a list of icons in a grid.
#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);

int i = 0;
for (i; i < 50; i++) {
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);
}

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), "Icon View");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
gtk_widget_set_size_request(window, 350, 330);

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 will display 200 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 4 icons from the disk.
 list_store = gtk_list_store_new(NUM_COLS, 
G_TYPE_STRING, GDK_TYPE_PIXBUF);
We will 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 icon to the icon view.
  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);
We create a GtkIconView widget and set an icon and it's name to the icon view.

Icon View
Figure: Icon View


In this part of the GTK+ tutorial, we have continued covering GTK+ widgets.

No comments:

Post a Comment