2009-05-01 16 views
5

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

Quindi ho ricevuto una richiamata dopo che l'utente ha fatto clic sul pulsante "Scarica immagini" e chiamo il metodo per scaricare le immagini all'interno della stessa classe.

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

Questo non funziona. L'unico modo ho il mio programma per entrare nella discussione è quello di utilizzare

gtk.threads_init ()

Prima di iniziare qualsiasi discussione. Ora che scarica le immagini, ma l'interfaccia grafica rimane insensibile. googled questo ed ho provato a mettere gtk.threads_enter e gtk.threads_leave intorno i fili, ma semplicemente non funziona.

risposta

12

La tua domanda è un po 'vaga, e senza un riferimento al tuo codice attuale è difficile speculare su cosa stai facendo male.

Quindi ti darò alcuni suggerimenti da leggere, quindi speculerò selvaggiamente sulla base dell'esperienza.

Prima di tutto, sembra che tu possa solo mantenere la GUI reattiva usando i thread. Questo non è vero. Puoi anche scrivere il tuo codice in modo asincrono e fare tutto in un'applicazione a thread singolo. Twisted è costruito su questo modello di programmazione. Ho recentemente made a blog post che spiega come ho creato un'interfaccia task asincrona e runner di esempio 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 ancora aggiornata.

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

Si dovrebbe iniziare leggendo The PyGTK FAQ entry on the subject, e si potrebbe trovare this blog post facile da capire anche.

Ora, alla speculazione. Suppongo che tu stia cercando di aggiornare la tua interfaccia utente GTK dal thread e di non gestire correttamente il blocco. Se questo è il caso, è meglio per ora rimandare tutti gli aggiornamenti dell'interfaccia utente che si desidera fare 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ù semplice da seguire nella tua programmazione.

volta che si sente capito davvero il threading e modelli di blocco, si potrebbe prendere in considerazione l'aggiornamento dell'interfaccia utente dal tuo thread, ma è facile perdere un threads_enter()/threads_leave()

+0

+1: non utilizzare thread, basta utilizzare I/O asincrono. – nosklo

1

È possibile utilizzare 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(), ma il problema è che non funziona bene su Windows. L'ho provato su Linux e si comporta abbastanza bene, ma non ho avuto fortuna a farlo funzionare su win32.

=== === Modifica

Sono stato navigando su questo, si potrebbe fare uso della gobject.io_add_watch per controllare se c'è qualcosa nella vostra presa, afferrarlo e quindi aggiornare la GUI.controlla il mio post su questo: Sockets (and some other files) and PyGTK without threads.