在本章的GTK+程序設計中,咱們仍然要繼續向你們介紹和展現各類各樣的構件。react
GtkComboBox
構件的做用是讓程序使用者根據不一樣的需求從不少選項中進行選擇。web
#include <gtk/gtk.h> void combo_selected(GtkWidget *widget, gpointer window) { gchar *text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); gtk_label_set_text(GTK_LABEL(window), text); g_free(text); } int main( int argc, char *argv[]) { GtkWidget *window; GtkWidget *fixed; GtkWidget *combo; GtkWidget *label; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "GtkCombo"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 230, 150); fixed = gtk_fixed_new(); combo = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Ubuntu"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Mandriva"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Fedora"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Mint"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Gentoo"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Debian"); gtk_fixed_put(GTK_FIXED(fixed), combo, 50, 50); gtk_container_add(GTK_CONTAINER(window), fixed); label = gtk_label_new("-"); gtk_fixed_put(GTK_FIXED(fixed), label, 50, 110); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window)); g_signal_connect(G_OBJECT(combo), "changed", G_CALLBACK(combo_selected), (gpointer) label); gtk_widget_show_all(window); gtk_main(); return 0; }
上面的這個例子主要是完成一個個下拉選擇框( combo box)和一個標籤(label)。在這裏下拉選擇框有六個選項。他們的名字都是Linux操做系統的不一樣發行版本。標籤中的內容就是咱們所選擇的那個選項的內容。編程
combo = gtk_combo_box_new_text(); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Ubuntu"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Mandriva"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Fedora"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Mint"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Gentoo"); gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Debian");
在上面,咱們生成了一個GtkComboBox
構件;而後又把Linux 發行版本的名字填加到其中去。ubuntu
label = gtk_label_new("-");
一樣咱們也生成了一個標籤構件。swift
gchar *text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); gtk_label_set_text(GTK_LABEL(window), text); g_free(text);
上面的代碼代表,咱們從所選的選項中得到了文本內容,並把此內容的傳遞給了標籤構件。在官方公佈的GTK+編程文本中顯示:函數 gtk_combo_box_get_active_text()
的返回值是當前最新擊活選項所對應的內容。這也就是說,咱們有必要要釋放對應的內存空間。緩存
GtkHSeparator
構件是一條水平分割線。這也屬於一種佈局構件。這一類的構件都是出於界面設計需求的考慮。他的兄弟構件也就是豎直分割線構件 GtkVSeparator
。app
#include <gtk/gtk.h> int main( int argc, char *argv[]) { GtkWidget *window; GtkWidget *label1; GtkWidget *label2; GtkWidget *hseparator; GtkWidget *vbox; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_title(GTK_WINDOW(window), "GtkHSeparator"); gtk_window_set_resizable(GTK_WINDOW(window), FALSE); gtk_container_set_border_width(GTK_CONTAINER(window), 20); label1 = gtk_label_new("Zinc is a moderately reactive, blue gray metal \ that tarnishes in moist air and burns in air with a bright bluish-green flame,\ giving off fumes of zinc oxide. It reacts with acids, alkalis and other non-metals.\ If not completely pure, zinc reacts with dilute acids to release hydrogen."); gtk_label_set_line_wrap(GTK_LABEL(label1), TRUE); label2 = gtk_label_new("Copper is an essential trace nutrient to all high \ plants and animals. In animals, including humans, it is found primarily in \ the bloodstream, as a co-factor in various enzymes, and in copper-based pigments. \ However, in sufficient amounts, copper can be poisonous and even fatal to organisms."); gtk_label_set_line_wrap(GTK_LABEL(label2), TRUE); vbox = gtk_vbox_new(FALSE, 10); gtk_container_add(GTK_CONTAINER(window), vbox); hseparator = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(vbox), label1, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), hseparator, FALSE, TRUE, 10); gtk_box_pack_start(GTK_BOX(vbox), label2, FALSE, TRUE, 0); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window)); gtk_widget_show_all(window); gtk_main(); return 0; }
以上的代碼正是在向咱們展現了兩個label構件,內容是講的兩種化學元素的定義;接着呢這兩個構件又被一個叫作horizontal 的GtkHSeparator構件給分割開來了。這樣看起來,整個程序界面就美觀多啦!不是麼?:)ide
label1 = gtk_label_new("Zinc is a moderately reactive, blue gray metal \ that tarnishes in moist air and burns in air with a bright bluish-green flame,\ giving off fumes of zinc oxide. It reacts with acids, alkalis and other non-metals.\ If not completely pure, zinc reacts with dilute acids to release hydrogen.");
咱們首先生成了第一個label構件,內容是鋅的定義。函數
gtk_label_set_line_wrap(GTK_LABEL(label2), TRUE);
固然得有換行啦!上面的代碼就是給文本進行換行的。佈局
hseparator = gtk_hseparator_new();
而後咱們就又生成了一個水平分割器。(horizontal separator)
gtk_box_pack_start(GTK_BOX(vbox), label1, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), hseparator, FALSE, TRUE, 10); gtk_box_pack_start(GTK_BOX(vbox), label2, FALSE, TRUE, 0);
最後咱們把分割器放置在兩個標籤中間。
GtkEntry
構件是什麼?她其實就是一個只擁有單行文本輸入框的構件。她主要是用來進行單行文本的輸入。
#include <gtk/gtk.h> int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *table; GtkWidget *label1; GtkWidget *label2; GtkWidget *label3; GtkWidget *entry1; GtkWidget *entry2; GtkWidget *entry3; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_title(GTK_WINDOW(window), "GtkEntry"); gtk_container_set_border_width(GTK_CONTAINER(window), 10); table = gtk_table_new(3, 2, FALSE); gtk_container_add(GTK_CONTAINER(window), table); label1 = gtk_label_new("Name"); label2 = gtk_label_new("Age"); label3 = gtk_label_new("Occupation"); gtk_table_attach(GTK_TABLE(table), label1, 0, 1, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), label2, 0, 1, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), label3, 0, 1, 2, 3, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); entry1 = gtk_entry_new(); entry2 = gtk_entry_new(); entry3 = gtk_entry_new(); gtk_table_attach(GTK_TABLE(table), entry1, 1, 2, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), entry2, 1, 2, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), entry3, 1, 2, 2, 3, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_widget_show(table); gtk_widget_show(label1); gtk_widget_show(label2); gtk_widget_show(label3); gtk_widget_show(entry1); gtk_widget_show(entry2); gtk_widget_show(entry3); gtk_widget_show(window); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_main(); return 0; }
在本節的例子中咱們向你們展現的是三個文本輸入框和分別對應的三個標籤。
table = gtk_table_new(3, 2, FALSE); gtk_container_add(GTK_CONTAINER(window), table);
爲了方便咱們管理構件,咱們使用了table容器構件。
entry1 = gtk_entry_new(); entry2 = gtk_entry_new(); entry3 = gtk_entry_new();
生成三個文本輸入框。
gtk_table_attach(GTK_TABLE(table), entry1, 1, 2, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), entry2, 1, 2, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5); gtk_table_attach(GTK_TABLE(table), entry3, 1, 2, 2, 3, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 5, 5);
把構件放置到table構件中。
GtkImage
構件功能是用來顯示圖象的。
#include <gtk/gtk.h> int main( int argc, char *argv[]) { GtkWidget *window; GtkWidget *image; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 230, 150); gtk_window_set_title(GTK_WINDOW(window), "Red Rock"); gtk_window_set_resizable(GTK_WINDOW(window), FALSE); gtk_container_set_border_width(GTK_CONTAINER(window), 2); image = gtk_image_new_from_file("redrock.png"); gtk_container_add(GTK_CONTAINER(window), image); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window)); gtk_widget_show_all(window); gtk_main(); return 0; }
在咱們本節的這個例子中,咱們向你們展現,咱們是如何把一個城堡的圖象用GTK+顯示出來的。這個城堡叫作Red Rock 位於斯洛伐克的西部。若是你喜歡的話能夠下載這個圖片。 here.
gtk_container_set_border_width(GTK_CONTAINER(window), 2);
咱們給這個圖片設置了2px 的邊框大小。
image = gtk_image_new_from_file("redrock.png"); gtk_container_add(GTK_CONTAINER(window), image);
咱們從一個圖象文件中加載了圖象,並把他放到佈局構件中。
構件GtkStatusbar
是的功能是用來顯示狀態信息用的。他一般被自動強制放置於應用程序窗口的底部。
#include <gtk/gtk.h> void button_pressed(GtkWidget *widget, gpointer window) { gchar *str; str = g_strdup_printf("Button %s clicked", gtk_button_get_label(GTK_BUTTON(widget))); gtk_statusbar_push(GTK_STATUSBAR(window), gtk_statusbar_get_context_id(GTK_STATUSBAR(window), str), str); g_free(str); } int main( int argc, char *argv[]) { GtkWidget *window; GtkWidget *fixed; GtkWidget *button1; GtkWidget *button2; GtkWidget *statusbar; GtkWidget *vbox; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 280, 150); gtk_window_set_title(GTK_WINDOW(window), "GtkStatusbar"); vbox = gtk_vbox_new(FALSE, 2); fixed = gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(window), vbox); gtk_box_pack_start(GTK_BOX(vbox), fixed, TRUE, TRUE, 1); button1 = gtk_button_new_with_label("OK"); gtk_widget_set_size_request(button1, 80, 30 ); button2 = gtk_button_new_with_label("Apply"); gtk_widget_set_size_request(button2, 80, 30 ); gtk_fixed_put(GTK_FIXED(fixed), button1, 50, 50); gtk_fixed_put(GTK_FIXED(fixed), button2, 150, 50); statusbar = gtk_statusbar_new(); gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, TRUE, 1); g_signal_connect(G_OBJECT(button1), "clicked", G_CALLBACK(button_pressed), G_OBJECT(statusbar)); g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(button_pressed), G_OBJECT(statusbar)); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window)); gtk_widget_show_all(window); gtk_main(); return 0; }
在咱們上面的這段代碼示例中,咱們展現了兩個按鈕和一個狀態欄。若是咱們單擊按鈕,一條信息便在狀態欄中顯示出來。也就說,狀態欄反映了哪一個按鈕被咱們按下了。
gchar *str; str = g_strdup_printf("Button %s clicked", gtk_button_get_label(GTK_BUTTON(widget)));
這裏咱們生成了一條消息。
gtk_statusbar_push(GTK_STATUSBAR(window), gtk_statusbar_get_context_id(GTK_STATUSBAR(window), str), str);
而後咱們把這條消息放置在狀態欄中。
構件GtkIconView 的功能是用來在一個柵格中顯示一系列的圖標。
#include <gtk/gtk.h> #include <assert.h> enum { COL_DISPLAY_NAME, COL_PIXBUF, NUM_COLS }; GtkTreeModel * init_model(void) { GtkListStore *list_store; GdkPixbuf *p1, *p2, *p3, *p4; GtkTreeIter iter; GError *err = NULL; p1 = gdk_pixbuf_new_from_file("ubuntu.png", &err); p2 = gdk_pixbuf_new_from_file("gnumeric.png", &err); p3 = gdk_pixbuf_new_from_file("blender.png", &err); p4 = gdk_pixbuf_new_from_file("inkscape.png", &err); assert(err==NULL); list_store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, GDK_TYPE_PIXBUF); int i = 0; for (i; i < 50; i++) { gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COL_DISPLAY_NAME, "ubuntu", COL_PIXBUF, p1, -1); gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COL_DISPLAY_NAME, "gnumeric", COL_PIXBUF, p2, -1); gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COL_DISPLAY_NAME, "blender", COL_PIXBUF, p3, -1); gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COL_DISPLAY_NAME, "inkscape", COL_PIXBUF, p4, -1); } return GTK_TREE_MODEL(list_store); } int main (int argc, char *argv[]) { GtkWidget *window; GtkWidget *icon_view; GtkWidget *sw; gtk_init (&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (window), "Icon View"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_container_set_border_width(GTK_CONTAINER(window), 10); gtk_widget_set_size_request(window, 350, 330); sw = gtk_scrolled_window_new(NULL, NULL); gtk_container_add(GTK_CONTAINER (window), sw); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); icon_view = gtk_icon_view_new_with_model(init_model()); gtk_container_add(GTK_CONTAINER(sw), icon_view); gtk_icon_view_set_text_column(GTK_ICON_VIEW(icon_view), COL_DISPLAY_NAME); gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(icon_view), COL_PIXBUF); gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(icon_view), GTK_SELECTION_MULTIPLE); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; }
在本節的代碼示例中,咱們顯示了200個小圖標。他們分別是四個著名開源項目的圖標。
p1 = gdk_pixbuf_new_from_file("ubuntu.png", &err); p2 = gdk_pixbuf_new_from_file("gnumeric.png", &err); p3 = gdk_pixbuf_new_from_file("blender.png", &err); p4 = gdk_pixbuf_new_from_file("inkscape.png", &err);
咱們從磁盤文件中載入了四個圖標。
list_store = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, GDK_TYPE_PIXBUF);
咱們將存儲文本和像素緩衝區(pixbuf)的數據。
gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COL_DISPLAY_NAME, "ubuntu", COL_PIXBUF, p1, -1);
上面這段代碼,正是把新圖標填加到準備顯示的緩存區中。
icon_view = gtk_icon_view_new_with_model(init_model()); gtk_container_add(GTK_CONTAINER(sw), icon_view); gtk_icon_view_set_text_column(GTK_ICON_VIEW(icon_view), COL_DISPLAY_NAME); gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(icon_view), COL_PIXBUF);
最後,咱們又生成了一個GtkIconView
構件而後把圖標和圖標文本整合在一塊兒。 (譯者注:若是本節理解起來有難度的話,正是說明你對MVC的概念還不是很清楚,建議查看相關文檔:))