Search code examples
pythonturtle-graphicstracebackpython-turtle

Python (Turtle) reports error when application window is exited


I've been testing the turtle library for about 3 days now. One recurring 'issue' that I've been getting is the traceback error whenever I exit my application window. The terminal displays rows of details regarding the turtle update function and it ends with:

_tkinter.TclError: can't invoke "update" command: application has been destroyed

Here's my code:

import turtle
wn = turtle.Screen()
wn.title("Game Window")
wn.bgcolor("black")
wn.setup(width=1000, height=650)
wn.tracer(0)

run = True

while run:

    wn.update()

I've been trying to wrap my head around the traceback report. I'm assuming it happens because the application continuously updates the window (as you can see in the while run block). So, there is a possibility that, once I exit the window, the application is already processing the wn.update() function, and it returns an error because it did not finish its operation. If that is the case, then what should I do about the update function? If not then, please, explain to me the issue and solution. Thank you!


Solution

  • The problem is your loop:

    while run:
    
        wn.update()
    

    This is the wrong way to approach Python turtle programming. I see this loop often in SO questions so there must be a book ("Programming Python Turtle by Bad Example") or tutorial somewhere teaching people the wrong way to approach turtle.

    Generally, I'd suggest you avoid tracer() and update() until your program is basically working and you now need to optimize its performance. If you do use tracer(), then you should only call update() when you are finished making changes and you want the user to see the current display. Something like:

    from turtle import Screen, Turtle
    
    screen = Screen()
    screen.setup(width=1000, height=650)
    screen.title("Game Window")
    screen.tracer(0)
    
    turtle = Turtle()
    
    radius = 1
    
    while radius < 300:
        turtle.circle(radius, extent=1)
    
        radius += 0.25
    
    screen.update()  # force above to be seen
    screen.mainloop()
    

    A key point to note is that our program ends with a mainloop() call which passes control onto Tk(inter)'s event loop. That's the same event loop that receives the window close event and closes down turtle cleanly.