GTK Gossip: GTK 事件處理函式

本文介绍如何在GTK+中处理事件信号,通过示例代码展示了如何使用g_signal_connect()连接事件信号与回调函数,并解释了回调函数如何控制事件传播。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

為 了連結一個事件Signal與Callback函式,一樣是使用g_signal_connect()函式,不過處理事件Signal的Callback 函式與純綷的GTK Signal的Callback函式在宣告時有些不同,以下是處理事件Signal的Callback函式宣告方式:

gboolean callback_func(
          GtkWidget *widget, GdkEvent *event, gpointer callback_data);


Callback函式多了一個GdkEvent*參數,而傳回值的部份,
可以控制事件是否進行下一步傳播, 傳回TRUE表示這個事件到止已獲得處理,事件不用繼續傳播,傳回FALSE表示事件繼續傳播。

事件Signal的處理函式會在GTK Signal的處理函式之前先處理,以按下按鈕為例,基本上的順序為:

按鈕按下 --> 發出 GDK_BUTTON_PRESS --> GDK 預設處理函式
                 --> 發出 button_press_event Signal --> GTK 預設處理函式
         --> 發出 clicked Signal --> GTK 預設處理函式


您可以設置事件Signal的Callback函式,攔截button_press_event,當處理完傳回TRUE時,就 不會繼續預設的GTK處理函式,也就不會發出clicked的Signal,只有在傳回FALSE時,才會發出clicked的Signal,則設置的 GTK Signal處理函式才會被執行。

以下這個例子為例:

  • event_demo.c

 

#include <gtk/gtk.h>

// Signal處理函式
void button_clicked_callback(GtkWidget *button, gpointer data) {
g_print("clicked處理函式/n");
}

// 事件處理函式
gboolean button_press_callback(
GtkWidget *button, GdkEvent *event, gpointer data) {
GdkEventType type = event->type;

if(type == GDK_BUTTON_PRESS) {
g_print("button_press_event處理函式(%d, %d)/n",
(gint) event->button.x, (gint) event->button.y);
}

return FALSE;
}

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(button), "event",
G_CALLBACK(button_press_callback), NULL);
g_signal_connect(GTK_OBJECT(button), "clicked",
G_CALLBACK(button_clicked_callback), NULL);
g_signal_connect(GTK_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);

gtk_widget_show(window);
gtk_widget_show(button);

gtk_main();

return 0;
}


在上面的程式中,以button_clicked_callback()函式來處理事件,因為 g_signal_connect()中設定為"event",表示所有事件都會經過button_press_callback處理,所以函式中使用 if判斷GdkEventType,只有當滑鼠按下時,顯示滑鼠的位置,最後傳回FALSE,執行結果如下所示:

button_press_event處理函式(58, 44)
clicked處理函式
button_press_event處理函式(134, 108)
clicked處理函式
button_press_event處理函式(66, 149)
clicked處理函式
button_press_event處理函式(146, 44)
clicked處理函式


如果 button_clicked_callback()函式傳回TRUE,則button_clicked_callback()函式將不執行,"clicked處理函式"文字將不會顯示。

如果您已知要處理特定的事件類型,則您可以在Callback函式上宣告特定的事件類型,並在g_signal_connect()時指定特定的事件Signal,例如上面的範例也可以修改為以下,而執行結果相同:

  • event_demo.c

 

#include <gtk/gtk.h>

// 自訂Callback函式
void button_clicked_callback(GtkWidget *button, gpointer data) {
g_print("clicked處理函式/n");
}

gboolean button_press_callback(
GtkWidget *button, GdkEventButton *event, gpointer data) {
g_print("button_press_event處理函式(%d, %d)/n",
(gint) event->x, (gint) event->y);

return FALSE;
}

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(button), "button_press_event",
G_CALLBACK(button_press_callback), NULL);
g_signal_connect(GTK_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(GTK_OBJECT(button), "clicked",
G_CALLBACK(button_clicked_callback), NULL);

gtk_widget_show(window);
gtk_widget_show(button);

gtk_main();

return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值