您的位置:首页 > 编程语言 > Go语言

GTK Gossip: 使用 Signal 关闭视窗

2010-12-08 16:19 363 查看
在
第一個 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>

int main(int argc, char *argv[]) {

GtkWidget *window;

gtk_init(&argc, &argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_window_set_title(GTK_WINDOW(window), "哈囉!GTK+!");

g_signal_connect(GTK_OBJECT(window), "destroy",

G_CALLBACK(gtk_main_quit), NULL);

gtk_widget_show(window);

gtk_main();

return 0;

}

從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);

gboolean g_signal_handler_is_connected(gpointer instance, gulong handler_id);

例如一個連接Signal與斷開Signal的程式片段如下:

....

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,

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);

更多有關Signal函式的說明,可以參考GObject參考文件的 Signals
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: