I have a process that will take a while (maybe a minute or two) to complete. When I call this from my pygtk GUI the window locks up (darkens and prevents user action) after about 10 seconds.
I'd like to stop this from happening, but I'm not sure how. I thought multithreading would be the answer, but it doesn't seem to be working. I've tried two different methods I found online. First, I modified this FAQ to take a long running function. Secondly I tried using threading.Thread directly like in this answer, but that also locks up.
My two samples are below. I'm new to multithreading, so maybe it's not the solution I'm looking for. I'm basically just trying to keep the GUI from locking up so I can update with a progress bar and let the user use a cancel button.
#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()
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…