GTK信号什么时候发出

问题描述 投票:0回答:1

给定从用户连接到回调函数的信号,gtk_main 线程将休眠,直到发出信号。我搜索了有关如何或何时发出的详细信息,但找不到任何我不知道的信息。

更具体地说,它是异步发出的,以便我可以在某个函数中间调用信号,还是等待特定函数先返回?从 GThread 内发出“切换页面”信号(例如使用

gtk_notebook_remove_page()
)可能会产生奇怪的效果,因为事件发生在主线程中,并且我不能保证
gtk_notebook_remove_page()
在主上下文中执行,就好像
g_main_context_invoke()
一样被使用?但是,如果我在线程内手动发出带有
g_signal_emit()
的信号(如果信号可以通过这种方式发出)会怎样?

c gtk signals
1个回答
3
投票

首先,gtk mainloop 不是线程安全的。从主循环以外的线程调用任何 gtk 函数都是 UB。

详细描述可以在here找到,但简而言之:主循环不会休眠或等待信号。它总是在迭代,如果它看到用户按下了按钮,它就会发出信号。

我个人使用此类函数,即 g_timeout_add'ed:

static gboolean
redrawer (gpointer data)
{
   MyObj *self = data;

   if (g_atomic_int_get (&self->priv->request_redraw)
     gtk_widget_queue_draw (GTK_WIDGET (self));

  return G_SOURCE_CONTINUE;
}

编辑:稍后我发现,

g_idle_add
是线程安全的,因此可以重写该函数,而无需显式检查
request_redraw
标志:

static void
callback_which_initiates_redraw (gpointer data)
{
   MyObj *self = data;
   g_idle_add (gtk_widget_queue_draw, self);
}

更具体地说,它是异步发出的,以便我可以在某个函数中间调用信号,还是等待特定函数先返回?

它等待着。当您处于主循环中时,没有什么是异步的。

从 GThread 内发出“switch-page”信号(例如使用 gtk_notebook_remove_page())可能会产生奇怪的效果,因为事件发生在主线程中,并且我不能保证 gtk_notebook_remove_page() 在主上下文中执行,就像 g_main_context_invoke( )被使用? 但是,如果我在线程内使用 g_signal_emit() 手动发出信号(如果信号可以通过这种方式发出)会怎样?

我不太明白这两个问题,但再说一遍:不从主循环调用 gtk 函数是 UB。

© www.soinside.com 2019 - 2024. All rights reserved.