GTK圖形程式設計

才智咖 人氣:1.22W
GTK圖形程式設計
【摘要】 本文介紹了Linux平臺下的Xwindow圖形視窗程式設計工具GTK,並給出了用GTK程式設計的基本要素和步驟。【關鍵詞】GTK,回撥函式,訊息處理器,調節器GTK(GIMP Toolkit)是一個圖形使用者程式設計的介面工具。它註冊完全免費,所以用來開發自由軟體或商業軟體都不需要花費什麼。現在很多Linux整合系統都已經將GTK1.2版本打包進去了。包括RedHat Linux 6.0以上版本,還有中文化的Turbo Linux等等。它也越來越被普遍的於UNIX系統程式設計。還有一個元件叫Glib,它包含了一些標準應用的新擴充套件用來提高GTK的相容性。用於Linux系統的某些函式可能不適合標準的UNIX系統,例如g_strerror()函式等等。某些函式也擴充套件了GNUC的一般功能,例如g_malloc函式就有自己加強的除錯功能。GTK可以與多種語言繫結,包括C++, Guile, Perl, Python, Ton, Ada95, Objective C, Free Pascal, Eiffel。用標準C開發的程式,編譯軟體可用GNU並附帶上GTK選項即可。想用除了標準C以外的其它語言來開發Xwindow圖形使用者程式,則需要先一下有關繫結軟體的(HTTP:// )。 如果用C++語言來呼叫GTK進行開發,可以用已經和C++繫結的軟體叫GTK--軟體,來提供一個比GTK更好的C++編譯環境。已經開發出來GTK的增強版GTK+。GTK+是將GTK,GDK,GLIB整合在一起的開發包,可以工作在許多類似於UNIX的系統上,沒有GTK的平臺限制。1.GTK的訊息處理機制下面我們先看一個基本的例子,該例子產生一個200×200畫素的視窗。它不能自己退出,只能通過shell來殺死程序(呼叫kill命令)。/*例子 base.c */#include <gtk/gtk.h>int main( int argc,char *argv[ ] ){GtkWidget *window;gtk_init (&argc, &argv); /* 初始化顯示環境 */window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* 建立一個新的視窗*/gtk_widget_show (window); /*顯示視窗*/gtk_main (); /*進入睡眠狀態,等待事件啟用*/return(0);}從上面的程式可以看出,GTK是一個事件驅動工具包,當它執行到gtk_main()函式時會自動睡眠,直到有事件發生,控制權轉讓給相應的函式呼叫,在該函式中可以用標準C寫出相應的事物邏輯。這與windows 上的程式處理是一樣的。對視窗物件上發生的事件(如按下滑鼠,啟用鍵盤等),GTK也有相應的訊息訊號產生。這時就需要程式設計師建立一個訊號處理器來捕獲該訊號,並告訴GTK程式事件發生後呼叫哪個回撥函式。訊號處理器的建立函式定義如下:gint gtk_signal_connect( GtkObject *object, gchar *name,GtkSignalFunc callback_func, gpointer func_data );返回值是一個區分同一物件中的事件與不同回撥函式的關聯標籤。這樣可以做到一個物件的一個訊號就有任意多個回撥函式,並且每一個都會按照宣告的順序執行。函式呼叫的第一個引數是產生訊號的widget元件(即按鈕等視窗構件),而name則是希望捕獲的訊號或事件的名稱,callback_func則是事件發生後所呼叫的回撥函式名稱,而第四個引數func_data則是傳遞給回撥函式的引數。回撥函式要定義在主程式的前面,它們的一般格式都如下所示:void callback_func( GtkWidget *widget, gpointer func_data );呼叫下面這個將允許你將回調函式與事件的關聯斷開:void gtk_signal_disconnect( GtkObject *object, gint id );該函式的第二個引數就是上述gtk_signal_connect()函式的返回值,即關聯標籤。第一個引數指向了去除關聯的物件名稱。這樣可以做到斷開事件與回撥函式的關聯,使得事件發生後,不會呼叫相關的回撥函式。佈局格式2.1打包盒子對GTK顯示格式的控制是通常通過打包盒子來完成的。widget元件打包可以採用兩種方式,水平盒子和垂直盒子。若將widget元件打包進平行盒子,元件就被依次水平的插入視窗;若是垂直盒子,則元件排列是垂直的。產生新的水平盒子的函式為GtkWidget *gtk_hbox_new (gint homogeneous, gint spacing);引數homogeneous是用來控制是否盒子中的每個元件都有同樣的大小(例如水平盒子中的控制元件有同樣的寬度,垂直盒子中的控制元件有同樣的高度)。Spacing引數是元件之間的間隔。垂直盒子的建立函式是gtk_vbox_new(),定義與水平盒子一致。gtk_box_pack_start()和gtk_box_pack_end()函式是用來將打包物件放入這些盒子中的。void gtk_box_pack_start( GtkBox *box, GtkWidget *child,gint expand, gint fill, gint padding );第一個引數是你將元件打進去的盒子指標,第二個引數是你將要打進去的元件指標。Expand引數是用來控制是否允許元件擴充套件至分配給盒子空間的大小(選TRUE),還是盒子的大小收縮到元件那麼大(選FALSE)。函式中的fill引數是用來控制是否將多餘的空間分配給元件,即將元件擴充套件到盒子的大小(選TRUE),或者多餘的空間不變,保留作為盒子和打包元件間的間隔。該引數只有在expand引數取TRUE時才有效。Padding引數是指元件四周與盒子的間隔大小。注意fill取FALSE值,expand取TRUE值時與expand取FALSE值,fill值無效的區別。前者的盒子仍是原來建立盒子時指定的大小,而後者的盒子已經縮小到打包元件的大小了。gtk_box_pack_end()函式的引數與上面描述的一致。只是排列順序分別是從下到上
,從右到左。最後將所有的盒子或元件打包到一個大盒子中,用gtk_container_add()函式將盒子加入視窗即可。
2.2表格打包我們可以產生一個表格,將widget元件一一放入。Widget元件將佔據所有分配給它的空間。建立表格是用下面的函式:GtkWidget *gtk_table_new( gint rows, gint columns,gint homogeneous );第一個引數,顯而易見,是表格的行數。後面的引數則是表格的列數。homogeneous引數則是用來安排表格間隔大小。如果它取TRUE,則表格中每個小格的大小用表格中最大元件的大小來設定的,所有的小格大小都是一樣的。如果homogeneous引數取FALSE的,每個小格的大小都用同行中最高元件的高度,同列中最寬元件的寬度。將一個widget元件放入一個表格,用下面的函式:void gtk_table_attach( GtkTable *table, GtkWidget *child, gint left_attach,gint right_attach, gint top_attach, gint bottom_attach,gint xoptions, gint yoptions, gint xpadding, gint ypadding );left_attach引數和right_attach引數將指出在哪兒放置元件,以及用了多少盒子。如果你想在兩行兩列的表格中的右下小格中加入一個按鈕,並且想讓按鈕充滿那個小格,則引數可以選擇left_attach = 1, right_attach = 2, top_attach = 1, bottom_attach = 2。其實left_attach也就是元件所在小格的左邊框是表格的第幾條邊數,其它依此類推。引數xoptions和yoptions是用來確定打包選項的,可以用OR來選擇多個選項。調節器
GTK有很多元件可以用滑鼠或鍵盤來調整,例如範圍元件(Range Widget)。還有一些元件在整個資料區域的一部分是可調整的,例如文字元件(Text Widget)和視口元件(Viewport Widget)。很明顯,程式是要能夠對可調整元件所產生的變化進行處理。一種解決辦法是讓可調整元件在釋放自己的訊號時,將調整資料值傳遞訊號處理器。或者用另外一種解決將調整資料值放入一個資料結構,由程式訪問該結構來獲得改變的引數值。有時候你可能需要將幾個可調整元件的調節相關聯,調整一個也會導致另一個的變化。最明顯的例子就是滾動條與文字編輯框元件的處理。如果這些相關聯的元件分別有自己處理調整資料的方法,則程式設計師必須自己寫一個訊號處理器,將一個元件的調整資料轉換成另一個元件的調整資料,並呼叫調整設定函式將該值設定進去。GTK呼叫了調節器成功的解決了這個。調節器不是元件,而是儲存和傳遞調整資料的結構。最典型的調整器是儲存配置引數和範圍元件的值。不同的是調整器也是從物件(Object)繼承而來的,它有許多不同於資料結構的特性。最重要的是,它也會釋放訊號,並且這些訊號不僅可以被程式捕獲來響應使用者的調整和編輯,還可以在可調整元件中透明的.傳播調整資料。一般調節器會建立元件時自動建立。例如讓文字元件和滾動條元件用同一個調節器如下所示:text = gtk_text_new (NULL, NULL);/* 將剛建立的調節器用於垂直滾動條 */vscrollbar = gtk_vscrollbar_new (GTK_TEXT(text)->vadj);調節器是從物件Object繼承下來的。所以它與其它的元件物件一樣,能夠產生訊號。當好幾個元件共享一個調節器時,它們都會和一個訊號處理器相關聯。這個訊號處理器是用來處理“value_changed”訊號的,跟程式中處理訊號是一樣。下面是在GtkAdjustmentClass結構中該訊號的定義:void (* value_changed) (GtkAdjustment *adjustment);不同的可調整元件都用一個調節器時,任何一個元件發生調整變化都會產生該訊號。有兩種情況會導致這個現象的發生。第一種情況是使用者在用滑鼠或鍵盤調整該元件(例如拉滾動條),或者直接在程式中用gtk_adjustment_set_value()函式來改變調節器中的value值。當調節器的upper引數和lower引數被重新配置時,就象使用者需要給一個文字編輯框加入了更多的文字後,調節器就會釋放出“changed”訊號。它的定義如下:void (* changed) (GtkAdjustment *adjustment);範圍元件將該訊號與一個訊號處理器相關聯,並隨時在面板上反映引數的變化。舉個例子,滾動條中滑動鍵的大小與調節器中upper,lower值之差正好成反比。一旦前者有任何改變,面板上的顯示也會相應產生變化。不需要在程式中將一個訊號處理器與該訊號相關聯,一切都是GTK完成的。如果你直接設定了調節器的這些引數,則需要在程式中呼叫下面的語句來釋放訊號:gtk_signal_emit_by_name (GTK_OBJECT (adjustment), "changed");建立元件小結
從上面可看出,建立一個widget元件可以用以下幾個步驟完成:gtk_*_new()—呼叫一個非常有用的函式來產生一個新的widget元件。4.2用gtk_box_pack_start()函式連線所有的訊號和事件,產生相應的事件處理器來呼叫回撥函式。4.3設定widget元件以及調節器的特性。4.4用合適的函式將widget元件打包到一個容器(盒子或表格)中,例如gtk_box_container_start()函式或者gtk_container_add()函式等。4.5用gtk_widget_show()函式來顯示元件。用上述方法可創建出程式設計師所需要的任意視窗構件,再將容器打入視窗並顯示視窗之後,程式便進入主迴圈睡眠狀態,主程式編制也就結束了。事件的處理邏輯放到回撥函式中編制。編譯程式用下面的命令:gcc my_prog.c –o my_prog.o –lgtk –lgdk ↙完成後在Xwindow環境下執行my_prog.o程式即可。X視窗(Xwindow)和GNU編譯系統已成為應用linux或unix作業系統的機工作站和大型計算機上最主要的圖形使用者介面系統,在微機上也有廣泛應用。而GTK正是兩者結合的程式設計開發包。它比以往用的Xwindow/Motif程式設計更為簡單方便,功能也很強大,有著較好的應用前景。目前網上已經有很多利用該軟體包開發出來的自由釋出軟體,極大的豐富了Linux平臺的應用。[]1.《GTK Turtoil》 Peter Mattis, Spencer Kimball, Josh MacDonald著2.《linux系統管理指南》 rinski,et著 曉冬 馬丁譯 1999,清華大學出版社3.《UNIX程式設計》 ard Stevens著 1998,清華大學出版