Tkinter: Exception RuntimeError: 'maximum recursion depth exceeded'

Jeff Hobbs jeff.hobbs at gmail.com
Wed Oct 13 10:49:56 EDT 2010


On Oct 13, 2:18 am, o... at dtrx.de (Olaf Dietrich) wrote:
> Jeff  Hobbs <jeff.ho... at gmail.com>:
>
>
>
>
>
> > On Oct 12, 9:43 am, o... at dtrx.de (Olaf Dietrich) wrote:
>
> >> 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
> [...]
> >> (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?
>
> > It seems very heavy-handed to create 1-pixel images for drawing onto
> > the canvas.  Any reason not to use something lighter weight?
>
> The example was _heavily_ simplified; originally, there was
> a background (e.g. gray-scale) image and I was drawing lines or
> other shapes onto that background that should appear in color
> and semi-transparent on top of the background. Additionally,
> both background and foreground can be zoomed and scrolled, and
> there should be a pixel-by-pixel correspondence between the
> (zoomed) background pixels and the semi-transparent shapes
> in the foreground (as opposed to overlayed vector graphics).
> I could not find a more light-weight solution for these
> requirements.

Interesting.  The canvas would support many of your primitives,
although the semi-transparent is only directly supported by images in
the core.  I'm not sure I entirely understand your app needs, but this
sounds like something the tkpath Tk extension solves (sort of canvas+
+), though that doesn't have a Tkinter wrapper that I'm aware of.

> > 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.
>
> Indeed, Tk/Toplevel/Canvas.update() seems to be at the
> center of the problem.
>
> If I replace update() by update_idletasks(), the problem
> disappears, but unfortunately, considerably fewer events
> are recorded on the canvas (when connecting the pixels with
> lines, the lines become much longer with update_idletasks()
> than with update()). If I remove both update() and
> update_idletasks(), things work similarly as with
> update_idletasks() (the display is only marginally slower
> than with update_idletasks()).
>
> I wonder if there is any compromise between update()
> and update_idletasks():
>
> * update(): smooth lines but recursion exception
> * update_idletasks(): non-smooth lines without exceptions

In general it isn't necessary to use update to keep up in pure Tcl/
Tk.  You can see an example drawing app at http://wiki.tcl.tk/15386
that has no trouble keeping up with the fastest mouse, without
update.  Without digging deeper into the Tkinter wrapper, maybe just
extending the recursionlimit is the easiest work-around?

Jeff



More information about the Python-list mailing list