Mein kleiner Bruder beginnt gerade mit dem Programmieren und für sein Science Fair-Projekt simuliert er einen Vogelschwarm am Himmel. Er hat den größten Teil seines Codes geschrieben und es funktioniert gut, aber die Vögel müssen sich jeden Moment bewegen .
Tkinter beansprucht jedoch die Zeit für eine eigene Ereignisschleife, sodass sein Code nicht ausgeführt wird. Läuft root.mainloop()
, läuft und läuft weiter, und das einzige, was ausgeführt wird, sind die Ereignishandler.
Gibt es eine Möglichkeit, seinen Code neben dem Mainloop auszuführen (ohne Multithreading ist dies verwirrend und sollte einfach gehalten werden), und wenn ja, was ist das?
Im Moment hat er sich einen hässlichen Hack ausgedacht, an den er seine move()
Funktion gebunden hat <b1-motion>
, so dass es funktioniert , solange er den Knopf gedrückt hält und mit der Maus wackelt. Aber es muss einen besseren Weg geben.
threading
Modul bleiben .Die von Björn veröffentlichte Lösung führt auf meinem Computer (RedHat Enterprise 5, Python 2.6.1) zu der Meldung "RuntimeError: Tcl aus einer anderen Wohnung aufrufen". Björn hat diese Nachricht möglicherweise nicht erhalten, da laut einer von mir überprüften Stelle das falsche Behandeln von Threading mit Tkinter unvorhersehbar und plattformabhängig ist.
Das Problem scheint zu sein, dass dies
app.start()
als Referenz auf Tk gilt, da die App Tk-Elemente enthält. Ich habe dies behoben, indem ich es durchapp.start()
einself.start()
Inneres ersetzt habe__init__
. Ich habe es auch so gemacht, dass sich alle Tk-Referenzen entweder innerhalb der aufrufenden Funktionmainloop()
oder innerhalb von Funktionen befinden, die von der aufrufenden Funktion aufgerufen werdenmainloop()
(dies ist anscheinend kritisch, um den Fehler "andere Wohnung" zu vermeiden).Schließlich habe ich einen Protokollhandler mit einem Rückruf hinzugefügt, da das Programm ohne diesen mit einem Fehler beendet wird, wenn das Tk-Fenster vom Benutzer geschlossen wird.
Der überarbeitete Code lautet wie folgt:
quelle
run
Methode übergeben? Ich kann nicht herausfinden, wie man ...__init__(..)
, speichert sieself
und verwendet sie inrun(..)
while app.is_alive(): etc
Wenn Sie Ihre eigene Schleife schreiben, wie in der Simulation (ich nehme an), müssen Sie die
update
Funktion aufrufen, die das tut, was siemainloop
tut: Aktualisiert das Fenster mit Ihren Änderungen, aber Sie tun es in Ihrer Schleife.quelle
task
aufgerufen werden, werden verschachtelte Ereignisschleifen angezeigt, und das ist schlecht. Wenn Sie nicht vollständig verstehen, wie Ereignisschleifen funktionieren, sollten Sie umupdate
jeden Preis einen Anruf vermeiden .Eine andere Möglichkeit besteht darin, tkinter in einem separaten Thread ausführen zu lassen. Eine Möglichkeit ist wie folgt:
Seien Sie jedoch vorsichtig, Multithread-Programmierung ist schwierig und es ist wirklich einfach, sich selbst in den Fuß zu schießen. Zum Beispiel müssen Sie vorsichtig sein, wenn Sie Mitgliedsvariablen der obigen Beispielklasse ändern, damit Sie nicht mit der Ereignisschleife von Tkinter unterbrechen.
quelle
Dies ist die erste funktionierende Version eines GPS-Lesegeräts und Datenpräsentators. tkinter ist eine sehr fragile Sache mit viel zu wenigen Fehlermeldungen. Es stellt keine Sachen auf und sagt nicht, warum die meiste Zeit. Sehr schwierig von einem guten WYSIWYG-Formularentwickler zu kommen. Auf jeden Fall wird 10 Mal pro Sekunde eine kleine Routine ausgeführt, und die Informationen werden auf einem Formular angezeigt. Es hat eine Weile gedauert, bis es soweit war. Als ich einen Timer-Wert von 0 versuchte, wurde das Formular nie angezeigt. Mein Kopf tut jetzt weh! 10 oder mehr Mal pro Sekunde ist gut genug für mich. Ich hoffe es hilft jemand anderem. Mike Morrow
quelle