(这是关于 GTK 4 中自定义部件的系列文章的第四部分。 第一部分, 第二部分, 第三部分)。
事件处理程序接管
在前几部分中,我们看到了一些处理 GtkWidget 信号被一些辅助对象替换的示例。在输入区域,这种趋势更加明显,我们传统上需要处理许多信号: ::button-press-event、::key-press-event、 ::touch-event 等。所有这些信号在 GTK 4 中都已消失,取而代之的是,您需要将事件控制器添加到您的部件,并监听它们的信号。例如,有 GtkGestureClick、GtkEventControllerKey、GtkGestureLongPress 以及更多。
事件控制器可以在 ui 文件中创建,但更常见的是在 init() 函数中创建
static void click_cb (GtkGestureClick *gesture, int n_press, double x, double y) { GtkEventController *controller = GTK_EVENT_CONTROLLER (gesture); GtkWidget *widget = gtk_event_controller_get_widget (controller); if (x < gtk_widget_get_width (widget) / 2.0 && y < gtk_widget_get_height (widget) / 2.0) g_print ("Red!\n"); } ... controller = gtk_gesture_click_new (); g_signal_handler_connect (controller, "pressed", G_CALLBACK (click_cb), NULL); gtk_widget_add_controller (widget, controller);
gtk_widget_add_controller() 接管控制器的所有权,并且 GTK 在部件最终确定时会自动清理控制器,因此无需执行其他操作。
复杂的事件处理程序
前几节中的事件处理程序示例很简单,一次只处理单个事件。手势则涉及更多,因为它们处理一系列相关事件,并且通常保持状态。
更复杂的事件处理程序的示例包括 DND 和键盘快捷键。我们可能会在以后的文章中介绍其中一些。
深入了解
所有不同事件处理程序背后的统一原则是,GTK 将从窗口系统接收的事件从部件树的根传播到目标部件,然后再返回,这种模式通常称为捕获-冒泡。
对于键盘事件,目标部件是当前焦点。对于指针事件,它是指针下悬停的部件。
要了解有关 GTK 中输入处理的更多信息,请访问 GTK 文档中的输入处理概述。
展望
我们已经到达本系列准备材料的结尾。如果有人感兴趣,它可能会在未来某个时候继续。可能的主题包括:快捷键、操作和激活、拖放、焦点处理或辅助功能。