Tkinter: Exception RuntimeError: 'maximum recursion depth exceeded'

Jeff Hobbs jeff.hobbs at gmail.com
Wed Oct 13 05:31:11 CEST 2010


On Oct 12, 9:43 am, o... at dtrx.de (Olaf Dietrich) wrote:
> I have the following (now extremely minimalistic) Tkinter
> application:
>
> --------------- START --------------------------------------------
>
> #! /usr/bin/python2.6
>
> import sys
> import Tkinter
> import numpy
> from PIL import Image, ImageTk
>
> class Viewer(object):
>
>     def __init__(self, tk_root):
>         '''Initialize viewer object for NumPy arrays.'''
>         self.root = tk_root
>         self.data = numpy.zeros((512,512))
>         self.canvas = Tkinter.Canvas(self.root, width=512, height=512)
>         self.canvas.pack()
>         self.canvas.bind('<Button1-Motion>', self.__leftbutton_motion)
>         self.viewdata()
>
>     def viewdata(self):
>         '''Update the currently viewed image data.'''
>         # convert to Tkinter photo object and insert into canvas
>         data = (self.data*255).astype('uint8')
>         img = Image.fromstring('L', (512,512), data.tostring())
>         self.photo = ImageTk.PhotoImage(img)
>         self.canvas.create_image(1, 1, image=self.photo, anchor=Tkinter.NW)
>         self.root.update()
>
>     def __leftbutton_motion(self, e):
>         '''Handle Ctrl + left mouse button (button 1) motion.'''
>         self.data[e.y, e.x] = 1
>         self.viewdata()
>
> # sys.setrecursionlimit(400)
> tk = Tkinter.Tk()
> Viewer(tk)
> tk.mainloop()
>
> --------------- END ----------------------------------------------
>
> With this class, I can "draw" with the mouse onto the
> canvas (originally, the points were connected with
> lines ...).
>
> After some somewhat heavy mouse action inside the
> canvas (with the left button pressed), the application throws:
>
> | Exception RuntimeError: 'maximum recursion depth exceeded' in <bound method PhotoImage.__del__ of <Tkinter.PhotoImage instance at 0x19c0998>> ignored
> | Exception in Tkinter callback
> | Traceback (most recent call last):
> |   File "/usr/local/apps/python/lib/python2.6/lib-tk/Tkinter.py", line 1410, in __call__
> |     return self.func(*args)
> |   File "./test_recursion.py", line 31, in __leftbutton_motion
> |     self.viewdata()
> |   File "./test_recursion.py", line 24, in viewdata
> |     self.photo = ImageTk.PhotoImage(img)
> |   File "/usr/local/apps/python/lib/python2.6/site-packages/PIL/ImageTk.py", line 113, in __init__
> |     self.__photo = apply(Tkinter.PhotoImage, (), kw)
>
> (and similiar ones)
>
> This error can be provoked faster by setting the recursion limit
> to lower values (e.g. 400 as in the comment above).
>
> Is there anything I can do (apart from increasing the recursion
> limit) to avoid this exception? Can I improve anything in the
> script above to make the whole thing more robust?
>
> Thanks in advance for any help or suggestions

It seems very heavy-handed to create 1-pixel images for drawing onto
the canvas.  Any reason not to use something lighter weight?

I suspect the "self.root.update()" is the problem.  Try
update_idletasks() instead, or to even avoid it if possible.  You
don't want to call update in the event loop, because you are likely
reprocessing from the same call, causing the recursion.

Jeff



More information about the Python-list mailing list