[pygtk] dialogs, sys.excepthook and gobject.add_idle

Tim Evans t.evans at aranz.com
Tue Apr 18 07:58:18 WST 2006


Chris Lambacher wrote:
> Hi,
> 
> I have a win32 app that overrides sys.excepthook to capture top level
> exceptions and display a dialog with the error.  This was working fine until I
> had an exception occur in a thread other than the main(gui) thread.  My
> standard trick for getting the UI to do something from another thread is to
> use gobject.add_idle.  For some reason this does not work when all the
> threading set up has been done.
> 
> A very simplified sample of the error is attached.  If threading is turned on,
> ie a call is made to gtk.threads_init and the gtk.threads_enter, the app
> hangs.  If the threading is not started, everything works as expected.  If
> threading is on and the dialog is created and run in the sys.excepthook,
> everything works properly.
> 
> I have tried this with version 2.8.6 of pygtk and 2.8.14 of gtk on win32.  I
> have not tried 2.4 or 2.6 versions though either would be acceptable since the
> code base is known to work with pygtk 2.4 and gtk 2.4.
> 
> Anyone have any ideas?

When gtk.threads_init() has been called, GObject idle and timeout 
functions are called without the GDK thread lock.  You code needs a 
simple change to correctly deal with this:

   def top_level_error_dialog(tracelines):
       # display an error message
       gtk.threads_enter()
       try:
           md = gtk.MessageDialog(buttons=gtk.BUTTONS_OK, 
message_format=tracelines)
           md.set_title('Unexpected Error')
           md.run()
           md.destroy()
       finally:
           gtk.threads_leave()

I find that myself needing this so often that I wrote functions 
something like these:

   def _with_lock(func, args):
       gtk.threads_enter()
       try:
           return func(*args)
       finally:
           gtk.threads_leave()

   def idle_add_lock(func, *args):
       return gobject.idle_add(_with_lock, func, args)

   def timeout_add_lock(millisecs, func, *args):
       return gobject.timeout_add(millisecs, _with_lock, func, args)

-- 
Tim Evans
Applied Research Associates NZ
http://www.aranz.co.nz/


More information about the pygtk mailing list