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_swapped
向gtk_window_close
传递window 窗口对象,使其可以正确关闭窗口。
评论