pythontkinterrecursionturtle-graphicspython-turtle

Avoid RecursionError in turtle paint code


I'm creating a simple program that uses turtle in a tkinter canvas to allow the user to draw with the mouse. The drawing function seems to work fine however after you draw for a bit the program stops and calls a RecursionError.

from turtle import *
import tkinter as tk

box=tk.Tk()

canv=ScrolledCanvas(box)
canv.pack()

screen=TurtleScreen(canv)

p=RawTurtle(screen)

p.speed(0)

def draw(event):

    p.goto(event.x-256,185-event.y) #The numbers are here because otherwise the turtle draws off center. Might be different depending on computer.

canv.bind('<B1-Motion>', draw)


box.mainloop()

This should in theory draw just fine but instead it is calling a RecursionError. I'm lost as to what I can do to prevent this other than maybe wrap the function in a try loop. Any help would be really appreciated.

The output in the Python Shell:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python36-32\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\Users\Charlie\Desktop\demo.py", line 17, in draw
    p.speed(0)
  File "C:\Program Files (x86)\Python36-32\lib\turtle.py", line 2174, in speed
    self.pen(speed=speed)
  File "C:\Program Files (x86)\Python36-32\lib\turtle.py", line 2459, in pen
    self._update()
  File "C:\Program Files (x86)\Python36-32\lib\turtle.py", line 2660, in _update
    self._update_data()
  File "C:\Program Files (x86)\Python36-32\lib\turtle.py", line 2651, in _update_data
    self._pencolor, self._pensize)
  File "C:\Program Files (x86)\Python36-32\lib\turtle.py", line 545, in _drawline
    self.cv.coords(lineitem, *cl)
  File "<string>", line 1, in coords
RecursionError: maximum recursion depth exceeded while calling a Python object

I've spent a good deal of time looking around for an answer and as far as I can tell there isn't one anywhere easy to find. This is my first question on this site so please forgive me if something I did was wrong.


Solution

  • I was not able to reproduce your recursion error but I have seen it before. Usually in situations where there are new events coming in while the event handler is busy handling an event. (Which is why it looks like recursion.) The usual fix is to turn off the event handler inside the event handler. Give this a try to see if it works any better for you:

    from turtle import RawTurtle, ScrolledCanvas, TurtleScreen
    import tkinter as tk
    
    box = tk.Tk()
    
    canv = ScrolledCanvas(box)
    canv.pack()
    
    screen = TurtleScreen(canv)
    
    p = RawTurtle(screen)
    p.speed('fastest')
    
    def draw(x, y):
        p.ondrag(None)
        p.setheading(p.towards(x, y))
        p.goto(x, y)
        p.ondrag(draw)
    
    p.ondrag(draw)
    
    box.mainloop()