Progmar Marcin Załęczny

Kod programu witaj świecie

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;
}

Wyjaśnienie kodu

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.