Mam proces, który potrwa chwilę (może minutę lub dwie), aby zakończyć. Kiedy wywołuję to z mojego GUI pygtk, okno blokuje się (przyciemnia i zapobiega działaniom użytkownika) po około 10 sekundach.Zatrzymaj GUI Pygtk przed blokowaniem podczas długotrwałego procesu
Chciałbym temu zapobiec, ale nie jestem pewien jak. Myślałem, że wielowątkowość będzie odpowiedzią, ale wydaje się, że nie działa. Próbowałem dwóch różnych metod, które znalazłem online. Najpierw zmodyfikowałem this FAQ, aby uzyskać długą funkcjonalność. Po drugie próbowałem używać threading.Thread bezpośrednio jak w this answer, ale to również się blokuje.
Moje dwie próbki znajdują się poniżej. Jestem nowy w wielowątkowości, więc może to nie jest rozwiązanie, którego szukam. Zasadniczo próbuję powstrzymać GUI przed blokowaniem, więc mogę aktualizować za pomocą paska postępu i pozwolić użytkownikowi na użycie przycisku anulowania.
#Sample 1
import threading
import time
import gobject
import gtk
gobject.threads_init()
class MyThread(threading.Thread):
def __init__(self, label, button):
super(MyThread, self).__init__()
self.label = label
self.button = button
self.counter = 0
button.connect("clicked", self.on_button_click)
self.quit = False
def update_label(self, counter):
self.label.set_text("Counter: %i" % counter)
time.sleep(20)
return False
def on_button_click(self, widget):
self.counter += 1
gobject.idle_add(self.update_label, self.counter)
window = gtk.Window()
label = gtk.Label()
box = gtk.VBox()
button = gtk.Button("Test")
box.pack_start(label)
box.pack_start(button)
window.add(box)
window.show_all()
window.connect("destroy", lambda _: gtk.main_quit())
thread = MyThread(label, button)
thread.start()
gtk.main()
thread.quit = True
#####################################
#Sample 2
from threading import Thread
import time
import gobject
import gtk
class Test():
def __init__(self):
self.counter = 0
self.label = gtk.Label()
button = gtk.Button("Test")
window = gtk.Window()
box = gtk.VBox()
box.pack_start(self.label)
box.pack_start(button)
window.add(box)
window.connect("destroy", lambda _: gtk.main_quit())
button.connect("clicked", self.on_button_click)
window.show_all()
def update_label(self, counter):
self.label.set_text("Counter: %i" % counter)
time.sleep(20)
return False
def on_button_click(self, widget):
self.counter += 1
thread = Thread(target=self.update_label, args=(self.counter,))
thread.start()
while thread.is_alive():
pass
thread.stop()
test = Test()
gtk.main()
OK, to ma sens. Rozumiem, dlaczego nie mogę ciągle sprawdzać statusu wątku. Ale muszę wiedzieć, kiedy wątek się skończy. Jeśli dodaję pasek stanu dla postępu wątku, skąd mogę wiedzieć, kiedy zatrzymać pasek stanu? –
Dodałem pasek postępu do przykładu. 'glib.timeout_add' pozwala ci odpytywać status wątku bez powodowania braku reakcji aplikacji. – jcollado
Okay świetnie. To ma sens. Nie wiedziałem o 'glib.timeout_add'. Dzięki za pomoc. –