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