| 在 第一個 GTK 程式 中,當您按下視窗右上X鈕時,在GTK視窗的預設處理中,只
會隱藏視窗,而不會直接關閉程式,GTK有一套Signal與Callback函式的處理機制,在某個動作發生時,GTK會發出特定Signal,若您想
要進行某些處理,則需定義Callback函式,並透過g_signal_connect()等函式,將Signal與Callback函式加以連結。 以按下視窗右上X鈕為例,按下X鈕後,GTK預設會發出"destroy"的Signal,您可以使用g_signal_connect()將之連結至gtk_main_quit()函式,這個函式會結束gtk_main()的迴圈處理因而結束GTK程式: #include <gtk/gtk.h> 從g_、G_開頭的函式名稱可以知道,它們是GLib所提供的函式與巨集(在GTK+ 2.0中,Signal處理已由GTK移至GLib),g_signal_connect()第一個參數,必須是GtkObject或其衍生的類別實例, 代表Signal發出的來源物件,第二個參數是感興趣的信號,第三個參數是Callback函式,G_CALLBACK巨集強制會轉換函式型態為無參數無傳回值的GCallback函式型態: #define G_CALLBACK(f) ((GCallback) (f))
在這邊使用GTK的gtk_main_quit()函式,第四個參數是可以傳遞給Callback函式的相關資料,在這邊不需 要,設定為NULL即可。 g_signal_connect()實際上是巨集(定義在/usr/include/glib-2.0/gobject/gsignal.h),方便使用g_signal_connect_data()函式: #define g_signal_connect(instance, detailed_signal, c_handler, data) \
g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) g_signal_connect_data()會傳回gulong型態的handler id,函式的定義如下: gulong g_signal_connect_data(gpointer instance,
const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags); 如果您打算將Signal與Callback斷開連結,可以根據傳回的handler id來使用g_signal_handler_disconnect()函式,也可以根據handler id來使用g_signal_handler_is_connected()函式,測試Signal的連接狀態: void g_signal_handler_disconnect(gpointer object, gulong id);
例如一個連接Signal與斷開Signal的程式片段如下:gboolean g_signal_handler_is_connected(gpointer instance, gulong handler_id); ....
gulong handler_id = g_signal_connect(GTK_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); .... if (g_signal_handler_is_connected(window, id)) { g_signal_handler_disconnect(GTK_OBJECTS(window), handler_id); } 若只是想暫停(block)某Signal處理,則可以使用g_signal_handler_block(),想恢復被暫停的Signal處理,則可以使用g_signal_handler_unblock(): void g_signal_handler_block(gpointer object, gulong id);
void g_signal_handler_unblock(gpointer object, gulong id); 一個被g_signal_handler_block()函式呼叫n次的Signal處理,也必須被g_signal_handler_unblock()相對應的次數,才可以恢復原本來未暫停的狀態。 若在未知handler id的情況下,想要中斷、暫停或恢復信號連結,則可以嘗試使用g_signal_handlers_disconnect_by_func()、g_signal_handlers_block_by_func()、g_signal_handlers_unblock_by_func(),這三者其實都是巨集: #define g_signal_handlers_disconnect_by_func(instance, func, data) \
g_signal_handlers_disconnect_matched ((instance), \ (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), \ 0, 0, NULL, (func), (data)) #define g_signal_handlers_block_by_func(instance, func, data) \ g_signal_handlers_block_matched ((instance), \ (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), \ 0, 0, NULL, (func), (data)) #define g_signal_handlers_unblock_by_func(instance, func, data) \ g_signal_handlers_unblock_matched ((instance), \ (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), \ 0, 0, NULL, (func), (data)) g_signal_handlers_disconnect_matched()、g_signal_handlers_block_matched ()、g_signal_handlers_unblock_matched()會傳回guint的數值,表示符合的handler數目: guint g_signal_handlers_disconnect_matched(gpointer instance,
更多有關Signal函式的說明,可以參考GObject參考文件的 Signals。GSignalMatchType mask, guint signal_id, GQuark detail, GClosure *closure, gpointer func, gpointer data); guint g_signal_handlers_block_matched(gpointer instance, GSignalMatchType mask, guint signal_id, GQuark detail, GClosure *closure, gpointer func, gpointer data); guint g_signal_handlers_unblock_matched(gpointer instance, GSignalMatchType mask, guint signal_id, GQuark detail, GClosure *closure, gpointer func, gpointer data); |