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/