<-上一篇(GTK4示例代码解析以及美化方案)

GTK 中,事件处理和绑定主要通过 g_signal_connect() 函数实现。此函数的基本用法如下:

g_signal_connect(instance, detailed_signal, c_handler, data);

通常,我们重点关注前四个参数:instance(触发事件的控件实例),detailed_signal(事件的名称),c_handler(事件发生时调用的回调函数),以及 data(传递给回调函数的自定义数据)。

以下是一些常见控件及其对应的事件名称(仅为示例,并非完整列表):

  • GtkApplication 窗体: "activate" (应用程序激活), "startup" (应用程序启动), "destroy" (应用程序销毁)

  • 按钮 (GtkButton): "clicked" (按钮点击)

  • 文本框 (GtkEntry): "changed" (文本内容改变), "activate" (按下回车键)

  • 窗口 (GtkWindow): "delete-event" (窗口关闭), "destroy" (窗口销毁)

  • 组合框 (GtkComboBox): "changed" (选中项改变)

  • 单选按钮 (GtkRadioButton): "toggled" (状态切换)

  • 复选框 (GtkCheckButton): "toggled" (状态切换)

  • 滑块 (GtkScale): "value-changed" (数值改变)

  • 定时器 (Glib.Source): "timeout" (超时)

  • 绘图区域 (GtkDrawingArea): "draw" (绘制), "button-press-event" (鼠标按下), "motion-notify-event" (鼠标移动)

  • 列表/树 (GtkTreeView): "row-activated" (行激活), "cursor-changed" (光标改变)

  • 菜单项 (GtkMenuItem): "activate" (激活)

  • 对话框 (GtkDialog): "response" (响应,例如点击确认或取消)

  • 文件选择器 (GtkFileChooserDialog): "file-activated" (文件激活,例如双击文件)

其中,c_handler 参数指定的回调函数会在事件发生时被调用。通常使用 G_CALLBACK (函数名) 的形式,结合 data 参数,可以实现更灵活的事件处理逻辑。

例如,假设我们有一个名为 button 的按钮,希望在单击它时输出 "Hello World"。可以这样编写代码:

回调函数:

static void print_hello ()
{
    g_print ("Hello World\n");
}

绑定事件:

g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);

除了g_signal_connect() 函数,想要绑定事件还可以使用g_signal_connect_after()g_signal_connect_swapped()函数。

g_signal_connect_after() 函数在信号发出之后执行回调函数,以下是原文解释:

原文:
g_signal_connect_after: @instance: the instance to connect to. @detailed_signal: a string of the form "signal-name::detail". @c_handler: the #GCallback to connect. @data: data to pass to @c_handler calls.
Connects a #GCallback function to a signal for a particular object.
The handler will be called synchronously, after the default handler of the signal.
This function cannot fail. If the given signal doesn’t exist, a critical warning is emitted.
Returns: the handler ID, of type `gulong` (always greater than 0)

译文:
`g_signal_connect_after`:
- `@instance`:要连接的对象实例。
- `@detailed_signal`:一个形式为 "signal-name::detail" 的字符串。
- `@c_handler`:要连接的 #GCallback 回调函数。
- `@data`:传递给 @c_handler 回调函数的数据。

此函数将一个 #GCallback 函数连接到特定对象的信号上。
处理程序将在信号的默认处理程序之后同步调用。
此函数不会失败。如果给定的信号不存在,则会发出严重警告。
返回值:处理程序的 ID,类型为 `gulong`(始终大于0)

也就是说,回调函数会在默认的处理函数执行完毕后执行。

g_signal_connect_swapped() 可以将实例数据作为用户数据传递给回调函数,以下是原文解释:

原文:
g_signal_connect_swapped: @instance: the instance to connect to. @detailed_signal: a string of the form "signal-name::detail". @c_handler: the #GCallback to connect. @data: data to pass to @c_handler calls.
Connects a #GCallback function to a signal for a particular object.
The instance on which the signal is emitted and @data will be swapped when calling the handler. This is useful when calling pre-existing functions to operate purely on the @data, rather than the @instance: swapping the parameters avoids the need to write a wrapper function.
For example, this allows the shorter code: |[<!-- language="C" --> g_signal_connect_swapped (button, "clicked", (GCallback) gtk_widget_hide, other_widget); ]|
Rather than the cumbersome: |[<!-- language="C" --> static void button_clicked_cb (GtkButton *button, GtkWidget *other_widget) { gtk_widget_hide (other_widget); }
...
g_signal_connect (button, "clicked", (GCallback) button_clicked_cb, other_widget); ]|
This function cannot fail. If the given signal doesn’t exist, a critical warning is emitted.
Returns: the handler ID, of type `gulong` (always greater than 0)

译文:
`g_signal_connect_swapped` 函数说明:

- `@instance`:要连接的对象实例。
- `@detailed_signal`:一个形式为 "signal-name::detail" 的字符串,用于指定要连接的信号。
- `@c_handler`:要连接的 #GCallback 回调函数。
- `@data`:传递给 @c_handler 回调函数的数据。

此函数将一个 #GCallback 函数连接到特定对象的信号上。当调用处理程序时,发出信号的实例和 @data 将被交换。这在调用预先存在的函数以仅对 @data 进行操作时非常有用,而不是对 @instance 进行操作:通过交换参数,可以避免编写包装函数。

例如,这允许使用更简短的代码:

g_signal_connect_swapped(button, "clicked", (GCallback) gtk_widget_hide, other_widget);

而不是繁琐的:

static void button_clicked_cb(GtkButton *button, GtkWidget *other_widget) {
    gtk_widget_hide(other_widget);
}
...
g_signal_connect(button, "clicked", (GCallback) button_clicked_cb, other_widget);

此函数不会失败。如果给定的信号不存在,则会发出严重警告。

返回值:处理程序的 ID,类型为 `gulong`(始终大于0)。

例如,在示例代码中我们就使用到了这个函数:

g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_close), window);

这里调用的回调函数是gtk_window_close ,这个函数为GTK自带的函数,可以直接关闭窗口,无需我们再编写一个函数来处理,非常方便。同时使用g_signal_connect_swappedgtk_window_close 传递window 窗口对象,使其可以正确关闭窗口。

下一篇(在GTK中使用布局)->