5. Kontenery
5.1. GtkVBox
Oprócz wspomnianego już GtkFixed istnieją w GTK+ również inne kontenery. Jednym z nich jest GtkVBox.
GtkVBox to kontener, w którym widżety umieszczone są w jednej kolumnie – jeden pod drugim. Aby go utworzyć należy posłużyć się funkcją:
GtkWidget* gtk_vbox_new (gboolean homogeneous, gint spacing);
W drugim parametrze należy podać żądany odstęp między widżetami, a w pierwszym należy ustalić, czy między wszystkimi widżetami ma być taka sama odległość.
Do ustawiania widżetów w GtkVBox służy natomiast funkcja:
void gtk_box_pack_start (GtkBox *box, GtkWidget *child, gboolean expand, gboolean fill, guint padding);
Jako pierwszy parametr należy podać wskaźnik do obiektu typu GtkBox, w następnym referencję do widżetu, który ma się znaleźć w kontenerze, w następnym należy określić, czy widżet ma zajmować całą dostępną przestrzeń (jeżeli jest kilka widżetów, przestrzeń jest dzielona pomiędzy nimi), w kolejnym trzeba podać, czy widżet ma zostać rozciągnięty i w ostatnim ustawić odstęp pomiędzy innymi widżetami.
Przykładowe użycie GtkVBox:
#include <gtk/gtk.h> int main( int argc, char *argv[]) { GtkWidget *okno; GtkWidget *vbox; GtkWidget *nowa_gra; GtkWidget *wczytaj_gre; GtkWidget *opcje; GtkWidget *autorzy; GtkWidget *wyjdz; gtk_init(&argc, &argv); okno = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_position (GTK_WINDOW(okno), GTK_WIN_POS_CENTER); gtk_window_set_default_size (GTK_WINDOW(okno), 230, 250); gtk_window_set_title (GTK_WINDOW(okno), "Gra 1.0"); gtk_container_set_border_width (GTK_CONTAINER(okno), 5); vbox = gtk_vbox_new(FALSE, 1); gtk_container_add(GTK_CONTAINER(okno), vbox); nowa_gra = gtk_button_new_with_label ("Nowa gra"); wczytaj_gre = gtk_button_new_with_label ("Wczytaj grę"); opcje = gtk_button_new_with_label ("Opcje"); autorzy = gtk_button_new_with_label ("Autorzy"); wyjdz = gtk_button_new_with_label ("Wyjdź"); gtk_box_pack_start (GTK_BOX(vbox), nowa_gra, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX(vbox), wczytaj_gre, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX(vbox), opcje, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX(vbox), autorzy, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX(vbox), wyjdz, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(okno), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(okno); gtk_main(); return 0; }
W powyższym kodzie znajduje się również jedna nowa funkcja:
gtk_container_set_border_width (GTK_CONTAINER(okno), 5);
Określa ona grubość ramki pomiędzy krawędzią kontenera a jego zawartością. Jako pierwszy argument podaje się referencję do kontenera, a jako drugą – grubość ramki wyrażoną w pikselach.
Po skompilowaniu i uruchomieniu programu ujrzysz coś takiego:
5.2. GtkHBox
Następnym omawianym kontenerem jest GtkHBox. Od powyższego różni się jedynie nazwą, funkcją, która go tworzy (a dokładniej gtk_hbox_new()) i tym, że układa widżety w jednym wierszu, a nie w kolumnie. Tak więc działanie powyższego programu po zmianie GtkVBoksa na GtkHBoksa oraz zmianie rozmiaru okna wygląda następująco:
5.3. GtkTable
GtkTable – jak sama nazwa wskazuje – umieszcza widżety w tabeli. Warto wspomnieć, że jeden widżet może wypełniać dowolną liczbę komórek tej tabeli. Aby utworzyć GtkTable, należy posłużyć się funkcją:
GtkWidget* gtk_table_new (guint rows, guint columns, gboolean homogeneous);
Jako pierwszy warunek przyjmuje liczbę wierszy, drugi liczbę kolumn, a ostatni określa, czy komórki mają być takiej samej wielkości.
Aby dodać widżet do tabeli można posłużyć się funkcją gtk_table_attach(), jednak łatwiej jest to zrobić za pomocą gtk_table_attach_defaults(), gdyż przyjmuje ona 4 argumenty mniej i tym samym jest prostsza w użyciu.
void gtk_table_attach_defaults (GtkTable *table, GtkWidget *widget, guint left_attach, guint right_attach, guint top_attach, guint bottom_attach);
Pierwszym argumentem, który należy podać jest referencja do GtkTable. Drugim – do widżetu. Następne 4 określają umiejscowienie widżetu – lewa krawędź, prawa krawędź, górna oraz dolna krawędź.
Istnieją jeszcze 2 funkcje przydatne przy pracy z tabelami. Są to gtk_table_set_row_spacings() oraz gtk_table_set_col_spacings(). Służą do ustawiania odstępów kolejno między wierszami oraz kolumnami. Obie funckje jako pierwszy argument przyjmują wskaźnik do tabeli i jako drugi – rozmiar wyrażony w pikselach.
Za pomocą GtkTable można stworzyć wiele różnych interfejsów – na przykład interfejs kalkulatora. Kod źródłowy będzie więc następujący:
#include <gtk/gtk.h> int main( int argc, char *argv[]) { GtkWidget *okno; GtkWidget *tabela; GtkWidget *przycisk[16]; gtk_init(&argc, &argv); okno = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(okno), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(okno), 250, 180); gtk_window_set_title(GTK_WINDOW(okno), "Kurs GTK+"); gtk_container_set_border_width(GTK_CONTAINER(okno), 5); tabela = gtk_table_new(4, 4, TRUE); gtk_table_set_row_spacings(GTK_TABLE(tabela), 2); gtk_table_set_col_spacings(GTK_TABLE(tabela), 2); przycisk[0] = gtk_button_new_with_label ("7"); przycisk[1] = gtk_button_new_with_label ("8"); przycisk[2] = gtk_button_new_with_label ("9"); przycisk[3] = gtk_button_new_with_label ("/"); przycisk[4] = gtk_button_new_with_label ("4"); przycisk[5] = gtk_button_new_with_label ("5"); przycisk[6] = gtk_button_new_with_label ("6"); przycisk[7] = gtk_button_new_with_label ("*"); przycisk[8] = gtk_button_new_with_label ("1"); przycisk[9] = gtk_button_new_with_label ("2"); przycisk[10] = gtk_button_new_with_label ("3"); przycisk[11] = gtk_button_new_with_label ("-"); przycisk[12] = gtk_button_new_with_label ("0"); przycisk[13] = gtk_button_new_with_label (","); przycisk[14] = gtk_button_new_with_label ("="); przycisk[15] = gtk_button_new_with_label ("+"); for (int x = 0; x < 4; x++) for (int y = 0; y < 4; y++) gtk_table_attach_defaults (GTK_TABLE(tabela), przycisk[(y*4)+x], x, x+1, y, y+1); gtk_container_add(GTK_CONTAINER(okno), tabela); g_signal_connect(G_OBJECT(okno), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(okno); gtk_main(); return 0; }
Efekt działania takiego programu jest następujący:
5.4. GtkAlignment
Ostatnim z kontenerów, jaki zostanie omówiony w tym rozdziale jest GtkAlignment. Służy on raczej nie tyle do tworzenia całego interfejsu, a do umieszczania widżetów w określonym miejscu. Tworzy się go następującą funkcją:
GtkWidget* gtk_alignment_new (gfloat xalign, gfloat yalign, gfloat xscale, gfloat yscale);
Pierwsze 2 argumenty to żądane położenie widżetu na osi x i y, natomiast następne 2 to jego wielkość. Oba argumenty to liczby typu float z przedziału 0-1.
Aby na przykład utworzyć puste okno z przyciskiem „Zamknij” w prawym dolnym rogu, można posłużyć się kodem:
#include <gtk/gtk.h> int main( int argc, char *argv[]) { GtkWidget *okno; GtkWidget *alignment; GtkWidget *zamknij; gtk_init(&argc, &argv); okno = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(okno), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(okno), 250, 100); gtk_window_set_title(GTK_WINDOW(okno), "Kurs GTK+"); gtk_container_set_border_width(GTK_CONTAINER(okno), 5); zamknij = gtk_button_new_with_label ("Zamknij"); alignment = gtk_alignment_new( 1, 1, 0, 0 ); gtk_container_add(GTK_CONTAINER(okno), alignment); gtk_container_add(GTK_CONTAINER(alignment), zamknij); g_signal_connect(G_OBJECT(okno), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(okno); gtk_main(); return 0; }
Efekt będzie następujący:
W następnym rozdziale postaram sie omówić kilka widżetów.
2 komentarze
piotr
Mam pytanie czy można łączyć GtkHBox z GtkVBox w jednym oknie jeżeli tak to jak?
Potrzebuje przerobić parę wtyczek do Gimp-a konkretnie przenieść okno podglądu z góry na lewą stronę.
Przykład z takiego standardowego wyglądu http://i7.minus.com/jhiNVCAqkVNR8.png do takiego o wiele wygodniejszego http://i3.minus.com/jbwZbzQP0XvzY.png
strona z kodem źródłowym wtyczki http://registry.gimp.org/node/1444
btw: nie jestem programistą.lol
Dziękuje.
Piotr
m4tx
adminKontenery działają tak, że przechowują w sobie widżety. Warto jednak zauważyć, że kontener sam w sobie też jest widżetem. Oznacza to, że można umieszczać jeden kontener w drugi – na takiej zasadzie jest to tutaj zrobione.
A chcesz przerabiać wtyczki do Gimpa? 🙂 Wybacz – nie mam czasu, żeby patrzeć na kod losowych aplikacji. I generalnie też po to napisałem ten kurs – coby innym pomóc. :>