main.cpp
#include <gtk/gtk.h>
int main(int argc, char** argv) {
GtkBuilder *builder;
GError *error;
GtkWidget *window;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
error = NULL;
gtk_builder_add_from_file(builder, "main_window.ui", &error);
if (error) {
g_print("Wystąpił błąd: %s\n", error->message);
g_error_free(error);
return -1;
}
window = GTK_WIDGET(gtk_builder_get_object(builder, "wndHelloWorld"));
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Na początku kodu inkludujemy główny plik biblioteki GTK: gtk/gtk.h. Ta linijka jest wymagana w każdym programie zbudowanym na bazie tej biblioteki. Inkluduje ona wszystkie obiekty, widgety i typy, z których będziemy korzystali.
Z kolei na początku funkcji main deklarujemy trzy zmienne:
GtkBuilder *builder;
GError *error;
GtkWidget *window;
Zmienna builder będzie wskazywała na obiekt GtkBuilder pozwalający wczytać interfejs z pliku XML. Zmienna error będzie wskazywała na obiekt zawierający informacje o ewentualnym błędzie podczas wczytywania interfejsu. Z kolei zmienna window będzie wskazywała na obiekt reprezentujący nasze okno główne. Jest ona typu GtkWidget*, gdyż każda kontrolka, włącznie z oknami głównymi i oknami dialogowymi, jest w bibliotece GTK nazywana widgetem i pochodzi od tej właśnie klasy.
Następnie wywoływana jest funkcja inicjalizacyjna biblioteki GTK:
gtk_init(&argc, &argv);
Pobiera ona wskaźniki na ilość parametrów przekazanych do programu oraz na tablicę tych parametrów. Jeśli znajdzie w tej tablicy parametr odwołujący się do działania jakiegoś składnika GTK, to stosuje podane ustawienie i usuwa ten parametr z tablicy.
W kolejnej linijce tworzymy obiekt buildera:
builder = gtk_builder_new();
Następnie wczytujemy interfejs z pliku przy pomocy funkcji gtk_builder_add_from_file
error = NULL;
gtk_builder_add_from_file(builder, "main_window.ui", &error);
if (error) {
g_print("Wystąpił błąd: %s\n", error->message);
g_error_free(error);
return -1;
}
Funkcja ta pobiera obiekt buildera, nazwę pliku XML zawierającego nasz interfejs oraz wskaźnik na zmienną error. Przed każdą funkcją pobierającą wskaźnik na zmienną typu GError* musimy tej zmiennej przypisać wartość NULL. Jeśli wystąpił jakiś błąd, to w tej zmiennej zostanie umieszczony jego opis. Po wywołaniu funkcji gtk_builder_add_from_file sprawdzamy czy plik został poprawnie wczytany. Jeśli nie, to wypisujemy komunikat błędu na ekranie, zwalniamy pamięć przydzieloną błędowi i kończymy działanie programu.
Teraz zostało tylko pobranie wskaźnika na nasze okienko i wyświetlenie go na ekranie:
window = GTK_WIDGET(gtk_builder_get_object(builder, "wndHelloWorld"));
gtk_widget_show_all(window);
Wskaźniki na widgety o ustawionej w projektancie glade nazwie możemy pobierać przy pomocy funkcji gtk_builder_get_object(). Funkcja ta jako pierwszy parametr pobiera wskaźnik na obiekt buildera a jako drugi parametr - nazwę widgeta.
Natomiast funkcja gtk_widget_show_all(window) odpowiada za wyświetlenie okienka na ekranie wraz ze wszystkimi widgetami, które w sobie zawiera (tutaj etykietą "Witaj świecie").
Na koniec pozostało wywołanie funkcji gtk_main(). Funcja ta wchodzi w nieskończoną pętlę, w której przetwarza wszystkie zdarzenia i przekazuje je odpowiednim funkcjom obsługi zdarzeń.
Teraz skompiluj program przy pomocy następującego polecenia:
g++ -o hello_world main.cpp `pkg-config --cflags --libs gtk+-3.0`
Uruchom powstały program hello_world i gdy już nacieszysz się jego działaniem, zamknij okno. Zauważ, że pomimo iż okno główne się zamknęło, program nie skończył działać. Aby przerwać jego działanie naciśnij w konsoli CTRL+C. Dzieje się tak dlatego, gdyż nie zostało obsłużone zdarzenie zamknięcia okna a tym samym nie opuściliśmy pętli gtk_main. O tym jak obsłużyc to zdarzenie - w następnym tutorialu.