如何检测python Turtle图形中的X(关闭)按钮?
当我在Turtle图形中运行无限循环绘图时单击X(关闭)按钮时,会出现一些错误消息。
这是一个例子:
import turtle
wn = turtle.Screen()
tess = turtle.Turtle()
while True:
tess.forward(50)
tess.left(120)
tess.forward(50)
wn.mainloop()
当我关闭窗口时,将显示以下错误消息。
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"
我想知道如何避免此类错误消息。
有什么方法可以将tkinter模块中Tk类的“协议”方法与“ WM_DELETE_WINDOW”选项一起使用?
-
是的,确实可以通过注册一个函数(我称它为
on_close
,但是您可以选择任何函数名)来拦截窗口关闭事件,从而避免这种情况。一个棘手的事情是该类的
protocol
一种方法Tk
。在不tkinter
使用Turtle的情况下,您可以Tk
自己创建对象作为顶级(或“根”)窗口小部件。在使用turtle
模块提供的小部件时,
我们如何访问顶级小部件? 它可以通过winfo_toplevel
canvas的 方法使用
(可以通过turtle
模块或屏幕对象进行访问)。您所观察到的错误是由无限循环导致的,该循环试图在窗口(以及画布)已经消失时绘制东西。因此,下一个棘手的事情是,如何防止它尝试这样做?正如Apostolos对“如何在Tkinter中处理窗口关闭事件?”的回答所建议的,我们可以使用全局布尔标志。(就像我叫Apostolos一样
running
。但是您可以选择对您有意义的任何名称。)这样,我们的循环不再是无限的了,它是一个有条件的循环。因为在三个乌龟移动之间可能关闭了窗口,所以我也检查了那里的标志: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)
在我的计算机上,如果没有这两个提示,它也可以正常工作而没有错误消息
if not running: break
零件,但这可能只是幸运的时机,所以我不会依赖它。(除非有人可以解释为什么这总是足够的。)
注意: 不需要调用
root.destroy()
inon_close
,因为无论如何,循环是程序中最后要运行的东西。( 请注意 ,我也
不会调用mainloop()
)。因此,当我们退出循环或由于其条件不再成立而导致循环结束时,程序将结束并关闭窗口。