如何检测python Turtle图形中的X(关闭)按钮? [英] How to detect X (close) button in python Turtle graphics?

查看:73
本文介绍了如何检测python Turtle图形中的X(关闭)按钮?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在 Turtle 图形中运行无限循环绘图时单击 X(关闭)按钮时,会出现一些错误消息.

When I click on the X (close) button while running a infinite loop of drawing in Turtle graphics, some error messages occurs.

这是一个例子:

import turtle

wn = turtle.Screen()
tess = turtle.Turtle()

while True:
    tess.forward(50)
    tess.left(120)
    tess.forward(50)

wn.mainloop()

当我关闭窗口时,会出现以下错误消息.

When I close the window, then the following error message shows up.

Traceback (most recent call last):
  File "/Users/user/Downloads/test.py", line 8, in <module>
    tess.forward(50)
  File "/Users/user/anaconda3/lib/python3.6/turtle.py", line 1637, in forward
    self._go(distance)
  File "/Users/user/anaconda3/lib/python3.6/turtle.py", line 1605, in _go
    self._goto(ende)
  File "/Users/user/anaconda3/lib/python3.6/turtle.py", line 3178, in _goto
    self._pencolor, self._pensize, top)
  File "/Users/user/anaconda3/lib/python3.6/turtle.py", line 545, in _drawline
    self.cv.coords(lineitem, *cl)
  File "<string>", line 1, in coords
  File "/Users/user/anaconda3/lib/python3.6/tkinter/__init__.py", line 2463, in coords
    self.tk.call((self._w, 'coords') + args))]
_tkinter.TclError: invalid command name ".!canvas"

我想知道如何避免此类错误消息.

I am wondering how such error messages could be avoided.

有没有什么方法可以像使用来自 tkinter 模块的 Tk 类的WM_DELETE_WINDOW"选项的协议"方法一样?

Is there any way like using "protocol" method with "WM_DELETE_WINDOW" option of the Tk class from the tkinter module?

推荐答案

是的,这确实可以通过注册一个函数来避免(我称之为on_close,但你可以选择任何函数名)拦截窗口关闭事件.

Yes, this can indeed be avoided by registering a function (I called it on_close, but you can choose any function name) to intercept the window closing event.

一件棘手的事情是protocolTk 类的一个方法.在非 turtle tkinter 用法中,您自己创建 Tk 对象作为顶级(或根")小部件.由于我们正在使用 turtle 模块提供的小部件,我们如何访问顶级小部件?它可以通过 winfo_toplevel画布的方法(可以通过turtle模块或屏幕对象访问).

One tricky thing is that protocol is a method of the Tk class. In non-turtle tkinter usage, you create your Tk object yourself as your top-level (or "root") widget. As we are using the widgets provided by the turtle module, how can we access the top-level widget? It's available through the winfo_toplevel method of the canvas (which can be accessed through the turtle module or the screen object).

您观察到的错误是由于在窗口(以及画布)已经消失时尝试绘制内容的无限循环引起的.所以下一个棘手的事情是,我们如何防止它尝试这样做?正如 Apostolos 的回答对我如何处理 Tkinter 中的窗口关闭事件?"的建议,我们可以使用全局布尔标志.(就像 Apostolos,我称它为 running.但是你可以选择任何对你有意义的名字.)这样,我们的循环不再是无限的,它是一个条件循环.因为窗口可能在三个海龟动作之间关闭,所以我也检查了那里的标志:

The error you've observed is caused by the infinite loop trying to draw stuff when the window (and with it, the canvas) is already gone. So the next tricky thing is, how can we prevent it from attempting that? As recommended by Apostolos' answer to "How do I handle the window close event in Tkinter?", we can use a global boolean flag. (Just like Apostolos, I called it running. But you can choose any name that makes sense to you.) With that, our loop isn't so infinite anymore, it's a conditional loop. Because the window might be closed between the three turtle movements, I check the flag there, too:

import turtle

wn = turtle.Screen()
canvas = wn.getcanvas()  # or, equivalently: turtle.getcanvas()
root = canvas.winfo_toplevel()

tess = turtle.Turtle()

def on_close():
    global running
    running = False

root.protocol("WM_DELETE_WINDOW", on_close)

running = True

while running:
    tess.forward(50)
    if not running:
        break
    tess.left(120)
    if not running:
        break
    tess.forward(50)

在我的电脑上,如果没有这两个,它也能正常工作,没有错误信息

On my computer, it also works without error message without the two

    if not running:
        break

部分,但这可能只是幸运的时机,所以我不会依赖它.(除非有人能解释为什么这总是足够的.)

parts, but that might just be lucky timing, so I wouldn't rely on that. (Unless someone can explain why that should always suffice.)

注意:我不需要在on_close中调用root.destroy(),因为循环是最后运行的无论如何,在程序中.(注意我也不调用mainloop())所以当我们跳出循环,或者循环结束时,因为它的条件不再正确,程序完成并关闭窗口.

Note: I didn't need to call root.destroy() in on_close, because the loop is the last thing to run in the program, anyway. (note that I also don't call mainloop()) So when we break out of the loop, or the loop finishes because its condition is no longer true, the program finishes and closes the window.

这篇关于如何检测python Turtle图形中的X(关闭)按钮?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