在 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, |
第一個參數是一個指向發出信號的元件的指標,最後一個參數是一個指向資料的指標,就是上面 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() 是相同的。所以當使用這個函式連接信號時,回呼函式應該是這樣的形式
void callback_func( gpointer callback_data, |
這個物件通常是一個元件。然而我們一般不用函式 g_signal_connect_swapped() 設置回呼。它們在訊號被發射在一些其他物件時,常用來呼叫一個只接受一個單獨的元件或者物件作為參數的 GTK 函式,在 helloworld 範例裡,我們在按鈕上連結”clicked”訊號,但是在視窗上呼叫gtk_widget_destroy()。
假如你的回呼需要額外的資料,使用 g_signal_connect() 而不是 g_signal_connect_swapped()。
1 則留言