Catching exceptions in Tkinter's mainloop

Mike Callahan mcalla at home.com
Mon Mar 19 21:46:44 EST 2001


I tried the following with no luck:

import Tkinter as T
import sys

class Gui:
    def __init__(self, master):
        T.Button(master, text='Crash2', command=self.crash).pack()

    def crash(self):
        z = zz

class Catcher:
    def __init__(self, func, subst, widget):
        self.func = func
        self.subst = subst
        self.widget = widget

    def __call__(self, *args):
        try:
            if self.subst:
                args = apply(self.subst, args)
            return apply(self.func, args)
        except SystemExit, msg:
            raise SystemExit, msg
        except:
            import traceback
            traceback.print_exc()
            self.widget.quit()

root = T.Tk()
f = open('test.log', 'w')
sys.stderr = f
T.CallWrapper = Catcher
app = Gui(root)
root.mainloop()

What am I doing wrong?

"Richard Townsend" <NOstarfighterSPAM at freeuk.com> wrote in message
news:drMs6.32482$HR6.3694604 at nnrp4.clara.net...
> "Mike Callahan" <mcalla at home.com> wrote in message
> news:%dws6.9947$Q47.2723350 at news1.rdc1.tn.home.com...
> > I want to make sure that if any exception pops up inside a mainloop,
that
> > exception is printed to a log file and the mainloop quits. I tried to
> > simulate this with the following code but failed:
> >
> > from Tkinter import *
> >
> > class Gui:
> >     def __init__(self, master):
> >         self.master = master
> >         self.button = Button(master, text='Crash', command=self.crash)
> >         self.button.pack()
> >
> >     def crash(self):
> >         z = zz  # trigger exception
> >
> > root = Tk()
> > app = Gui(root)
> > try:
> >     root.mainloop()
> > except:
> >     print 'caught'
> >     root.quit()
> >
> > It doesn't work. The exception is printed out by standard traceback and
> the
> > mainloop continues. What am I doing wrong?
> >
> > Mike Callahan
> >
>
> Tkinter catches exceptions raised in callbacks and Tk by using the class
> 'CallWrapper' (defined in Tkinter.py). I copied the technique used by Pmw,
> and created my own CallWrapper class (based on Tkinter.CallWrapper) and
then
> after initialising Tk, I use the following statement:
>
>     Tkinter.CallWrapper = MyCallWrapper
>
> MyCallWrapper's __call__ method invokes my error logging function in the
> final except clause, you could get yours to print info to your log file
and
> quit.
>
> Note, you must always have an except clause for SystemExit (like
> Tkinter.CallWrapper does) otherwise calling sys.exit() in a callback won't
> work!
>
> e.g.
>
> class MyCallWrapper:
>     """Internal class. Stores function to call when some user
>     defined Tcl function is called e.g. after an event occurred."""
>     def __init__(self, func, subst, widget):
>         """Store FUNC, SUBST and WIDGET as members."""
>         self.func = func
>         self.subst = subst
>         self.widget = widget
>     def __call__(self, *args):
>         """Apply first function SUBST to arguments, than FUNC."""
>         try:
>             if self.subst:
>                 args = apply(self.subst, args)
>             return apply(self.func, args)
>         except SystemExit, msg:
>             raise SystemExit, msg
>         except:
>             # substitute your functionality here...
>
> Richard
>
>
>
>





More information about the Python-list mailing list