Mój młodszy brat dopiero zaczyna programować, a w ramach swojego projektu Science Fair przeprowadza symulację stada ptaków na niebie. Napisał większość swojego kodu i działa dobrze, ale ptaki muszą się poruszać w każdej chwili .
Jednak Tkinter poświęca czas na własną pętlę zdarzeń, więc jego kod nie będzie działać. Wykonywanie root.mainloop()
, uruchamianie i kontynuowanie działania, a jedyne, co uruchamia, to programy obsługi zdarzeń.
Czy istnieje sposób, aby jego kod działał obok pętli głównej (bez wielowątkowości, jest to mylące i powinno być proste), a jeśli tak, to co to jest?
W tej chwili wymyślił brzydki hack, do którego przypisał swoją move()
funkcję <b1-motion>
, więc tak długo, jak przytrzyma przycisk i porusza myszą, działa. Ale musi być lepszy sposób.
threading
modułu.Plik Rozwiązanie wysłane przez Bjorn wyników w „RuntimeError: Wywoływanie Tcl z innym mieszkaniu” wiadomości na moim komputerze (RedHat Enterprise 5, Python 2.6.1). Bjorn mógł nie otrzymać tej wiadomości, ponieważ według jednego z miejsc, które sprawdziłem , niewłaściwa obsługa wątków w Tkinter jest nieprzewidywalna i zależna od platformy.
Wydaje się, że problem polega na tym, że
app.start()
liczy się jako odniesienie do Tk, ponieważ aplikacja zawiera elementy Tk. Naprawiłem to poprzez zastąpienieapp.start()
zself.start()
wewnątrz__init__
. Zrobiłem też to tak, że wszystkie odwołania Tk znajdują się wewnątrz funkcji, która wywołujemainloop()
albo są wewnątrz funkcji, które są wywoływane przez funkcję, która wywołujemainloop()
(jest to najwyraźniej krytyczne, aby uniknąć błędu „inne mieszkanie”).Na koniec dodałem obsługę protokołu z wywołaniem zwrotnym, ponieważ bez tego program kończy pracę z błędem, gdy okno Tk jest zamykane przez użytkownika.
Zmieniony kod jest następujący:
źródło
run
metody? Wydaje się, że nie wiem, jak ...__init__(..)
, przechowujesz jeself
i używaszrun(..)
while app.is_alive(): etc
Pisząc własną pętlę, tak jak w symulacji (zakładam), musisz wywołać
update
funkcję, która robi to, comainloop
robi: aktualizuje okno twoimi zmianami, ale robisz to w swojej pętli.źródło
task
wywołanie, otrzymasz zagnieżdżone pętle zdarzeń, a to źle. Jeśli nie rozumiesz w pełni, jak działają pętle zdarzeń, powinieneś unikać dzwonieniaupdate
za wszelką cenę.Inną opcją jest zezwolenie tkinterowi na wykonanie w osobnym wątku. Można to zrobić tak:
Uważaj jednak, programowanie wielowątkowe jest trudne i naprawdę łatwo jest strzelić sobie w stopę. Na przykład, musisz być ostrożny, kiedy zmieniasz zmienne składowe klasy przykładowej powyżej, aby nie przerywać pętli zdarzeń Tkintera.
źródło
To pierwsza działająca wersja tego, co będzie czytnikiem GPS i prezenterem danych. tkinter jest bardzo delikatną rzeczą ze zbyt małą liczbą komunikatów o błędach. Nie umieszcza rzeczy i nie mówi dlaczego przez większość czasu. Bardzo trudne od dobrego programisty formularzy WYSIWYG. W każdym razie uruchamia to małą procedurę 10 razy na sekundę i przedstawia informacje w formularzu. Zajęło trochę czasu, zanim to się stało. Kiedy wypróbowałem wartość licznika czasu równą 0, formularz nigdy się nie pojawił. Boli mnie teraz głowa! 10 lub więcej razy na sekundę wystarczy dla mnie. Mam nadzieję, że pomoże to komuś innemu. Mike Morrow
źródło