GTK Gossip: 自訂 callback 函式

来源:互联网 发布:淘宝网网支付方式 编辑:程序博客网 时间:2024/06/05 02:25
您可以自訂callback函式,使用g_signa_connect()函式連接,在指定的Signal發生時呼叫自訂的callback函式,自訂的callback函式原型基本上是以下的形式:
void func_name(GtkWidget *widget, ..., gpointer user_data);

第一個參數是發出信號的Widget指標,第二個參數是呼叫callback函式時,所要傳遞給callback函式的相關資料,舉個實際的例子,下面這個範例會有一個按鈕,當按下按鈕時,會在主控台下顯示指定的訊息:
  • callback_demo.c
#include <gtk/gtk.h>

// 自訂Callback函式
void button_clicked(GtkWidget *button, gpointer data) {
g_print("按鈕按下:%s/n", (char *) data);
}

int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *button;

gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "哈囉!GTK+!");

button = gtk_button_new_with_label("按我");
gtk_container_add(GTK_CONTAINER(window), button);

g_signal_connect(GTK_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(GTK_OBJECT(button), "clicked",
G_CALLBACK(button_clicked), "哈囉!按鈕!");

gtk_widget_show(window);
gtk_widget_show(button);

gtk_main();

return 0;
}

這個範例是以
使用 Signal 關閉視窗為基礎,增加了一個按鈕,程式中注意的是Callback函式的定義,而要產生一個具有文字的按鈕,可以使用gtk_button_new_with_label()函式,由於GtkWindow是GtkContainer的子類,所以它可以容納其它的Widget元件,在這邊使用gtk_container_add()函式將GtkButton加入GtkWindow之中,目前沒有設置任何版面配置,所以按鈕就填滿整個視窗。

要連接自訂的Callback函式,一樣使用g_signal_connect(),注意到雖然G_CALLBACK巨集會將函式指標轉換為無參數無傳回值的型態,但這不代表Callback函式不可以傳回值或帶有參數,實際操作時是依當時所連接的函式型態而定,在這邊,g_signal_connect()最後一個參數將傳遞給button_clicked()函式的data參數。

要顯示加入的GtkButton,在這邊再次使用gtk_widget_show(),您也可以直接使用gtk_widget_show_all(),將所有在指定的GtkContainer中的元件都顯示出來:
gtk_widget_show_all(window);

一個執行時的畫面如下所示:


另一個較少使用的Signal連結函式是g_signal_connect_swapped(),它實際上也是個巨集,方便使用g_signal_connect_data()函式,定義如下:
#define g_signal_connect_swapped(instance, detailed_signal, c_handler, data) /
    g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, G_CONNECT_SWAPPED)

它所對應的Callback函式應如下定義:
void func_name(gpointer user_data, ..., GtkWidget *widget);

簡單的說,就是兩個參數對調,g_signal_connect_swapped()常用來接結僅接受一個單獨Widget作為參數的callback函式,舉個例子來說,像 gtk_widget_destroy() 函式:

void gtk_widget_destroy(GtkWidget *widget);

這個函式會消除指定的Widget,若您在程式中,想要指定消除一個Widget,則可以使用這個函式,舉例來說,若要按下按鈕後,消除GtkWindow,則可以如下:
  • callback_demo.c
#include <gtk/gtk.h>

int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *button;

gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "哈囉!GTK+!");

button = gtk_button_new_with_label("按我");
gtk_container_add(GTK_CONTAINER(window), button);

g_signal_connect(GTK_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect_swapped(GTK_OBJECT(button), "clicked",
G_CALLBACK(gtk_widget_destroy), window);

gtk_widget_show_all(window);

gtk_main();

return 0;
}

這個程式在按下按鈕後,會消去window所儲存的GtkWindow,由於這是唯一個GtkWindow,消除後程式也就跟著結束。您也可以如前一個範例,在自訂的button_clicked()函式中呼叫gtk_widget_destroy():
  • callback_demo.c
#include <gtk/gtk.h>

// 自訂Callback函式
void button_clicked(GtkWidget *button, gpointer data) {
gtk_widget_destroy((GtkWidget*) data);
}

int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *button;

gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "哈囉!GTK+!");

button = gtk_button_new_with_label("按我");
gtk_container_add(GTK_CONTAINER(window), button);

g_signal_connect(GTK_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(GTK_OBJECT(button), "clicked",
G_CALLBACK(button_clicked), NULL);

gtk_widget_show_all(window);

gtk_main();

return 0;
}

雖然程式的執行也可以透過按下按鈕消除GtkWindow,但直接使用g_signal_connect_swapped()會是比較直接的方式。

另也還有個g_signal_connect_after()函式值得注意,它實際也是巨集,定義如下:
#define g_signal_connect_after(instance, detailed_signal, c_handler, data) /
    g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, G_CONNECT_AFTER)

若您使用g_signal_connect_after()來連接callback函式,則該callback函式,會在所有使用g_signal_connect()設定的callback函式執行之後再執行。


 

 

BloggerAds 廣告正版 iPhone MSN
終於來了 官方版功能超完整,使用超安全,免費申裝!更多訊息..ASUS U系列
移動輕哲學 極薄1.9cm羽量 1.66kg,任Intel Core i5智慧處理器飆行。10hr超強電池續航力,讓你在城市從容遊走。更多訊息..

原创粉丝点击