Код не может выйти из приложения GTK-очевидно, нет циклов сообщений


Я пытаюсь понять, как заставить приложение 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);
}

И, для полноты, вот main, который присоединяет обработчик сигнала и запускает приложение GTK:

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 (я не думаю, что это имеет место и здесь).

Я, очевидно, делая что-то неправильно, почему мое приложение не имеет запущенного цикла сообщений?

1 7
gtk

1 ответ:

Функция gtk_main_quit, по-видимому, не подходит при использовании GtkApplication. От кого-то, кто участвовал в разработке различных проектов Gnome, один Эммануэль Басси (а) прокомментировал в другом месте (слегка перефразировав и отметив, в частности, второй абзац):

Если вы вызываете g_application_run() , то вам не нужно также вызывать gtk_main(): Метод run() будет вращать основной цикл для вас.

вы также не используете gtk_main_quit(), чтобы остановите основной цикл приложения: вместо него следует использовать g_application_quit().


Имея это в виду, вам нужно передать приложение в callback и вызвать функцию выхода приложения с ним:

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

(а) у кого, на мой взгляд, есть способ слишком самодовольно выглядеть на фото : -)