![]() |
|
Programowanie:
Artykuły
FAQ
Download
Książki
WWW:
Artykuły
Narzędzia
Kursy
Darmowe
FAQ
Skrypty
Humor
Inne:
Forum
Wiki
Liczniki
Linki
Chat
Grafika
Video
Inne
|
Programowanie GTK
Autor: Özcan Güngör
Tłumaczenie: neuromancer (neuro.go.pl) Co to jest GTK?Ogólnie rzecz biorąc GTK jest to biblioteka do tworzenia graficznego interfejsu użytkownika (GUI). Biblioteka jest rozpowszechniania na licencji GPL/LGPL. Używając tej biblioteki można tworzyć programy darmowe, komercyjne, open-source, czy jakie tam kto sobie wymyśli ;). Co to jest GTK? Kompilacja Początek Ustawienia okna Sygnały i zdarzenia Przycisk Pakowanie komponentów używając pudełek (box) Tabele Przełączany Przycisk (Toggle Button) Przycisk testowy (check button) Napis (Label) Okienka informacyjne - podpowiedzi (tooltips) Pudełko kombinacyjne (combo box)Nazwa biblioteki pochodzi od GIMP toolkit, bo początkowo została stworzona dla GIMP'a (na marginesie: co nie najlepiej o niej świadczy). Jej utorami są: Peter Mattis Spencer Kimball Josh MacDonald. GTK ma obiektowo zorientowany interfejs. Biblioteki można używać na Windows (np. wersje GIMP pod ten system), ale raczej jej niszą jest Linux (chociażby GNOME który jej używa) i pod niego też będziemy programować. KompilacjaWymagany gcc. Po zapisaniu pliku źródłowego z rozszerzeniem .c należy uruchomić terminal (komenda xterm) i przejść do katalogu z plikiem (komenda cd <katalog>, np. cd /root/projekt). Następnie wpisaćgcc -o hello hello.c `gtk-config --cflags --libs` gdzie zamiast hello podajemy nazwę pliku wyjściowego (wykonywalnego), a zamiast hello.c nazwę naszego pliku źródłowego. UWAGA: symbol ` uzyskujemy naciskając klawisz na lewo od jedynki (tylda - ~) a nie cudzysłów. Biblioteki GTK można znaleźć pod ftp://ftp.gtk.org/ Do kompilacji wymagane są oczywiście zainstalowane biblioteki GTK i znajomość ich położenia. Aby się dowiedzieć tego można wpisać: gtk-config --cflags --libs Powinno dać coś takiego (w zależnosci od systemu): -I/opt/gnome/include/gtk-1.2 -I/opt/gnome/include/glib-1.2 -I/opt/gnome/lib/glib /include -I/usr/X11R6/include -L/opt/gnome/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -l Xext -lX11 -lm gdzie: -l library: Searches for a library in the form like liblibrary.a in defined paths. -L path: Adds a path to search libraries. -I path: Adds a path to search header file used in program. PoczątekDobra zaczynamy. Pierwszy okienkowy program. Tworzy puste okno o rozmiarach 200x200.#include <gtk/gtk.h> //Dołączamy nagłówki int main(int argc, char *argv[]) { GtkWidget *window; //Klasa okienka gtk_init(&argc, &argv); //Obsługa parametrów programu window = gtk_window_new (GTK_WINDOW_TOPLEVEL); //Tworzymy nowe okno gtk_widget_show(window); //Pokazujemy okno gtk_main (); //Główna pętla programu return 0 ; } void gtk_init(int *argc,char ***argv) GtkWidget *gtk_window_new(GtkWindowType windowtype)
void gtk_widget_show(GtkWidget *widget) void gtk_main(void) Ustawienia oknaTytuł oknavoid gtk_window_set_title(GtkWindow *window,const gchar *title) Dobra dalej. Drugi parametr jest typu gchar, który jest zdefiniowany w bibliotece glib i jest takiego samego typu jak char. Jest to wskaźnik czyli można ustawić parametr typu char *, lub tablicę char[]. Rozmiar okna void gtk_window_set_default_size(GtkWindow *window, gint width, gint height) Położenie okna void gtk_window_set_position(GtkWindow *window, GtkWindowPosition position)
gtk_widget_set_uposition(window, sx, sy); Przykładowy kod: #include <gtk/gtk.h> //Nagłówki GTK int main(int argc,char *argv[]) { GtkWidget *window; //Komponent: okno gtk_init(&argc, &argv); //Obsługa parametrów window = gtk_window_new(GTK_WINDOW_TOPLEVEL); //Stworzenie okna gtk_window_set_title(GTK_WINDOW(window), "Program"); //Zmiana tytułu okna gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); //Położenie gtk_window_set_default_size(GTK_WINDOW(window), 300, 300); //Rozmiar gtk_widget_show(window); //Pokazanie okna gtk_main(); //Główna procedura programu return 0; } Sygnały i zdarzeniaGraficzny interfejs użytkownika (GUI) służy do komunikacji z użytkownikiem programu, więc musi odpowiednio reagować na to co on robi (zdarzenia). Może to zrobić dzięki sygnałom na które adekwatnie reaguje.W GTK służy do tego funkcja: guint gtk_signal_connect_object(GtkObject *object, const gchar *name, GtkSignalFunc func, GtkObject *slot_object);
#include <gtk/gtk.h> //Nagłówki void close(GtkWidget *widget, gpointer *data) //Funkcja { gtk_main_quit(); //Zamknij program GTK } int main(int argc,char *argv[]) { GtkWidget *window; //Klasa okna gtk_init(&argc, &argv); //Parametry window = gtk_window_new (GTK_WINDOW_TOPLEVEL); //Utworzenie okna gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(close), NULL); //Skojarzenie sygnału gtk_widget_show(window); //Pokazanie gtk_main(); //Główna funckja programu GTK return 0; } gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(close), NULL) PrzyciskZwykłe przyciski służą do wykonania jakichś operacji po ich wciśnięciu. W GTK są dwie drogi stworzenia przycisków:GtkWidget* gtk_button_new (void); GtkWidget* gtk_button_new_with_label (const gchar *label); Kolejną ważną funkcją jest: void gtk_container_add(GtkContainer *container, GtkWidget *widget) #include <gtk/gtk.h> //Nagłówki GTK void close(GtkWidget *widget, gpointer *data) //Zamknięcie okna { gtk_main_quit(); //Zamknij okno } void clicked(GtkWidget *widget,gpointer *data) //Funkcja wywołana po kliknięciu okna { g_print("Button Clicked\n"); //Wyświetlenie napisu } int main(int argc,char *argv[]) //Główna funkcja programu { GtkWidget *window, *button; //Deklaracje komponentów gtk_init(&argc, &argv); //Obsługa parametrów window = gtk_window_new(GTK_WINDOW_TOPLEVEL); //Utowrzenie okna gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(close), NULL); //Skojarzenie sygnału zniszenia okna z funkcją close button=gtk_button_new_with_label("Button"); //Stworzenie przycisku z napisem gtk_container_add(GTK_CONTAINER(window),button); //Dodanie przycisku do okna gtk_signal_connect(GTK_OBJECT(button),"clicked", GTK_SIGNAL_FUNC(clicked),NULL); //Skojarzenie zdarzenia kliknięcia przycisku z funkcją clicked gtk_widget_show(button); //Pokazanie przycisku gtk_widget_show(window); //Pokazanie okna gtk_main(); //Główna pętla programu GTK return 0; } Pakowanie komponentów używając pudełek (box)Pakowanie oznacza ustawianie komponentów w kolejności w oknie. Jedną z możliwości w GTK są pudełka (boxy). Główna idea z pudełkami to pakowanie komponentów kolejno poziomo lub pionowo. Są więc dwa typy pudełek: poziome i pionowe.Poziome pudełka W tym typie pudełka, komponenty są pakowane (układane) poziomo. Aby utworzyć pudełko należy wpisać: gtk_widget *box; //Deklaracja komponentu box=gtk_hbox_new(gboolean homogenous, gint spacing); //Utworzenie pudełka Pionowe pudełka W tym typie komponenty są układane pionowo Do utworzenia używamy: gtk_widget *box; box=gtk_vbox_new(gboolean homogenous, gint spacing); Obsługa pudełek Aby dodać komponent do pudełka, można użyć jednej z dwóch możliwości. Pierwszą jest: gtk_box_pack_start(GtkBox *box, GtkWidget *child, gboolean expand, gboolean fill, guint padding); Parzystą funkcją do powyższej jest gtk_box_pack_end(GtkBox *box,GtkWidget *child, gboolean expand, gboolean fill, guint padding); Do dodania pudełka do okna służy funkcja: gtk_container_add (GtkContainer *container,GtkWidget *component); gtk_container_add(GTK_CONTAINER(window), box); gtk_box_set_homogeneous (GtkBox *box, gboolean homogenous); Funkcja: gtk_box_set_spacing(GtkBox *box, gint spacing); Do zmiany ustawień już zapakowanych komponentów służy funkcja: gtk_box_set_child_packing(GkBox *box,GtkWidget *shild, gboolean expand, gboolean fill, guint padding, GtkPackType packingtype); Przykładowy kod: #include <gtk/gtk.h> //Nagłówki GTK #include <string.h> //Obsługa łańcuchów znakowych #include <stdlib.h> //Obsługa stardowych funkcji systemu void destroy(GtkWidget *widget, gpointer data) { //Usunięcie programu gtk_main_quit(); } GtkWidget *window, *text[10], *box, *button[10], *box1, *box2, *box3, *box4, *sep; //Deklaracje komponentów int t, padding=0, space=0; //Zmienne z opisami odległości char name[15], no, isim[10][15] = { "Expand FALSE","FillFALSE", "Padding 10","Homojen FALSE","Spacing 0","Expand TRUE", "Fill TRUE","Padding 0","Homojen TRUE","Spacing 10" }, labelisim[6][15]={ "expand = ","fill = ","padding = ","homojen = ", "spacing = " }; gboolean expand=0, fill=0, homogen=0; //Ustawienia stylu pakowania komponentów void click(GtkWidget *widget, GdkEventButton *data, gpointer *po){ //Definicja funkcji wywołanej po kliknięciu przycisku //Która po kolejnym kliknięciu przycisku modyfikuje parametry pakowania if(!strcmp(gtk_widget_get_name(GTK_WIDGET(po)),"button5")) expand = 1; else if(!strcmp(gtk_widget_get_name(GTK_WIDGET(po)),"button0")) expand=0; else if(!strcmp(gtk_widget_get_name(GTK_WIDGET(po)),"button6")) fill=1; else if(!strcmp(gtk_widget_get_name(GTK_WIDGET(po)),"button1")) fill=0; else if(!strcmp(gtk_widget_get_name(GTK_WIDGET(po)),"button7")) padding=0; else if(!strcmp(gtk_widget_get_name(GTK_WIDGET(po)),"button2")) padding=10; else if(!strcmp(gtk_widget_get_name(GTK_WIDGET(po)),"button8")) homogen=1; else if(!strcmp(gtk_widget_get_name(GTK_WIDGET(po)),"button3")) homogen=0; else if(!strcmp(gtk_widget_get_name(GTK_WIDGET(po)),"button9")) space=10; else if(!strcmp(gtk_widget_get_name(GTK_WIDGET(po)),"button4")) space=0; else g_print("ALOO"); gtk_box_set_homogeneous(GTK_BOX(box3), homogen); gtk_box_set_spacing(GTK_BOX(box3),space); gtk_box_set_homogeneous(GTK_BOX(box4),homogen); gtk_box_set_spacing(GTK_BOX(box4),space); for(t=4;t<5;t++) { gtk_box_set_child_packing (GTK_BOX(box3),text[t],expand,fill,padding,GTK_PACK_START); gtk_box_set_child_packing (GTK_BOX(box4),button[t],expand,fill,padding,GTK_PACK_START); } strcpy(name, labelisim[4]); if(space==0) strcat(name,"0"); else strcat(name,"10"); gtk_label_set_text(GTK_LABEL(text[4]),name); strcpy(name,labelisim[0]); t=strlen(name); name[t]=expand+48; name[t+1]=0; gtk_label_set_text(GTK_LABEL(text[0]),name); strcpy(name,labelisim[1]); t=strlen(name); name[t]=fill+48; name[t+1]=0; gtk_label_set_text(GTK_LABEL(text[1]),name); strcpy(name,labelisim[2]); if(padding==0) strcat(name,"0"); else strcat(name,"10"); gtk_label_set_text(GTK_LABEL(text[2]),name); strcpy(name,labelisim[3]); t=strlen(name); name[t]=homogen+48; name[t+1]=0; gtk_label_set_text(GTK_LABEL(text[3]),name); } int main(int argc, char *argv[]) { gtk_init (&argc, &argv); //Inicjalizacja window = gtk_window_new (GTK_WINDOW_TOPLEVEL); //Utworzenie okna gtk_window_set_title((GtkWindow *)window,"Program"); //Zmiana tytułu okna gtk_widget_set_usize(window,700,200); //Zmiana rozmiaru gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); //Zmiana położenia gtk_signal_connect_object(GTK_OBJECT(window),"destroy", GTK_SIGNAL_FUNC(destroy),NULL); //Skojarzenie sygnału zamknięcia okna z funkcją destroy gtk_container_set_border_width (GTK_CONTAINER (window), 10); //Zmiana obramowania kontenera (tutaj okna) //Utworzenie kolejnych pudełek box1=gtk_hbox_new(TRUE,0); box=gtk_hbox_new(TRUE,0); box2=gtk_vbox_new(FALSE,0); box3=gtk_hbox_new(homogen,space); box4=gtk_hbox_new(homogen,space); //Stworzenie separatora sep=gtk_hseparator_new(); for(t=0;t<5;t++) { strcpy(name,"label"); name[6]=t+48; name[7]='\0'; text[t]=gtk_label_new(labelisim[t]); //Utworzenie kolejnych napisów (etykiet) gtk_label_set_justify(GTK_LABEL(text[t]),GTK_JUSTIFY_FILL); //Zmiana wyrównania etykiet gtk_box_pack_start(GTK_BOX(box3),text[t],expand,fill,space); //Pakowanie etykiet do pudełka gtk_widget_show(text[t]); //Pokazanie napisu } gtk_box_pack_start(GTK_BOX(box2),box3,FALSE,FALSE,0); //Dopakowanie pudełka pudełkiem gtk_widget_show(box3); //Pokazanie pudełka for(t=0;t<10;t++) { strcpy(name,"button"); name[6]=t+48; name[7]='\0'; button[t]=gtk_button_new_with_label(isim[t]); gtk_widget_set_name(GTK_WIDGET(button[t]),name); gtk_widget_set_usize(button[t],100,20); gtk_signal_connect_object(GTK_OBJECT(button[t]),"button_release_event", GTK_SIGNAL_FUNC(click),(gpointer)box3); if(t>4) gtk_box_pack_start(GTK_BOX(box1),button[t],FALSE,FALSE,0); else gtk_box_pack_start(GTK_BOX(box),button[t],FALSE,FALSE,0); gtk_widget_show(button[t]); } for (t=0;t<5;t++) { //Utworzenie, zapakowanie I pokazanie kolejnych napisów button[t]=gtk_button_new_with_label("button"); gtk_box_pack_start(GTK_BOX(box4),button[t],expand,fill,space); gtk_widget_show(button[t]); } //Wpakowanie i pokazanie kolejnych pudełek gtk_box_pack_start (GTK_BOX (box2), box4,FALSE,FALSE,0); gtk_widget_show(box4); gtk_box_pack_start(GTK_BOX(box2), sep,FALSE,FALSE,10); gtk_widget_show(sep); gtk_box_pack_start (GTK_BOX (box2), box1,FALSE,FALSE,0); gtk_widget_show(box1); gtk_box_pack_start (GTK_BOX (box2), box,FALSE,FALSE,0); gtk_widget_show(box); gtk_container_add (GTK_CONTAINER (window), box2); gtk_widget_show(box2); gtk_widget_show (window); //Pokazanie okna gtk_main (); //Główna funkcja GTK return 0; } TabeleTabele tak jak w HTML służy do pakowania komponentów do komórek. Dzięki temu, wystarczy utworzyć tabelę z wierszami i kolumnami. Potem możemy układać komponenty w komórki, albo grupy komórek. Do utworzenia tabeli używamy:GtkWidget *table; //Deklaracja komponentu GtkWidget *gtk_table_new(guint row, guint column, gboolean homogenous); //Utworzenie tabeli Aby dodać komponent do tabeli należy użyć funkcji: void gtk_table_attach (GtkTable *table, GtkWidget *child, guint left_attach, guint right_attach, guint top_attach, guint bottom_attach, GtkAttachOptions xoptions, GtkAttachOptions yoptions, guint xpadding, guint ypadding);
Przykładowy kod: #include <gtk/gtk.h> //Nagłówki GTK //Zamknięcie programu GTK void delete_event(GtkWidget *widget,GdkEvent *event, gpointer data) { gtk_main_quit(); } int main(int argc,char *argv[]) { GtkWidget *window; //Deklaracjekomponentów GtkWidget *button; GtkWidget *table; gtk_init(&argc, &argv); //Inicjalizacja window = gtk_window_new (GTK_WINDOW_TOPLEVEL); //Utworzenie okna gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(delete_event), NULL); //Skojarzenie sygnału niszczenia okna z funkcją zamykającą program table = gtk_table_new (2, 2, TRUE); //Utworzenie tabeli gtk_container_add(GTK_CONTAINER(window), table); //Dodanie tabeli do kontenera (tutaj okno) button = gtk_button_new_with_label ("button 1"); //Utworzenie przycisku gtk_table_attach(GTK_TABLE(table), button, 0, 1, 0, 2,GTK_SHRINK, GTK_SHRINK,0,0); //Umieszczenie przycisku w tabeli gtk_widget_show(button); //Pokazanie przycisku button = gtk_button_new_with_label("button 2"); //Utworzenie przycisku gtk_table_attach(GTK_TABLE(table), button, 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0); // Umieszczenie przycisku w tabeli gtk_widget_show(button); //Pokazanie przycisku button = gtk_button_new_with_label("button 3"); gtk_table_attach (GTK_TABLE(table), button, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); gtk_widget_show(button); gtk_widget_show(table); //Pokazanietabeli gtk_widget_show(window); //Pokazanie okna gtk_main(); return 0; } void gtk_table_attach_defaults (GtkTable *table, GtkWidget *child, guint left_attach, guint right_attach, guint top_attach, guint bottom_attach); Do zmiany liczby kolumn i wierszy istniejącej tabeli służy funkcja: void gtk_table_resize(GtkTable *table, guint rows, guint columns); void gtk_table_set_row_spacing (GtkTable *table, guint row, guint spacing); void gtk_table_set_col_spacing (GtkTable *table, guint column, guint spacing); void gtk_table_set_row_spacings (GtkTable *table, guint spacing); void gtk_table_set_col_spacings (GtkTable *table, guint spacing); void gtk_table_set_homogeneous (GtkTable *table, gboolean homogenous); Przełączany Przycisk (Toggle Button)Ten przycisk wygląda jak normalny przycisk, ale przyjmuje dwa stany: wciśnięty i niewciśnięty. Do stworzenia przycisku należy użyć jednej z dwóch funkcji:GtkWidget *toggle=gtk_toggle_button_new(void); GtkWidget *toggle=gtk_toggle_button_new_with_label(const gchar *label); Do zmiany stanu przycisku służy funkcja: gtk_toggle_button_set_active(GtkToggleButton *toggle_button, gboolean is_active); Do pobrania stanu (statusu) przycisku służy funkcja: gboolean gtk_toggle_button_get_active(GtkToggleButton *button); Przykładowy kod: #include <gtk/gtk.h> //Nagłówki GTK void togg(GtkWidget *widget, gpointer *data) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data))) //Sprawdza stan (aktywność) przycisku, przy użyciu makra wyciągającego z parametru data g_print("State is 1\n"); else g_print("State is 0\n"); } int main(int argc,char *argv[]) { GtkWidget *window; //Deklaracja okna GtkWidget *button; //Deklaracja przycisku gtk_init(&argc, &argv); //Inicjalizacja window = gtk_window_new (GTK_WINDOW_TOPLEVEL); //Utworzenie nowego okna gtk_window_set_title(GTK_WINDOW (window), "Toggle Button"); //Zmiana tytułu okna gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_main_quit), NULL); //Połączenie zdarzenia z funkcją button=gtk_toggle_button_new_with_label("I'm a toggle button"); //Utworzenie przycisku toggle z napisem gtk_container_add(GTK_CONTAINER(window),button); //Dodanie przycisku do kontenera (tutaj okna) gtk_signal_connect(GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC(togg), (gpointer *)button); //Połączenie zdarzenia toggled z funkcją togg gtk_widget_show(button); //Pokazanie przycisku gtk_widget_show(window); //Pokazanie okna gtk_main(); //Główna pętla programu return 0; } Przycisk testowy (check button)Check button (znany także jako check box) jest podklasą (subclass) przycisku toggle. Może być używany do wyboru pewnych opcji.Do stworzenia przycisku można użyć funkcji: GtkWidget* gtk_check_button_new (void); GtkWidget |