gtk_widget_add_tick_callback() and gtk_main_iteration()

gtk_widget_add_tick_callback() and gtk_main_iteration()

本文关键字:gtk main iteration and callback widget add tick      更新时间:2023-10-16

我有两个GTK Windows

  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);
       }
    }
    

问题:主窗口中的动画正常工作,直到调用show_modal()为止。它看起来是gtk_main_iteration();函数添加的 CC_3块。一旦我关闭了次要窗口,然后while() {gtk_main_iteration();}循环退出,然后在主窗口中的动画再次开始运行。

如何在GTK中制作"动画友好"模态循环的任何想法?

更新:它显示为gtk_main_iteration();块,不仅是tick脚的,而且还显示了"当前"以外的任何窗口的任何更新 - 它们只是被冷冻的。这种GTK行为的推理是什么?

更新#2:

gtk_dialog_run();的行为完全像gtk_main_iteration();-锁定了Active窗口以外的其他窗口上的任何更新。

它似乎是定义:链接

gboolean gtk_main_iteration (void); 运行Mainloop的单个迭代。如果没有等待处理的事件,则GTK 将阻止,直到注意到下一个事件。如果您不想阻止查看gtk_main_iteration_do()或检查是否首先使用gtk_events_pending()进行任何事件。

如果您不想要阻止,则说明建议使用gtk_main_iteration_do(FALSE)

gboolean gtk_main_iteration_do (gboolean blocking); 运行Mainloop的单个迭代。如果没有可用的事件,则根据blocking的值返回或块: TRUE如果您希望GTK 阻止如果没有事件进行

对于gtk_dialog_run:它也通过Design link link

阻止

gint gtk_dialog_run (GtkDialog *dialog); 在递归主循环中,直到对话框发出"响应"信号或被破坏为止。[...]

我阅读了有关人们使用多个线程解决此问题的信息:在主线程中处理GUI,并在另一个线程中进行背景工作。这里有一篇文章可能有用。

我假设在主要上下文中从回调或其他活动中调用show_modal。您可以尝试使用Invoke或Signal_idle将模态窗口添加到主上下文中。

以这种方式执行show_modal将结束。

#include <gtkmm.h>
#include <string>
int main()
{
    auto Application = Gtk::Application::create();
    Gtk::Window window;
    Gtk::Window* window2;
    Gtk::Button button;
    window.add(button);
    //I hope timeout behaves similar to ticks. I have no idea how animations in GTK work
    int i=0;
    Glib::MainContext::get_default()->signal_timeout().connect([&]()->bool{
            button.set_label(std::to_string(i++));
            return true;
        }, 1000);
    button.signal_clicked().connect([&]{
            Glib::MainContext::get_default()->invoke([&]()->bool{
                    window2 = new Gtk::Window;
                    window2->set_modal(true);
                    window2->set_keep_above(true);
                    window2->signal_delete_event().connect([&](GdkEventAny* any_event)->bool{
                            delete window2;
                            return false;
                        });
                    window2->show_all();
                    return false;
                });
        });
    window.show_all();
    return Application->run(window);
}