Tkinter / Tcl callbacks, and return -code error

Steve Davis sdati at hotmail.com
Wed Nov 6 10:48:48 EST 2002


Jeff Epler <jepler at unpythonic.net> wrote in message news:<mailman.1036514646.31698.python-list at python.org>...
> 
> It looks like raising an exception in a Python function called from TCL
> should end up returning TCL_ERROR.  It appears that there's an
> "adderrorinfo" method as well.
> 

Jeff,  

Thanks for the thought.  Yes, it looks like raising an exception
should work, but my experience seems to counter this.  First thing I
tried was the obvious (return 0 or 1, or "0" or "1").  That didn't do
it, so then I tried raising various exceptions.  This works, sort of. 
The exception doesn't seem to be caught immediately, so multiple
exceptions get raised (once each time the callback is called), and
then propagated back, eventually hitting my call to mainloop().

Fortunately, python is cool, and lets me do this (first time I'd ever
noticed this example in the tutorial!)

try:
    raise ProgressException, "Cancelled"
except ProgressException:
    # Already raised - just pass it on
    raise

Unfortunately, this doesn't actually work (probably timing issues -
the final callback call is being made after the exception(s) is
caught?)

Unfortunately, it is EXTREMELY slow to raise this exception within the
callback - I don't know what's going on (something with the event
loop, it seems), but it's something bad.  Fortunately, by modifying
tkinter's register() function (and its helper class) slightly, I can
get acceptable performance.  I just have to raise the exception within
the helper class, something like this:

    def __call__(self, *args):
        result = apply(self.func, args)
            
        if not result:
            raise ProgressException, "Cancelled"

        return result

And then I have a really ugly hack to catch the spurious exceptions
that make it through:

    try:
        while root.winfo_exists():
            try:
                root.mainloop()
            except ProgressException, e:
                print e
    except TclError:
        pass

Seems like there must be a better way...

Steve



More information about the Python-list mailing list