2016-04-28 9 views
6

Sto cercando di capire come ottenere un'applicazione GTK per uscire automaticamente dopo lo in un determinato momento.Il codice non può uscire dall'applicazione GTK - apparentemente nessun loop di messaggi

quindi ho una funzione di callback che è destinata a spegnere l'applicazione:

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

Poi, nel gestore activate del segnale, comincio il cinque secondi il timer:

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

E, per completezza, ecco il main che allega il gestore di segnale e avvia l'applicazione 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; 
} 
.210

mio problema è che, quando il timer incendi, la chiamata a gtk_main_quit sembra non essere valido e non sono sicuro perché:

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

Ho ricercato il problema sul web, ma trova solo roba in cui o:

  • è fatto da una parte del codice in cui v'è un ciclo interno in esecuzione (ad esempio in una finestra di dialogo) in modo che si spegne che uno piuttosto che il ciclo principale (non è il caso qui, credo) ; oppure
  • non esiste un ciclo in esecuzione poiché, ad esempio, l'applicazione è stata eseguita con lo gtk_main_iteration_do one-shot (non credo che sia il caso anche qui).

Sono ovviamente facendo qualcosa di sbagliato, perché la mia domanda appare non avere un ciclo di messaggi in esecuzione?

risposta

5

La funzione gtk_main_quit non sembra essere adatta quando si utilizza GtkApplication. Da qualcuno che è stato coinvolto nello sviluppo di vari progetti di Gnome, uno Emmanuele Bassi(a) commentato elsewhere (un po 'parafrasata e notando in particolare il secondo comma):

Se chiami g_application_run() allora don Non è necessario chiamare lo gtk_main(): il metodo run() farà girare il loop principale per te.

Inoltre non utilizzare gtk_main_quit() per interrompere il ciclo principale dell'applicazione: è invece necessario utilizzare g_application_quit().


Con questo in mente, è necessario passare l'applicazione alla richiamata, e chiamare l'applicazione funzione con esso 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; 
} 

(a) Chi , a mio parere, ha un modo troppo compiaciuto :-)

+0

Cosa h si verifica se chiami ['g_application_quit()'] (https://developer.gnome.org/gio/unstable/GApplication.html # g-application-quit) invece di 'gtk_main_quit()' nel tuo codice originale? – andlabs

+0

@andlabs, che funziona altrettanto bene, una volta che passo l'applicazione al callback. Aggiornerà la risposta. – paxdiablo

+0

Questo dovrebbe probabilmente essere più chiaramente documentato allora; puoi presentare un problema sul bugzilla ufficiale di GNOME suggerendo che la documentazione dice di non chiamare 'gtk_main_quit()' se usi GtkApplication ... – andlabs

Problemi correlati