Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with turtle simulation when closing window #23749

Open
wissme opened this issue Feb 16, 2025 · 1 comment
Open

Problem with turtle simulation when closing window #23749

wissme opened this issue Feb 16, 2025 · 1 comment

Comments

@wissme
Copy link

wissme commented Feb 16, 2025

Is there a way to get the same behavior at execution between SPYDER and IDLE to get the following program run smoothly even if called several times. I tried so many ways, so many features. It's for demonstrating with several kind of machines. IDLE should lead the semantics of mainloop and friends, correct ? Don't answer to put a try: or something like this to avoid an error. Just show a portable Python version of this code, please... or will it depend finally on the IDE ? In my little head I suppose there exists such a beast. In the web, so many patches, so many solutions, many of them not working with Spyder. How the student user can know if he should go into a menu to modify the console behavior, or...
Thanks a lot, I'm on Mac mini m1 and Spyder 6.0.4
-w

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# spyder-collision-bug-at-end.py              # sort of a code from an AI, working but terminating on error
import turtle
import time

window = turtle.Screen()
window.title("Collision")
window.setup(width=600, height=200)
window.getcanvas().winfo_toplevel().focus_force()

window.tracer(False)

x , v = 0, 4     # position on a line, speed
T = turtle.Turtle()
T. shape('circle')

def update_position():
    global x,v
    x += v
    if (x <= -200) or (x >= 200) : v = -v
    T.goto(x,0)

while True:
    window.update()
    update_position()
    time.sleep(0.01)

window.mainloop()
# _tkinter.TclError: invalid command name ".!canvas"
@ccordoba12
Copy link
Member

Hey @wissme, thanks for reporting. You said:

Is there a way to get the same behavior at execution between SPYDER and IDLE to get the following program run smoothly even if called several times.

The only way your code can work in Spyder without any changes is by following these steps:

  1. Go to the menu entry Run > Configuration per file
  2. In Runner select External terminal
  3. Click on Custom configuration to uncollapse those options.
  4. Disable Interact with the interpreter after execution

Image

After that you need to click in the menu entry Run > Run in external terminal. This will emulate the behavior you get when running in a terminal python spyder-collision-bug-at-end.py.

Since the interpreter window will be closed immediately after you close the Turtle window, users wouldn't see the error.

Don't answer to put a try: or something like this to avoid an error. Just show a portable Python version of this code, please...

I don't understand why not because

  • The error is present in IDLE too. This is what I see on Linux:

    Image

  • The error is (as far as I understand your code) expected because you're using an infinite While loop to update your animation and that will fail when the window is closed because there's no window canvas to update anymore.

  • That's what basically makes your script portable between IDEs. This is how I fixed it:

import tkinter
import turtle
import time

window = turtle.Screen()
window.title("Collision")
window.setup(width=600, height=200)
window.getcanvas().winfo_toplevel().focus_force()

window.tracer(False)

x , v = 0, 4     # position on a line, speed
T = turtle.Turtle()
T. shape('circle')

def update_position():
    global x,v
    x += v
    if (x <= -200) or (x >= 200) : v = -v
    T.goto(x,0)

while True:
    try:
        window.update()
    except turtle.Terminator:
        pass

    try:
        update_position()
    except tkinter.TclError:
        break

    time.sleep(0.01)

window.mainloop()

or will it depend finally on the IDE ?

It will, at least in Spyder's case. That's because by default we use the Jupyter architecture for execution in the IPython console. And that's not the same as a bare bones Python interpreter running your code behind the scenes (like in IDLE).

Let us know if the above helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants