如何检测python Turtle图形中的X(关闭)按钮? [英] How to detect X (close) button in python Turtle graphics?
问题描述
当我在 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.
一件棘手的事情是protocol
是Tk
类的一个方法.在非 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屋!