2009-05-01 12 views
5

Mam problem z wątkami w pygtk. Moja aplikacja składa się z programu, który pobiera zdjęcia z Internetu, a następnie wyświetla je za pomocą pygtk. Problem polega na tym, że aby to zrobić i utrzymać responsywność GUI, potrzebuję użyć wątków.Jak pracować z wątkami w pygtk

Więc dostałem callback po tym, jak użytkownik kliknął przycisk "Pobierz zdjęcia" i wzywam metodę pobierania obrazów, które znajdują się w tej samej klasie.

thread.start_new_thread (self.images_download (ścieżka stron)

To nie zadziała. Tylko w ten sposób mogę dostać mój program, aby dostać się gwintu jest za pomocą

gtk.threads_init ()

Przed rozpoczęciem jakiejkolwiek nici. teraz pobiera obrazy ale GUI pozostaje obojętne. google to i starałem oddanie gtk.threads_enter i gtk.threads_leave wokół wątków, ale to po prostu nie działa.

Odpowiedz

12

Twoje pytanie jest trochę niejasne i bez odniesienia do twojego rzeczywistego kodu trudno jest spekulować, co robisz źle.

Więc dam ci wskazówki do przeczytania, a potem spekuluj dziko na podstawie doświadczenia.

Przede wszystkim wydaje się, że można zachować responsywność GUI tylko za pomocą wątków. To nie jest prawda. Możesz również napisać swój kod asynchronicznie i zrobić wszystko w aplikacji jednowątkowej. Twisted jest zbudowany na tym modelu programowania. Ostatnio wyjaśniłem, w jaki sposób utworzyłem asynchroniczny interfejs zadań i przykładowe programy dla CLI i GTK +. Możesz obejrzeć te przykłady, aby zobaczyć, jak zadania mogą być zaimplementowane asynchronicznie, a interfejs użytkownika wciąż jest aktualizowany.

Po drugie, jeśli wolisz używać wątków z jakiegoś powodu, musisz trochę zrozumieć model GTK +.

Powinieneś zacząć od przeczytania The PyGTK FAQ entry on the subject, a także możesz łatwo znaleźć this blog post.

Teraz do spekulacji. Zgaduję, że próbujesz zaktualizować swój interfejs GTK z wątku i nie obsługuje poprawnie blokowania. Jeśli tak jest, lepiej odłożyć na później wszystkie aktualizacje interfejsu użytkownika, które chcesz wykonać z wątków do głównego wątku, używając gobject.idle_add() W ten sposób wszystkie wywołania interfejsu użytkownika będą wykonywane z głównego wątku. Jest to łatwiejszy model mentalny do naśladowania w twoim programowaniu.

Kiedy czujesz, że naprawdę zrozumieć gwintowanie i modele blokujące, można rozważyć aktualizację UI z Twoich wątków, ale łatwo przegapić threads_enter()/threads_leave()

+0

+1: Nie używaj wątków, po prostu użyj asynchronicznych operacji we/wy. – nosklo

1

Można użyć gtk.gdk. threads_init() w celu umożliwienia dowolnego wątku modyfikowania interfejsu użytkownika z zachowaniem funkcji gtk.gdk.threads_enter() i gtk.gdk.theads_leave(), ale problem polega na tym, że nie działa dobrze w systemie Windows. Przetestowałem go na Linuksie i działa całkiem nieźle, ale nie miałem szczęścia, żeby to działało nad win32.

=== Edit ===

I zostały przeglądający ten temat, można skorzystać z gobject.io_add_watch aby sprawdzić, czy jest coś w swoim gnieździe, złapał go, a następnie zaktualizować GUI.sprawdź mój post na ten temat: Sockets (and some other files) and PyGTK without threads.