如何在GTK3+中从非主线程向主线程发布自定义事件



我是GTK开发的新手,不太清楚GTK是否支持自定义/用户定义的事件。我正在构建一个应用程序,其中需要从内存中读取GUI布局(即GtkWidgets的大小和位置(,并使用这些数据创建和显示UI以供用户交互。

GTK-Main事件循环在Main线程上运行,而另一个(非Main(线程处理GUI布局并更新内存。目标是在内存准备好读取时,将触发器从非主线程发送到主线程。实现这一点的一种方法是让主线程在一个无限while循环中等待,直到内存在某个共享标志的帮助下准备就绪。但是,由于一些特定于应用程序体系结构的限制,我们希望主线程尽早进入GTK事件循环。

因此,我尝试定义并使用自定义GdkEvent(CREATE_WINDOW(。在主线程中,我创建了一个GTK_EVENT_BOX(因为在读取内存之前,我们不希望创建任何可见的窗口(,并在它进入GTK事件循环(GTK_main(((之前为它附加了一个回调函数。其目的是从非主线程发布一个自定义事件,该事件最终会导致调用回调函数。回调函数依次读取内存并创建实际的GUI。

主线程实现如下-

eventbox = gtk_event_box_new ();
gtk_event_box_set_above_child (GTK_EVENT_BOX (eventbox), true);
g_signal_connect (G_OBJECT (eventbox), "event", G_CALLBACK (InternalWindowLifecycleHandler), nullptr);
gtk_widget_set_realized (eventbox, true);
gtk_widget_show_all (eventbox);
gtk_main ();

非主线程代码非常简单(跳过了内存准备代码(-

GdkEvent *  createwinevent;
createwinevent = gdk_event_new ((GdkEventType) custEvent::CREATE_WINDOW);
gdk_event_put (createwinevent);

注意-custEvent是我定义的枚举。

与我们的预期相反,发布此自定义事件不会触发回调函数InternalWindowLifecycleHandler

我想知道,有没有自定义/用户定义的事件,有没有可能在GTK中实现我的目标?

问题的解决方案是在主线程中使用g_idle_add((/g_idle_add_full((,而不是使用GtkEventBox和回调函数。

我的问题是,一旦主线程进入GTK的事件循环,其他线程发布的自定义事件就没有得到处理,因为它没有发出GTK调用回调函数所需的信号。但是,传递给g_idle_add((/g_idle_add_full((的任何函数都会被GTK调用,即使在进入主事件循环之后,如果没有高优先级事件挂起操作。

因此,修改后的主线程代码变得简单多了——

g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, InternalWindowLifecycleHandler, data, nullptr);
gtk_main ();

非主线程发布的事件可以很容易地在InternalWindowLifecycleHandler函数-中捕获和处理

gboolean
InternalWindowLifecycleHandler (gpointer data)
{
GdkEvent *      gevent;
gevent = gdk_event_peek ();
if (gevent) {
switch ((int) gevent->type)
{
...
...
}
}
return true;
}

相关内容

  • 没有找到相关文章

最新更新