【问题标题】:Code cannot exit from GTK application - apparently no message loops代码无法从 GTK 应用程序中退出 - 显然没有消息循环
【发布时间】:2016-04-28 04:13:57
【问题描述】:

我正在尝试弄清楚如何让 GTK 应用程序在之后自动退出 一定的时间。

所以我有一个用于关闭应用程序的回调函数:

static gboolean killOffApp (gpointer userData) {
    gtk_main_quit ();
    return FALSE;
}

然后,在activate 信号处理程序中,我启动五秒计时器:

static void activate (GtkApplication* app, gpointer user_data) {
    GtkWidget *window = gtk_application_window_new (app);
    g_timeout_add_seconds (5, killOffApp, NULL);
    gtk_widget_show_all (window);
}

并且,为了完整起见,这里是附加信号处理程序并运行 GTK 应用程序的 main

int main (int argc, char **argv) {
    GtkApplication *app = gtk_application_new ("com.example", G_APPLICATION_FLAGS_NONE);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    int status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);
    return status;
}

我的问题是,当计时器触发时,对gtk_main_quit 的调用似乎无效,我不知道为什么:

(MyProg:776): Gtk-CRITICAL **: gtk_main_quit: assertion 'main_loops != NULL' failed

我在网上研究过这个问题,但只发现了以下任何一个问题:

  • 它是从运行内部循环的部分代码完成的(例如在对话框中),因此它会关闭该内部循环而不是主循环(我相信这里不是这种情况);或
  • 没有循环运行,例如,应用程序是使用一次性 gtk_main_iteration_do 运行的(我认为这里也不是这种情况)。

我显然做错了某事,为什么我的应用程序似乎没有运行消息循环?

【问题讨论】:

    标签: c gtk


    【解决方案1】:

    gtk_main_quit 函数在使用 GtkApplication 时似乎不合适。一位参与过各种 Gnome 项目开发的人,其中一位 Emmanuele Bassi 评论了 elsewhere(稍作解释,特别注意第二段):

    如果您正在调用g_application_run(),那么您也不需要调用gtk_main()run() 方法将为您旋转主循环。

    您也不要使用gtk_main_quit() 来停止应用程序的主循环:您应该改用g_application_quit()


    考虑到这一点,您需要将应用程序传递给回调,并使用它调用应用程序退出函数:

    static void activate (GtkApplication* app, gpointer user_data) {
        GtkWidget *window = gtk_application_window_new (app);
        g_timeout_add_seconds (forceShutdown, killOffApp, app); // << here
        gtk_widget_show_all (window);
    }
    
    static gboolean killOffApp (gpointer userData) {
        g_application_quit (userData); // << and here
        return FALSE;
    }
    

    【讨论】:

    • 如果您在原始代码中调用 g_application_quit() 而不是 gtk_main_quit() 会发生什么?
    • @andlabs,一旦我将应用程序传递给回调,它也可以正常工作。将更新答案。
    • 那可能应该更清楚地记录下来;你可以在官方 GNOME bugzilla 上提出问题,建议文档说如果你使用 GtkApplication,不要调用 gtk_main_quit()...
    • 在 Gtk 3.22.9 中尝试这个 ..,我必须将 gpointer userData 作为第二个参数传递,而不是第一个参数。我没有尝试使用第一个参数,只是假设它是小部件获取销毁信号,因此将 GtkWidget *widget 放在那里。我还必须使用 G_APPLICATION(userData)。
    • 我在尝试 gtk3 -- gotk3 的 go 绑定时发现这很有用。
    猜你喜欢
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    相关资源
    最近更新 更多