Przemek Kramarczyk ~/

wstęp do gtk+

(c)2004 Przemek Kramarczyk

Biblioteka GTK+ sluży do tworzenia graficznego interfejsu użytkownika (GUI) przy pomocy językow programowania C, C++, C#, Python, Perl, Java i wielu innych. Z GTK korzysta między innymi Gimp, Firefox, Acrobat Reader, Nvu, RealPlayer. Można ją uruchomic na prawie każdym komputerze i systemie operacyjnym, jednak najbardziej popularna jest na platformie GNU/Linux. Aby móc skorzystać z możliwości jakie daje nam ta biblioteka, należy ją zainstalować z CD lub sciągnać ze strony www.gtk.org. Jeżeli w komputerze mamy zainstalowany desktop GNOME to GTK+ najprawdopodobniej też już tam jest. Jeżeli nie używamy GNOME trzeba GTK zainstalować ręcznie (pakiety gtk+2, glib2, pango, atk i cairo). Obecność biblioteki można sprawdzić wydając polecenie:

pkg-config gtk+-2.0 --cflags --libs

Na ekranie powinno nam sie pokazać coś takiego:
-I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0
Dla wygody proponuje stworzyć w pliku /etc/profile taką zmienną srodowiskową:

export GTK="`pkg-config gtk+-2.0 --cflags --libs` -Wall"

Nasze programy będziemy kompilować poleceniem:
gcc -o program program.c -lm $GTK
Zaczynamy.

Zakładam że czytelnik zna podstawy języka C. Jeżeli nie, to zapraszam na stronę z kursem C. Nasz program będzie obliczał pojemnośc skokową silnika spalinowego. Służy do tego prosty wzór:
(PI*r2*h)*liczba_cylindrow
Gdzie r2 to połowa średnicy cylindra podniesiona do kwadratu, a h to skok tłoka.

