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. :>