gtk_widget_add_tick_callback()和gtk_main_iteration()

c-s*_*ile 15 c++ gtk gtk3 gtkmm3

我有两个GTK窗口

  1. 正常(主)窗口运行动画,在注册的回调中绘制内容gtk_widget_add_tick_callback().

  2. 在某些时候,创建了运行模态循环的辅助窗口:

    void show_modal() 
    {
       GtkWindow* gw = gtkwindow(this);
    
       if( parent() )
         gtk_window_set_transient_for(gw, gtkwindow( parent() ));
    
    
       gtk_widget_show(GTK_WIDGET(gw));
       gtk_window_set_modal(gw,TRUE);
       gtk_window_set_keep_above(gw,TRUE);
       this->update_window_state(gool::WINDOW_SHOWN);
    
       while( this->is_valid_window() )
       {
          if(this->_window_state == WINDOW_HIDDEN) break;
          if(this->_window_state == WINDOW_STATE_NA) break;
          gtk_main_iteration(); // gtk_main_iteration_do(true);
       }
    }
    
    Run Code Online (Sandbox Code Playgroud)

问题:主窗口中的动画工作正常,直到show_modal()被调用.它显示为gtk_main_iteration();gtk_widget_add_tick_callback()功能添加的块标记.一旦我关闭辅助窗口,所以while() {gtk_main_iteration();}循环退出然后主窗口中的动画再次开始运行.

想知道如何在GTK中制作"动画友好"的模态循环吗?

更新:gtk_main_iteration();除了"当前"之外,它看起来像块不仅是滴答而是任何窗口的任何更新 - 它们只是被冻结.这种GTK行为的原因是什么?

更新#2:

gtk_dialog_run();表现完全一样gtk_main_iteration();- 锁定活动窗口以外的任何窗口上的任何更新.

JHB*_*ius 1

这似乎是根据定义:链接

\n\n
\n

gboolean gtk_main_iteration (void);\n 运行主循环的单次迭代。如果没有事件等待处理,GTK+将阻塞,直到注意到下一个事件。如果您不想阻止\xe2\x80\x99,请首先查看gtk_main_iteration_do()或检查是否有任何事件正在等待处理gtk_events_pending()

\n
\n\n

解释建议gtk_main_iteration_do(FALSE)如果您不想阻止则使用:

\n\n
\n

gboolean gtk_main_iteration_do (gboolean blocking);\n 运行主循环的单次迭代。如果没有可用的事件,则返回或阻止,具体取决于blocking:\n TRUE如果您希望 GTK+ 在没有待处理的事件时阻止

\n
\n\n

至于gtk_dialog_run:它也通过设计 链接阻止

\n\n
\n

gint gtk_dialog_run (GtkDialog *dialog);\n 阻塞在递归主循环中,直到对话框发出 \xe2\x80\x9cresponse\xe2\x80\x9d 信号或被销毁。[...]

\n
\n\n

我读到人们使用多线程解决这个问题:在主线程中处理 GUI,并在另一个线程中进行后台工作。这里有一篇关于它的文章可能有用。

\n

  • 这就是所有 UI 平台上模态循环的本质 - 通过显示带有问题的窗口并运行“消息泵”循环直到其关闭来阻止当前执行。就像这里:https://www.codeproject.com/Articles/348/Implementing-Modal-Message-Loops 在 Windows 和 Mac 上工作得很好。只是在 GTK 上 `gtk_main_iteration_do(/*没关系*/)` 不会将消息分派到除活动窗口之外的任何其他窗口。由于未知的原因。 (2认同)