Na początek otwieramy potrzebne pliki nagłówkowe.
#include <gtk/gtk.h> /* tutaj są prototypy funkcji i makra GTK+ */ #include <math.h> /* tutaj jest definicja liczby PI i funkcji pow() */ #include <stdio.h> /* potrzebujemy funkcji sprintf() */ #include <stdlib.h> void licz(void); void kasuj(void); void koniec(void); void buduj_interfejs(void); /* GtkWidget jest typem danych gtk. */ /* Prawie każdy element widoczny na ekranie jest wskaźnikiem do tego typu. */ GtkWidget *okno, *ramka, *tabela, *pole_srednica, *pole_skok, *pole_ilosc_cylindrow, *pole_wynik, *przycisk_licz, *przycisk_resetuj;
Funkcja main() int main(int argc, char **argv) { gtk_init(&argc, &argv); /* inicjalizacja gtk */
buduj_interfejs(); /* nasza funkcja tworząca interfejs programu */
gtk_main(); /* g?owna pętla gtk */
return(0); }
Funkcja buduj_interfejs() void buduj_interfejs() { /* otwieramy nowe okno i określamy jego typ (TOPLEVEL) */ okno=gtk_window_new(GTK_WINDOW_TOPLEVEL);
/* ustawiamy tytuł okna "okno" gtk_window_set_title(GTK_WINDOW(okno),"programik");
/* zabezpieczamy sie przed zmianą rozmiaru okna (FALSE) */ gtk_window_set_resizable(GTK_WINDOW(okno), FALSE);
/* ustawiamy nasze okno na środku ekranu */ gtk_window_set_position(GTK_WINDOW(okno), GTK_WIN_POS_CENTER);
/* tworzymy ramkę bez opisu (NULL) */ ramka=gtk_frame_new(NULL);
/* wstawiamy ramkę do okna (kontenera) */ gtk_container_add(GTK_CONTAINER(okno), ramka);
/* ustawiamy odległość miedzy krawedzią okna a ramką */ gtk_container_set_border_width(GTK_CONTAINER(okno), 5);
/* tworzymy tabele o 6 wierszach i 5 kolumnach */ tabela=gtk_table_new(6,5,0);
/* wstawiamy tabele do ramki */ gtk_container_add(GTK_CONTAINER(ramka), tabela);
/* wstawiamy etykiete tekstową do tabeli na pozycji w kolumnie (1, 2) i wierszu (1, 2) */ gtk_table_attach_defaults(GTK_TABLE(tabela), gtk_label_new("srednica cylindra (mm)"), 1, 2, 1, 2);
/* tworzymy pole dialogowe dla wpisania średnicy cylindra */ pole_srednica=gtk_entry_new();
/* dołączamy pole dialogowe do tabeli na pozycjach 1,2 i 2,3 */ gtk_table_attach_defaults(GTK_TABLE(tabela), pole_srednica, 1, 2, 2, 3);
/* tworzymy etykiete tekstową */ gtk_table_attach_defaults(gtk_table(tabela), gtk_label_new("skok tloka (mm)"), 1, 2, 3, 4);
/* tworzymy pole dialogowe dla wpisania skoku tłoka */ pole_skok=gtk_entry_new(); gtk_table_attach_defaults(GTK_TABLE(tabela), pole_skok, 1, 2, 4, 5);
/* dołączamy pole dialogowe do tabeli na pozycjach 4,5 1,2 */ przycisk_licz=gtk_button_new_with_label(" oblicz ");
/* tworzymy przycisk z etykietą */ gtk_table_attach_defaults(GTK_TABLE(tabela), przycisk_licz, 2, 3, 4, 5);
/* podłączamy guzik do funkcji "licz()" */ g_signal_connect(G_OBJECT(przycisk_licz), "clicked", G_CALLBACK(licz), NULL); przycisk_resetuj=gtk_button_new_with_label(" skasuj "); gtk_table_attach_defaults(GTK_TABLE(tabela), przycisk_resetuj, 2, 3, 2, 3); g_signal_connect(G_OBJECT(przycisk_resetuj),"clicked", G_CALLBACK(kasuj), NULL); gtk_table_attach_defaults(GTK_TABLE(tabela), gtk_label_new("ilosc cylindrow"), 3, 4, 1, 2); pole_ilosc_cylindrow=gtk_entry_new(); gtk_table_attach_defaults(GTK_TABLE(tabela), pole_ilosc_cylindrow, 3, 4, 2, 3); gtk_table_attach_defaults(GTK_TABLE(tabela), gtk_label_new("wynik (cm^3)"), 3, 4, 3, 4); pole_wynik=gtk_entry_new(); /* ustawiamy niemożność edycji pola "wynik" */ gtk_entry_set_editable(GTK_ENTRY(pole_wynik), FALSE); gtk_table_attach_defaults(GTK_TABLE(tabela), pole_wynik, 3, 4, 4, 5); g_signal_connect(G_OBJECT(okno), "destroy", G_CALLBACK(koniec), NULL); /* ustawiamy odległość między wierszami tabeli */ gtk_table_set_row_spacings(GTK_TABLE(tabela), 5); /* ustawiamy odległośc miedzy kolumnami tabeli */ gtk_table_set_col_spacings(GTK_TABLE(tabela), 8); /* pokazujemy wszystkie widgety w oknie */ gtk_widget_show_all(okno); return; }

funkcja koniec() void koniec() { gtk_main_quit(); return; }
funkcja kasuj() void kasuj() { const char N[]="\0"; gtk_entry_set_text(GTK_ENTRY(pole_srednica), N); gtk_entry_set_text(GTK_ENTRY(pole_skok), N); gtk_entry_set_text(GTK_ENTRY(pole_ilosc_cylindrow), N); gtk_entry_set_text(GTK_ENTRY(pole_wynik), N); return; }
funkcja licz() ----------------------------------------------------------- void licz() { int ile_cyl=0; const char *c_ile_cyl, *c_srednica, *c_skok; char *c_wynik; float skok, wynik; skok=wynik=0; c_skok=gtk_entry_get_text(GTK_ENTRY(pole_skok)); c_srednica=gtk_entry_get_text(GTK_ENTRY(pole_srednica)); c_ile_cyl=gtk_entry_get_text(GTK_ENTRY(pole_ilosc_cylindrow)); skok=atof(c_skok); ile_cyl=atoi(c_ile_cyl); wynik=(((M_PI*pow(atof(c_srednica)/2, 2)*skok)*ile_cyl)/1000); c_wynik=(char*)malloc(64*sizeof(char)); if (c_wynik==NULL) { exit(EXIT_FAILURE); } sprintf(c_wynik, "%g", wynik); gtk_entry_set_text(GTK_ENTRY(pole_wynik), c_wynik); free(c_wynik); return; }
A oto gotowy programik :-)

screenshot

pobierz plik programik.c
pobierz plik Makefile

strona domowa GTK+
świetny tutorial
opis API