15、GTK+ 信号与事件全解析

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

GTK+ 信号与事件全解析

1. GTK+ 信号基础

GTK+ 是一个依赖信号和回调函数的系统。信号是向应用程序发出的通知,表示用户执行了某个操作。当信号发出时,可以让 GTK+ 运行一个名为回调函数的函数。

要连接信号,可以使用 g_signal_connect() 函数,它接受四个参数:

gulong g_signal_connect (gpointer object,
                         const gchar *signal_name,
                         GCallback handler,
                         gpointer data);
  • object :要监视信号的 GObject。
  • signal_name :表示信号的字符串。
  • handler :信号发出时将调用的回调函数的名称。
  • data :允许将任意指针类型的数据发送到回调函数。

此外,还可以使用 g_signal_connect_swapped() ,它的工作方式与 g_signal_connect() 相同,只是对象和数据参数的顺序交换了。

2. 事件类型

事件是由 X 窗口系统发出的一种特殊信号。发出后,它们从窗口管理器发送到应用程序,由 GLib 提供的信号系统进行解释。事件回调函数返回一个 gboolean 值,如果返回 TRUE ,则不会发生进一步的操作;如果返回默认值 FALSE ,GTK+ 将继续处理该事件。

以下是一些常见的 GtkWidget 事件类型:
| 信号名称 | GdkEventType 值 | 描述 |
| — | — | — |
| delete-event | GDK_DELETE | 窗口管理器请求销毁顶级窗口,可用于确认窗口删除。 |
| destroy-event | GDK_DESTROY | 小部件的 GdkWindow 被销毁,通常不建议使用此信号。 |
| expose-event | GDK_EXPOSE | 小部件的新部分显示出来,需要进行绘制。 |
| motion-notify-event | GDK_MOTION_NOTIFY | 鼠标光标在小部件附近移动。 |
| button-press-event | GDK_BUTTON_PRESS | 鼠标按钮被单击一次。 |
| button-press-event | GDK_2BUTTON_PRESS | 鼠标按钮被双击。 |
| button-press-event | GDK_3BUTTON_PRESS | 鼠标按钮被三击。 |
| button-release-event | GDK_BUTTON_RELEASE | 之前单击的鼠标按钮被释放。 |
| key-press-event | GDK_KEY_PRESS | 键盘按键被按下,返回 TRUE 可阻止文本输入或操作。 |
| key-release-event | GDK_KEY_RELEASE | 之前按下的键盘按键被释放。 |
| enter-notify-event | GDK_ENTER_NOTIFY | 鼠标光标进入小部件附近。 |
| leave-notify-event | GDK_LEAVE_NOTIFY | 鼠标光标离开小部件附近。 |
| focus-in-event | GDK_FOCUS_CHANGE | 键盘焦点从窗口内的另一个小部件进入该小部件。 |
| focus-out-event | GDK_FOCUS_CHANGE | 键盘焦点从该小部件离开到窗口内的另一个小部件。 |
| configure-event | GDK_CONFIGURE | 小部件的大小、位置或堆叠顺序发生变化。 |
| map-event | GDK_MAP | 小部件被映射到显示器上。 |
| unmap-event | GDK_UNMAP | 小部件从显示器上取消映射。 |
| property-notify-event | GDK_PROPERTY_NOTIFY | 小部件的属性被更改或删除。 |
| selection-clear-event | GDK_SELECTION_CLEAR | 应用程序不再拥有选择项的所有权,需要清除。 |
| selection-request-event | GDK_SELECTION_REQUEST | 小部件的选择项被另一个应用程序请求。 |
| selection-notify-event | GDK_SELECTION_NOTIFY | 选择项的所有者响应选择项转换请求。 |
| proximity-in-event | GDK_PROXIMITY_IN | 输入设备与感应表面接触。 |
| proximity-out-event | GDK_PROXIMITY_OUT | 输入设备与感应表面断开接触。 |
| event | GDK_DRAG_ENTER | 拖动操作进行时,鼠标指针进入小部件。 |
| event | GDK_DRAG_LEAVE | 拖动操作进行时,鼠标指针离开小部件。 |
| event | GDK_DRAG_MOTION | 拖动操作进行时,鼠标指针在小部件内移动。 |
| event | GDK_DRAG_STATUS | 拖动操作的当前状态发生变化。 |
| event | GDK_DROP_START | 小部件上的放置操作开始。 |
| event | GDK_DROP_FINISHED | 小部件上的放置操作完成。 |
| client-event | GDK_CLIENT_EVENT | 小部件从另一个应用程序接收到事件。 |
| visibility-notify-event | GDK_VISIBILITY_NOTIFY | 小部件的可见性发生变化。 |
| no-expose-event | GDK_NO_EXPOSE | 复制可绘制区域的部分时,源区域完全可用。 |
| scroll-event | GDK_SCROLL | 小部件在某个方向上滚动。 |
| window-state-event | GDK_WINDOW_STATE | 小部件的状态发生变化。 |
| event | GDK_SETTING | 小部件的设置被添加、删除或修改。 |

