Domanda

Ho un problema con i thread in pygtk. La mia applicazione consiste in un programma che scarica le immagini da Internet e quindi le visualizza con pygtk. Il problema è che per fare questo e mantenere la GUI reattiva, ho bisogno di usare i thread.

Quindi sono entrato in una richiamata dopo che l'utente ha fatto clic sul pulsante " Scarica immagini " e chiamo il metodo per scaricare le immagini che appartengono alla stessa classe.

thread.start_new_thread (self.images_download, (percorso, pagine)

Questo non funzionerà. L'unico modo per ottenere il mio programma per entrare nel thread è usando

gtk.threads_init ()

Prima di iniziare qualsiasi thread. Ora scarica le immagini ma la GUI non risponde. Ho cercato su Google questo e ho provato a mettere gtk.threads_enter e gtk.threads_leave attorno ai thread ma non funziona.

È stato utile?

Soluzione

La tua domanda è un po 'vaga e senza un riferimento al tuo codice reale è difficile speculare su cosa stai facendo di sbagliato.

Quindi ti darò alcuni consigli da leggere, quindi speculerò selvaggiamente in base all'esperienza.

Prima di tutto, sembra che tu possa mantenere la GUI reattiva solo usando i thread. Questo non è vero. Puoi anche scrivere il codice in modo asincrono e fare tutto in un'applicazione a thread singolo. Twisted è basato su questo modello di programmazione. Di recente ho pubblicato un post sul blog che spiega come ho creato un'interfaccia di attività asincrona e un esempio corridori sia per CLI che GTK +. Puoi guardare quegli esempi per vedere come le attività possono essere implementate in modo asincrono e l'interfaccia utente viene comunque aggiornata.

In secondo luogo, se si preferisce utilizzare i thread per qualche motivo, sarà necessario comprendere un po 'il modello di threading GTK +.

Dovresti iniziare leggendo La voce FAQ PyGTK sull'argomento e potresti trovare questo post sul blog anche facile da capire.

Ora, passiamo alla speculazione. Immagino che tu stia provando ad aggiornare l'interfaccia utente GTK dal thread e non gestisca il blocco correttamente. In questo caso, per ora è meglio rinviare tutti gli aggiornamenti dell'interfaccia utente che si desidera eseguire dai thread al thread principale utilizzando gobject.idle_add () In questo modo, tutte le chiamate dell'interfaccia utente verranno effettuate dal thread principale. È un modello mentale più facile da seguire nella programmazione.

Una volta che hai capito bene i modelli di threading e di blocco, potresti prendere in considerazione l'aggiornamento dell'interfaccia utente dai thread, ma è facile perdere un thread_enter () / thread_leave ()

Altri suggerimenti

Puoi usare gtk.gdk.threads_init () per consentire a qualsiasi thread di modificare l'interfaccia utente con il rispettivo gtk.gdk.threads_enter () e gtk.gdk.theads_leave () lock, ma il problema è che non funziona bene su Windows. L'ho testato su Linux e funziona abbastanza bene, ma non ho avuto fortuna a farlo funzionare su Win32.

=== Modifica ===

Ho cercato su questo, potresti usare gobject.io_add_watch per verificare se c'è qualcosa nel tuo socket, afferrarlo e quindi aggiornare la GUI. controlla il mio post su questo: Socket (e alcuni altri file) e PyGTK senza thread.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top