I have a worker thread, and when the worker is done I want it to show a popup dialog. The sample application below demonstrates this. There are two buttons: a "Show dialog" button which immediately displays a dialog, and a "Do work" button which launches a worker thread. The worker thread simulates some work by sleeping a moment, and then attempts to display a dialog.
The problem is that when the worker thread attempts to display the popup the program freezes. What is the difference between showing a dialog from the event handler thread in the "connected" button2_click() method, and showing a dialog in the run() method of a custom thread?
import gobject
import gtk
import threading
import time
class MessageBox(gtk.MessageDialog):
def __init__(self, parent, message):
gtk.MessageDialog.__init__(self, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, message)
self.set_default_response(gtk.RESPONSE_OK)
self.connect('response', self._handle_clicked)
def _handle_clicked(self, *args):
self.destroy()
class TestThread(threading.Thread):
def __init__(self, mainview):
threading.Thread.__init__(self)
self.mainview = mainview
def run(self):
print "Some work is done here..."
time.sleep(3)
dialog = MessageBox(self.mainview, "Work completed")
dialog.show_all()
print "Work complete"
class MainView(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.connect('delete_event', self.handle_window_delete_event)
self.connect('destroy', self.quit)
button1 = gtk.Button("Do work")
button1.connect('clicked', self.button1_click)
button2 = gtk.Button("Show dialog")
button2.connect('clicked', self.button2_click)
box = gtk.VBox()
box.pack_start(button1)
box.pack_start(button2)
self.add(box)
def quit(self, *args):
gtk.main_quit()
def handle_window_delete_event(self, *args):
return False
def button1_click(self, *args):
worker = TestThread(self)
worker.start()
def button2_click(self, *args):
dialog = MessageBox(self, "Just a message!")
dialog.show_all()
if __name__ == "__main__":
main = MainView()
main.show_all()
gobject.threads_init()
gtk.gdk.threads_init()
gtk.gdk.threads_enter()
gtk.main()
gtk.gdk.threads_leave()