簡介 GTK+(GIMP TOOLKIT),是一個跨平台的圖形界面(GUI)開發工具,是目前Linux操作系統中較常用的圖形界面開發工具之一,它采用一種非常有特色的面向對象的C語言開發框架(C Framework),應用它可以輕松的在LINUX系統平台的X WINDOW環境下開發出漂亮的圖形界面應用程序。直接用GTK+開發應用程序必須使用C/C++語言,所以您必須具有一定的C語言基礎,最好用C語言開發過應用程序。 GTK+2.0是GNOME2桌面環境的圖形基礎,是GNU工程的一部分,采用LGPL條款分發。於2002年3月正式發布,目前最穩定的版本是2.0.6 ,最新的2.1.0 版正在開發測試過程中,可以到FTP://ftp.gtk.org/pub/gtk/v2.1下載它的源代碼。
控件的分類 GTK+中的控件實際是用C語言對X WINDOW系統中的控件的簡單封裝,在GTK+中,控件大體上可以分為兩類,即: 容器控件 非容器控件 非容器控件 GTK+中的非容器控件包括諸如文字標簽、圖像、單行輸入等圖形界面編程中的最基本的元素。下面為簡單的示例代碼: GtkWidget *label; GtkWidget *image; GtkWidget *entry; label = gtk_label_new("this is a test label"); /* 創建文字標簽控件 */ image = gtk_image_new_from_file("image.png"); /* 創建圖像控件,指定要顯示的圖像名 */ entry = gtk_entry_new(); /* 創建單行輸入控件 */
容器控件 在GTK+中,除了非容器控件外,其它多數控件均屬於容器控件,所有容器都是基於GtkContainer對象的,它又分為兩類:只能容納一個控件的容器和能容納多個控件的容器。
只能容納一個控件的容器 只能容納一個控件的容器是基於GtkBin對象的,其中包括: 窗口類控件(GtkWindow,GtkDialog,GtkMessageDialog,主要是窗口和各種對話框) 滾動窗口(GtkScrolledWindow) 框架類控件(GtkFrame,GtkASPectFrame) 視口(GtkViewport) 各種按鈕(GtkButton,GtkToggleButton) 浮動窗口(GtkHandleBox) 事件盒(GtkEventBox)等 這些控件的特色是只能容納一個子控件,要想容納多個子控件,必須向其中添加一個能容納多個控件的容器,然後再向此容器中添加控件。 能容納多個控件的容器 能容納多個控件的容器從功能上又可分為兩種:一種是只能設定子控件的排放次序,不能設定子控件幾何位置的容器;另一種是可以設定子控件幾何位置的容器。 不能設定子控件幾何位置的容器 只能設定子控件的排放次序、不能設定子控件幾何位置的容器,是GTK+中最常用的容器控件,它包括以下幾類: 只能容納一行或一列子控件的容器--盒狀容器(GtkBox),它又分成兩種橫向盒狀容器(GtkHBox)和縱向盒狀容器(GtkVBox); 盒狀容器的子類--按鈕盒(GtkButtonBox),也分為橫向按鈕盒(GtkHButtonBox)和縱向按鈕盒(GtkVButtonBox); 能容納多行多列子控件的容器--格狀容器(GtkTable); 能控制子控件的尺寸的容器--分隔面板(GtkPaned),它也分成橫向分隔面板(GtkHPaned)和縱向分隔面板(GtkVPaned); 能分頁顯示多個子控件的容器--多頁顯示控件(GtkNotebook); 此外還包括菜單條、工具條、列表控件等,它們實際上是上述容器控件的靈活運用,本教程不做詳細介紹 可以設定子控件幾何位置的容器 可以設定子控件幾何位置的容器類似於WINDOWS編程中的FORM控件,主要包括兩種: 自由布局控件(GtkFixed)-- 可以按固定坐標放置子控件的容器 布局控件(GtkLayout)-- 是一個無窮大的滾動區域,可以包含子控件,也可以定制繪圖 以上分類列出了GTK+中各種常用的容器控件的基本情況,含概了GTK+控件大多數的內容。GTK中的容器中又可以包含容器,這樣創建一個復雜的應用程序界面變得非常輕松,也使在LINUX下創建圖形界面應用程序不再難做了。
布局技巧 使用盒狀容器 盒狀容器是在布局中最常用的一種容器控件,它可以將一系列子控件按順序組織擺放到一個特定的矩形區域內,或一行或一列,子控件有相同的寬度或高度;對於橫向盒狀容器中子控件的高度是一致的,而縱向盒狀容器中的子控件的寬度是一致的。 盒狀容器引入了"排放"這一概念,是指要加入盒狀容器中的子控件順序的起始位置,從前向後還是從後向前,對於橫向盒狀容器來說就是從左到右,對縱向盒狀容器來說就是從上到下,函數gtk_box_pack_start表示從前向後排列子控件,函數gtk_box_pack_end表示從後向前排列子控件,也可以兩者同時使用,在排列時還要設定容器中子控件的間距(以像素為單位),是否可擴展,是否填充滿整個容器空間等;此外還可以用函數gtk_container_set_border_width來設定容器的邊框寬度。 下面代碼創建了一個簡單的橫向盒狀容器,運行結果如圖所示: box = gtk_hbox_new(FALSE,0); button1 = gtk_button_new_with_label("按鈕一"); gtk_box_pack_start(GTK_BOX(box),button1,FALSE,FALSE,3); button2 = gtk_button_new_with_label("按鈕二"); gtk_box_pack_start(GTK_BOX(box),button2,FALSE,FALSE,3); button3 = gtk_button_new_with_label("按鈕三"); gtk_box_pack_start(GTK_BOX(box),button3,TRUE,TRUE,3); button4 = gtk_button_new_with_label("按鈕四"); gtk_box_pack_start(GTK_BOX(box),button4,FALSE,FALSE,3); 按鈕一、二、四在排列時設定其可擴展屬性為FALSE,不能隨窗口的改變來改變大小,而按鈕三的可擴展屬性設為TRUE,則可以改變大小,所以在窗口拉長時按鈕三隨之變長,看到了這樣的效果圖。同樣我們可以用gtk_vbox_new(FALSE,0);函數來創建一個縱向的盒狀容器。 使用按鈕盒 按鈕盒是盒狀容器的子類,所以它具有盒狀容器的所有功能,又具有自己的特點,如可以設定子控件的排列方式等。下面代碼創建了一個簡單的按鈕盒,運行結果如圖所示: bbox = gtk_hbutton_box_new(); gtk_box_set_spacing(GTK_BOX(bbox),5); /* 以上代碼設定按鈕盒的子控件間隙 */ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox),GTK_BUTTONBOX_END); /* 以上代碼設定按鈕盒的子控件排列方式 */ button1 = gtk_button_new_with_label("按"); gtk_box_pack_start(GTK_BOX(bbox),button1,FALSE,FALSE,0); button2 = gtk_button_new_with_label("鈕"); gtk_box_pack_start(GTK_BOX(bbox),button2,FALSE,FALSE,0); button3 = gtk_button_new_with_label("盒"); gtk_box_pack_start(GTK_BOX(bbox),button3,FALSE,FALSE,0); 與盒狀容器一樣,向按鈕盒中排列按鈕也使用gtk_box_pack_*系列函數,代碼中我們設定按鈕盒中子控件的間距為5個像素,設定按鈕盒的屬性為GTK_BUTTONBOX_END,即子控件的對齊方式為尾對齊(靠橫向的左側或縱向的下部),所以看到這一效果。同樣還可以用gtk_vbutton_box_new函數來創建縱向的按鈕盒。 使用盒狀容器創建帶有圖像和文字的按鈕 按鈕是一種只能容納一個控件的容器,我們這裡加了一個盒狀容器,再向盒狀容器中加圖像和按鈕,從而形成了帶有圖像和文字的按鈕。這正是為什麼窗口是一種只能容納一個控件的容器,但卻容納了很多控件的原因,其它的此類容器也是如此。下面代碼創建了一個帶圖像和標簽的按鈕(圖像在左面,文字在右面),改動圖像和文字的排放順序,或創建為後縱向盒狀容器後可以創建另外三種形式的按鈕,效果如圖所示:(看完這段代碼,相信你一定再也不會為創建帶圖像的按鈕發愁了) image = gtk_image_new_from_stock(GTK_STOCK_HELP,GTK_ICON_SIZE_MENU); label = gtk_label_new("按鈕標簽"); box = gtk_hbox_new(FALSE,0); gtk_box_pack_start(GTK_BOX(box),image,FALSE,FALSE,2); gtk_box_pack_start(GTK_BOX(box),label,FALSE,FALSE,2); button = gtk_button_new(); /* 創建按鈕 */ gtk_container_add(GTK_CONTAINER(button),box);/* 將盒狀容器加入到按鈕中 */ 使用滾動窗口 下面代碼創建了一個滾動窗口,並向其中加入了一個帶有三個按鈕的縱向盒狀容器,運行效果如圖所示: swin = gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); vbox = gtk_vbox_new(FALSE,0); gtk_container_set_border_width(GTK_CONTAINER(vbox),10); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin),vbox); button1 = gtk_button_new_with_label("測試按鈕一"); gtk_box_pack_start(GTK_BOX(vbox),button1,FALSE,FALSE,5); button2 = gtk_button_new_with_label("測試按鈕二"); gtk_box_pack_start(GTK_BOX(vbox),but