On 04 April 2003, Jon Trowbridge said: > That set, allow me to offer a suggestion: you can make your life a lot > easier by not making gtk calls from threads. Instead, do all of your > gtk calls from inside of one-shot idle functions launched from inside > threads.
Great tip -- I've rewritten the code yet again, and it seems to work now. Mostly. (While the eject ioctl() is running in a background thread, the GUI is not responsive -- rather, events are buffered and replayed when the ioctl() returns and the background thread finishes. However, if I replace the ioctl() with a sleep(), then the GUI responds exactly as I expect. So I'm inclined to blame this on Linux rather than GTK: perhaps a blocking ioctl() blocks *all* threads of the current process, rather than just the thread that made the call. In that case, putting the CD-ROM eject/close ioctl() calls in a background thread is pointless. Sigh. Well, it should still help for CDDB lookups...) > Your "eject" example could be handled by code like this: For the record, here's how I did it (roughly): # setup the GUI def __init__ (self): # ... self.eject_button.connect("clicked", self.start_eject) # ...later on... def start_eject (self, widget): # First update the GUI to reflect what we're about to do. ebutton = self.eject_button ebutton.set_sensitive(False) if self.cdrom.tray_open: # will close the drive tray status = "Closing CD-ROM drive tray..." ebutton.set_label("Eject") else: # will eject the disc status = "Ejecting CD..." ebutton.set_label("Close") self.statusbar.push(self.statusbar.get_context_id(""), status) gtk.mainiteration() # And then launch the thread that actually does it. print "launching eject/close thread..." thread = Thread(name="cdrom-eject", target=self.eject_cd) thread.start() def eject_cd (self): print "eject/close thread (%r) starting" % get_thread_id() if self.cdrom.tray_open: # close the drive tray self.cdrom.closetray() else: self.cdrom.eject() gtk.idle_add(self.eject_done) def eject_done (self): print "eject_done(): thread %r updating widgets" % get_thread_id() self.eject_button.set_sensitive(True) self.statusbar.pop(self.statusbar.get_context_id("")) Thanks! Greg -- Greg Ward <[EMAIL PROTECTED]> http://www.gerg.ca/ Moderation is for monks. _______________________________________________ pygtk mailing list [EMAIL PROTECTED] http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/