訊號和回呼函數的原理
|
在 2.0 版,訊號系統已從 GTK 移到 GLib,因此在函數和類型的說明中有首碼 "g_" 而不是 "gtk_"。我們不打算介紹 GLib 2.0 訊號系統相對 GTK 1.2 訊號系統擴充的細節。 |
在我們詳細分析 helloworld
程式之前,我們會討論訊號和回呼函數。GTK 是一個事件驅動的工具包,意味著它會等在 gtk_main() 那裡,直到下一個事件發生,才把控制權傳給適當的函數。
控
制權的傳遞是使用“訊號”的辦法來完成的。(注意這裡的訊號並不等同於 Unix 系統裡的訊號,並且也不是用它們實現的,雖然使用的術語是一樣的。)
當一個事件發生時,如按一下滑鼠鍵,所按的構件會“發出”適當的訊號。這就是 GTK 的工作機制。有所有構件都繼承的訊號,如
"destroy",有構件專有的訊號,如開關 (toggle) 按鈕發出的 "toggled" 訊號。
要使一個按鈕執行一個動作,我們需設定訊號和訊號處理函數之間的串連。可以這樣使用函數來設定串連:
gulong g_signal_connect( gpointer *object, const gchar *name, GCallback func, gpointer func_data ); |
第一個參數是要發出訊號的構件,第二個參數是你想要串連的訊號的名稱,第三個參數是訊號被捕獲時所要調用的函數,第四個參數是你想傳遞給這個函數的資料。
第三個參數指定的函數叫做回呼函數,一般為下面的形式:
void callback_func( GtkWidget *widget, gpointer callback_data ); |
第一個參數是一個指向發出訊號的構件的指標,第二個參數是一個指向資料的指標,就是上面 g_signal_connect() 函數的最後一個參數傳進來的資料。
注意上面回呼函數的聲明只是一般的形式,有些構件的特殊訊號會用不同的調用參數。
另一個在 helloworld
樣本中使用的調用,是:
gulong g_signal_connect_swapped( gpointer *object, const gchar *name, GCallback func, gpointer *slot_object ); |
g_signal_connect_swapped() 和 g_signal_connect() 相同,只是回呼函數只用一個參數,一個指向 GTK 對象的指標。所以當使用這個函數串連訊號時,回呼函數應該是這樣的形式
void callback_func( GtkObject *object ); |
這個對象通常是一個構件。然而我們一般不用函數 g_signal_connect_swapped() 設定回調。它們常用來調用一個只接受一個單獨的構件或者對象作為參數的 GTK 函數,如同我們的 helloworld
樣本中那樣。
擁
有兩個函數來設定訊號串連的目的只是為了允許回呼函數有不同數目的參數。GTK
庫中許多函數僅接受一個單獨的構件指標作為其參數,所以對於這些函數你要用
g_signal_connect_swapped(),然而對你自己定義的函數,你可能需要附加的資料提供給你的回呼函數。
| <<< Previous |
Home |
Next >>> |
| 編譯 Hello World 程式 |
Up |
事件 |