3. 小部件信号

不同的 GTK+ 小部件有各自的信号,以下是一些常见小部件信号的示例:

3.1 GtkAction 信号
信号名称 描述
activate 关联的菜单或工具栏项被触发。
3.2 GtkActionGroup 信号
信号名称 附加参数 描述
connect-proxy GtkAction action, GtkWidget proxy 用于同步 GtkAction 对象和关联小部件属性的代理被添加。
disconnect-proxy GtkAction action, GtkWidget proxy 用于同步 GtkAction 和关联小部件属性的代理被移除。
post-activate GtkAction *action 操作组中包含的操作在信号发出后被激活。
pre-activate GtkAction *action 操作组中包含的操作在该信号发出后即将被激活。
3.3 GtkAdjustment 信号
信号名称 描述
changed 调整的一个或多个属性(不包括值属性)发生变化。
value-changed 调整的值属性发生变化。
4. 信号连接流程

以下是连接信号的基本流程:

graph TD;
    A[定义回调函数] --> B[选择要监视的对象];
    B --> C[确定信号名称];
    C --> D[使用 g_signal_connect() 或 g_signal_connect_swapped() 连接信号];
    D --> E[信号发出时调用回调函数];

通过以上内容,我们对 GTK+ 的信号和事件有了更深入的了解。在实际开发中,可以根据需求选择合适的信号和回调函数,实现丰富的交互功能。

GTK+ 信号与事件全解析

5. 更多小部件信号解析
5.1 GtkButton 信号
信号名称 描述
activate 用于为按钮设置动画,不建议连接此信号,应使用 clicked 信号。
clicked 按钮被点击或释放。
5.2 GtkCalendar 信号
信号名称 描述
day-selected 用户在日历上选择了一天。
day-selected-double-click 用户通过双击选择了一天,可用于强制更新补充小部件。
month-changed 用户使用箭头按钮选择了新的月份。
next-month 显示的月份递增,仅在用户手动更改月份时调用。
next-year 显示的年份递增,仅在用户手动更改年份时调用。
prev-month 显示的月份递减,仅在用户手动更改月份时调用。
prev-year 显示的年份递减,仅在用户手动更改年份时调用。
5.3 GtkCellEditable 信号
信号名称 描述
editing-done 用户完成单元格文本内容的编辑,通知单元格渲染器更新其值。
remove-widget 单元格编辑完成,可销毁文本编辑小部件。
6. 信号处理示例

GtkButton clicked 信号为例,以下是一个简单的代码示例展示如何连接信号并处理:

#include <gtk/gtk.h>

// 回调函数
static void button_clicked(GtkWidget *widget, gpointer data) {
    g_print("按钮被点击了!\n");
}

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

    // 初始化 GTK+
    gtk_init(&argc, &argv);

    // 创建窗口
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    // 创建按钮
    button = gtk_button_new_with_label("点击我");
    g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), NULL);

    // 将按钮添加到窗口
    gtk_container_add(GTK_CONTAINER(window), button);

    // 显示所有小部件
    gtk_widget_show_all(window);

    // 进入主循环
    gtk_main();

    return 0;
}

上述代码的执行流程如下:

graph TD;
    A[初始化 GTK+] --> B[创建窗口];
    B --> C[创建按钮];
    C --> D[连接按钮的 clicked 信号到回调函数];
    D --> E[将按钮添加到窗口];
    E --> F[显示所有小部件];
    F --> G[进入主循环等待事件];
    H[按钮被点击] --> I[调用回调函数];
7. 信号处理的注意事项

在处理 GTK+ 信号时,有以下几点需要注意:
- 回调函数原型 :不同的信号可能有不同的回调函数原型,需要根据 GTK+ API 文档来确定。很多函数原型的文档可能不完整,可在信号参考表中查找非标准参数的更多信息。
- 事件回调返回值 :事件回调函数返回一个 gboolean 值,返回 TRUE 表示不再进行进一步操作,返回 FALSE 则 GTK+ 会继续处理该事件。
- 信号连接顺序 :信号连接的顺序可能会影响回调函数的执行顺序,需要根据实际需求进行合理安排。

8. 总结

GTK+ 的信号和事件机制为开发者提供了强大的交互能力。通过连接不同的信号和编写合适的回调函数,可以实现各种复杂的用户交互功能。在实际开发中,需要熟悉不同小部件的信号,根据需求选择合适的信号进行处理,并注意信号处理过程中的一些细节,以确保程序的稳定性和可靠性。以下是对常见小部件信号的总结表格:
| 小部件 | 常用信号 | 用途 |
| — | — | — |
| GtkButton | clicked | 处理按钮点击事件 |
| GtkCalendar | day-selected | 处理日历日期选择事件 |
| GtkCellEditable | editing-done | 处理单元格编辑完成事件 |

通过对这些信号和事件的灵活运用,能够开发出更加丰富、交互性强的 GTK+ 应用程序。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值