2009-05-01 13 views
5

Ich habe ein Problem mit Threads in pygtk. Meine Anwendung besteht aus einem Programm, das Bilder aus dem Internet herunterlädt und dann mit pygtk anzeigt. Das Problem besteht darin, dass ich Threads verwenden muss, um dies zu tun und die GUI ansprechend zu halten.Wie mit Threads in pygtk arbeiten

So bekam ich einen Rückruf, nachdem der Benutzer auf den Button "Bilder herunterladen" geklickt hat und ich die Methode aufrufen, um die Bilder herunterzuladen, die innerhalb der gleichen Klasse sind.

thread.start_new_thread (self.images_download, (Pfad, Seiten)

Das wird nicht funktionieren. Die einzige Art, wie ich mein Programm kommen in den Thread zu bekommen, ist durch die Verwendung

gtk.threads_init ()

Vor Thread zu starten. Jetzt lädt er die Bilder, aber die GUI bleibt nicht mehr reagiert. ich diese gegoogelt und ich versuchte gtk.threads_enter und gtk.threads_leave rund um die Themen setzen, aber es funktioniert einfach nicht.

Antwort

12

Ihre Frage ist ein bisschen vage und ohne einen Hinweis auf Ihren eigentlichen Code ist es schwer zu spekulieren, was Sie falsch machen.

Also werde ich Ihnen ein paar Tipps zum Lesen geben, dann spekulieren wild basierend auf Erfahrung.

Zunächst scheinen Sie zu denken, dass Sie die GUI nur mit Threads reaktionsfähig halten können. Das ist nicht wahr. Sie können Ihren Code auch asynchron schreiben und alles in einer Single-Thread-Anwendung ausführen. Twisted basiert auf diesem Programmiermodell. Ich vor kurzem made a blog post, dass erläutert, wie ich eine asynchrone Task-Schnittstelle erstellt, und Beispiel Läufer sowohl für CLI und GTK +. Sie können diese Beispiele betrachten, um zu sehen, wie Aufgaben asynchron implementiert werden können und die Benutzeroberfläche immer noch aktualisiert wird.

Zweitens, wenn Sie aus irgendeinem Grund lieber Threads verwenden möchten, müssen Sie das GTK + Threading-Modell ein wenig verstehen.

Sie sollten mit dem Lesen beginnen The PyGTK FAQ entry on the subject, und Sie könnten this blog post auch leicht zu verstehen.

Nun zur Spekulation. Ich vermute, dass Sie versuchen, Ihre GTK UI aus dem Thread zu aktualisieren, und das Sperren nicht richtig behandeln. Wenn dies der Fall ist, sollten Sie jetzt alle Ihre UI-Aktualisierungen, die Sie von Threads an den Hauptthread durchführen möchten, mit gobject.idle_add() verschieben. Auf diese Weise werden alle Benutzeroberflächenaufrufe vom Hauptthread ausgeführt. Es ist ein einfacheres mentales Modell, dem du bei deiner Programmierung folgen kannst.

Sobald Sie das Gefühl haben wirklich das Einfädeln und Verriegelungs Modelle verstehen, könnten Sie die Benutzeroberfläche von Threads zu aktualisieren betrachten, aber es ist einfach kann eine threads_enter()/threads_leave()

+0

+1: Verwenden Sie keine Threads, verwenden Sie einfach asynchrone I/O. – nosklo

1

Sie gtk.gdk verwenden zu verpassen. threads_init(), damit jeder Thread die Benutzeroberfläche mit der entsprechenden gtk.gdk.threads_enter() - und gtk.gdk.theads_leave() - Sperre bearbeiten kann, aber das Problem dabei ist, dass es unter Windows nicht gut funktioniert. Ich habe es unter Linux getestet und funktioniert ziemlich gut, aber ich hatte kein Glück damit, das über win32 zu machen.

=== bearbeiten ===

Ich habe darüber gegrast, könnten Sie nutzen die gobject.io_add_watch machen zu überprüfen, ob es etwas in Ihrer Steckdose ist, es zu packen und dann die GUI aktualisieren.Überprüfen Sie meinen Beitrag dazu: Sockets (and some other files) and PyGTK without threads.