設計視窗程式的人都知道,在視窗程式中最麻煩也最難的就是版面配置,每次都為了元件的位置擺放在傷腦筋,目前為止在 自訂 callback 函式 看到的範例,,僅曾經單純的將GtkButton置放入GtkContainer之中,GtkButton預設填滿整個視窗,若是有多個元件,元件位置是否會適當的自我調整大小、位置(或像是字型大小自動調整之類的),以配合視窗縮放展現適當的觀感等,這些都是版面配置的議題。
視窗程式的解決方案都會提供一些現成的版面配置方式,讓您可以不必自行配置元件位置,在GTK中,基本版面配置可以透過GtkBox這個Widget來進行,這是個不可視的 (Invisible)元件,可以容納其它Widget,其繼承架構關係如下:
GtkBox繼承自GtkContainer,有兩個主要子類別GtkVBox與GtkHBox,而GtkButtonBox與前兩者類似,主要是作為按鈕群組版面配置使用。
以下先說明GtkVBox與GtkHBox的使用,基本上兩者使用是相似的,要建立一個GtkHBox,可以如下撰寫:
第一個參數決定GtkHBox中所有的元件是否平均分配空間,第二個參數則設定兩個元件之間的空間,單位是像素(Pixel)。若要將元件加入GtkHBox中,則要使用gtk_box_pack_start()或gtk_box_pack_end(),前者將元件從GtkHBox的左邊開始加入(如果是GtkVBox就是從上面),後者則加至右邊( 如果是GtkVBox就是從下面 ),例如:
第一個布林參數設定Widget是否使用所有的可用空間,設定為TRUE時,Widget的可用空間會隨著GtkHBox大小改變而改變(但Widget元件本身不變)。第二個參數只有在第一個參數為TRUE時才有用,可設定Widget是否填滿可用空間,設定為TRUE時,Widget的大小會隨GtkHBox大小改變而改變。
以下直接看例子,使用GtkHBox進行元件的版面配置,您以水平的方式來擺放元件:
程式中使用到GtkSpinButton與GtkLabel,並作了適當的Signal,讓您可以設定數字並顯示在另一個文字元件上, GtkSpinButton與GtkLabel之後還會介紹,現在請注意粗體字有關版面配置的程式碼即可,一個執行的畫面如下所示:
![](http://gtk.awaysoft.com/docs/GTKGossip/images/GtkHBoxGtkVBox-1.jpg)
根據gtk_box_pack_start()的設定,元件會自動填滿視窗,如果您拉動視窗,則當中的元件也會適當的變動大小:
![](http://gtk.awaysoft.com/docs/GTKGossip/images/GtkHBoxGtkVBox-2.jpg)
如果使用GtkVBox來改寫上面的範例:
一個執行畫面如下所示:
![](http://gtk.awaysoft.com/docs/GTKGossip/images/GtkHBoxGtkVBox-3.jpg)
点击打开链接
視窗程式的解決方案都會提供一些現成的版面配置方式,讓您可以不必自行配置元件位置,在GTK中,基本版面配置可以透過GtkBox這個Widget來進行,這是個不可視的 (Invisible)元件,可以容納其它Widget,其繼承架構關係如下:
GObject
+----GInitiallyUnowned
+----GtkObject
+----GtkWidget
+----GtkContainer
+----GtkBox
+----GtkVBox
+----GtkHBox
+----GtkButtonBox
+----GInitiallyUnowned
+----GtkObject
+----GtkWidget
+----GtkContainer
+----GtkBox
+----GtkVBox
+----GtkHBox
+----GtkButtonBox
GtkBox繼承自GtkContainer,有兩個主要子類別GtkVBox與GtkHBox,而GtkButtonBox與前兩者類似,主要是作為按鈕群組版面配置使用。
以下先說明GtkVBox與GtkHBox的使用,基本上兩者使用是相似的,要建立一個GtkHBox,可以如下撰寫:
GtkWidget *hbox = gtk_hbox_new(TRUE, 5);
第一個參數決定GtkHBox中所有的元件是否平均分配空間,第二個參數則設定兩個元件之間的空間,單位是像素(Pixel)。若要將元件加入GtkHBox中,則要使用gtk_box_pack_start()或gtk_box_pack_end(),前者將元件從GtkHBox的左邊開始加入(如果是GtkVBox就是從上面),後者則加至右邊( 如果是GtkVBox就是從下面 ),例如:
GtkWidget *spinButton = gtk_spin_button_new_with_range(0.0, 100.0, 1.0);
gtk_box_pack_start(GTK_BOX(hbox), spinButton, TRUE, TRUE, 5);
第一個布林參數設定Widget是否使用所有的可用空間,設定為TRUE時,Widget的可用空間會隨著GtkHBox大小改變而改變(但Widget元件本身不變)。第二個參數只有在第一個參數為TRUE時才有用,可設定Widget是否填滿可用空間,設定為TRUE時,Widget的大小會隨GtkHBox大小改變而改變。
以下直接看例子,使用GtkHBox進行元件的版面配置,您以水平的方式來擺放元件:
- gtkhbox_demo.c
#include <gtk/gtk.h> void value_changed_callback(GtkSpinButton *spinButton, gpointer data) { gint value = gtk_spin_button_get_value_as_int(spinButton); GString *text = g_string_new(""); g_string_sprintf(text, "%d", value); gtk_label_set_text(GTK_LABEL(data), text->str); } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *spinButton; GtkWidget *label; GtkWidget *hbox; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "GtkHBox"); gtk_window_set_default_size(GTK_WINDOW(window), 200, 50); spinButton = gtk_spin_button_new_with_range(0.0, 100.0, 1.0); label = gtk_label_new("0"); hbox = gtk_hbox_new(TRUE, 5); gtk_box_pack_start(GTK_BOX(hbox), spinButton, TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 5); gtk_container_add(GTK_CONTAINER(window), hbox); g_signal_connect(GTK_OBJECT(spinButton), "value_changed", G_CALLBACK(value_changed_callback), label); g_signal_connect(GTK_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; }
程式中使用到GtkSpinButton與GtkLabel,並作了適當的Signal,讓您可以設定數字並顯示在另一個文字元件上, GtkSpinButton與GtkLabel之後還會介紹,現在請注意粗體字有關版面配置的程式碼即可,一個執行的畫面如下所示:
![](http://gtk.awaysoft.com/docs/GTKGossip/images/GtkHBoxGtkVBox-1.jpg)
根據gtk_box_pack_start()的設定,元件會自動填滿視窗,如果您拉動視窗,則當中的元件也會適當的變動大小:
![](http://gtk.awaysoft.com/docs/GTKGossip/images/GtkHBoxGtkVBox-2.jpg)
如果使用GtkVBox來改寫上面的範例:
- gtkvbox_demo.c
#include <gtk/gtk.h> void value_changed_callback(GtkSpinButton *spinButton, gpointer data) { gint value = gtk_spin_button_get_value_as_int(spinButton); GString *text = g_string_new(""); g_string_sprintf(text, "%d", value); gtk_label_set_text(GTK_LABEL(data), text->str); } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *spinButton; GtkWidget *label; GtkWidget *vbox; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "GtkVBox"); gtk_window_set_default_size(GTK_WINDOW(window), 200, 50); spinButton = gtk_spin_button_new_with_range(0.0, 100.0, 1.0); label = gtk_label_new("0"); vbox = gtk_vbox_new(TRUE, 5); gtk_box_pack_start(GTK_BOX(vbox), spinButton, TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 5); gtk_container_add(GTK_CONTAINER(window), vbox); g_signal_connect(GTK_OBJECT(spinButton), "value_changed", G_CALLBACK(value_changed_callback), label); g_signal_connect(GTK_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; }
一個執行畫面如下所示:
![](http://gtk.awaysoft.com/docs/GTKGossip/images/GtkHBoxGtkVBox-3.jpg)
点击打开链接