繁体   English   中英

gtk_widget_add_tick_callback()和gtk_main_iteration()

[英]gtk_widget_add_tick_callback() and gtk_main_iteration()

我有两个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); } } 

问题:主窗口中的动画工作正常,直到调用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(); - 锁定活动窗口以外的任何窗口上的任何更新。

它似乎是定义: 链接

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的值:如果您希望GTK +在没有待处理的事件时阻止,则为TRUE

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

gint gtk_dialog_run (GtkDialog *dialog); 在递归主循环中阻塞 ,直到对话框发出“响应”信号,或被销毁。[...]

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

我假设show_modal是从主要上下文中的回调或其他活动调用的。 您可以尝试使用invokesignal_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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM