Sunday, April 14, 2013

First programs in GTK+

First programs in GTK+

In this part of the GTK+ programming tutorial, we will create our first programs in GTK+

Simple example

We start with a very simple example. We will show a basic window.
#include <gtk/gtk.h>

int main( int argc, char *argv[])
{
GtkWidget *window;

gtk_init(&argc, &argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show(window);

gtk_main();

return 0;
}
This example will show a basic window on screen.
  gcc -o simple simple.c `pkg-config --libs --cflags gtk+-2.0`
This is how we compile the example.
 gtk_init(&argc, &argv);
Here we initiate the GTK+ library.
 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
We create a GtkWindow widget. The window type is GTK_WINDOW_TOPLEVEL. Toplevel windows have a titlebar and a border. They are managed by the window manager.
 gtk_widget_show(window);
After we have created a widget, we must show it.
 gtk_main();
This code enters the GTK+ main loop. From this point, the application sits and waits for events to happen.

Simple
Figure: Simple

Centering the window

If we do not position the window ourselves, the window manager will position it for us. In the next example, we will center the window.
#include <gtk/gtk.h>

int main( int argc, char *argv[])
{
GtkWidget *window;

gtk_init(&argc, &argv);

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

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

gtk_main();

return 0;
}
In our example, we center the window, set a title and size for the window.
 gtk_window_set_title(GTK_WINDOW(window), "Center");
The gtk_window_set_title() function will set a window title. If we do not set a title ourselves, the GTK+ will use a name of a source file as a title.
 gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
This code sets the size of the window to 230x150 pixels. Note, that we are talking about the client area, excluding the decorations provided by the window manager.
 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
This code centers the window.
 g_signal_connect_swapped(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
In the previous example, the window was not completely destroyed, when we clicked on the x button. We can see it, if we launch the example from the command line. The window does not react to the destroy signal by default. We must explicitly terminate the application by connecting the destroy signal to the gtk_main_quit() function.

The application icon

In the next example, we show the application icon. Most window managers display the icon in the left corner of the titlebar and also on the taskbar.
#include <gtk/gtk.h>

GdkPixbuf *create_pixbuf(const gchar * filename)
{
GdkPixbuf *pixbuf;
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file(filename, &error);
if(!pixbuf) {
fprintf(stderr, "%s\n", error->message);
g_error_free(error);
}

return pixbuf;
}

int main( int argc, char *argv[])
{
GtkWidget *window;

gtk_init(&argc, &argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "icon");
gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_icon(GTK_WINDOW(window), create_pixbuf("web.png"));
gtk_widget_show(window);

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

gtk_main();

return 0;
}
The code example shows the application icon.
 gtk_window_set_icon(GTK_WINDOW(window), create_pixbuf("web.png"));
The gtk_window_set_icon() displays the icon for our window. The create_pixbuf() creates a GdkPixbuf from a png file.
 pixbuf = gdk_pixbuf_new_from_file(filename, &error);
According to the documentation, the gdk_pixbuf_new_from_file() function creates a new pixbuf by loading an image from a file. The file format is detected automatically. If NULL is returned, then error will be set.

Icon   Taskbar Icon
Figure: Icon

Increase - Decrease

We finish the first chapter of the GTK+ programming tutorial with an example, where we have three child widgets. Two buttons and one label. The label will hold an integer number. The buttons will increase or decrease this number.
#include <gtk/gtk.h>

gint count = 0;
char buf[5];

void increase(GtkWidget *widget, gpointer label)
{
count++;

sprintf(buf, "%d", count);
gtk_label_set_text(GTK_LABEL(label), buf);
}

void decrease(GtkWidget *widget, gpointer label)
{
count--;

sprintf(buf, "%d", count);
gtk_label_set_text(GTK_LABEL(label), buf);
}

int main(int argc, char** argv) {

GtkWidget *label;
GtkWidget *window;
GtkWidget *frame;
GtkWidget *plus;
GtkWidget *minus;

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), 250, 180);
gtk_window_set_title(GTK_WINDOW(window), "+-");

frame = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window), frame);

plus = gtk_button_new_with_label("+");
gtk_widget_set_size_request(plus, 80, 35);
gtk_fixed_put(GTK_FIXED(frame), plus, 50, 20);

minus = gtk_button_new_with_label("-");
gtk_widget_set_size_request(minus, 80, 35);
gtk_fixed_put(GTK_FIXED(frame), minus, 50, 80);

label = gtk_label_new("0");
gtk_fixed_put(GTK_FIXED(frame), label, 190, 58);

gtk_widget_show_all(window);

g_signal_connect(window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);

g_signal_connect(plus, "clicked",
G_CALLBACK(increase), label);

g_signal_connect(minus, "clicked",
G_CALLBACK(decrease), label);

gtk_main();

return 0;
}
The code example increases or decreases a value in a GtkLabel.
 g_signal_connect(plus, "clicked", 
G_CALLBACK(increase), label);
We connect the increase() callback to the plus button. Note that we send a label as a parameter to the callback. We will work on this label inside the callback function.
  count++;

sprintf(buf, "%d", count);
gtk_label_set_text(GTK_LABEL(label), buf);
Inside the increase callback, we increase the counter. Make textual data out of the number value and update the label.

Increase - Decrease
Figure: Increase - Decrease


In this chapter we introduced some simple GTK+ programs.

No comments:

Post a Comment