当我在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”选项使用“protocol”方法?
答案 0 :(得分:2)
是的,通过注册一个函数(我称之为on_close
,但您可以选择任何函数名称)来拦截窗口关闭事件,确实可以避免这种情况。
一个棘手的问题是protocol
是Tk
类的一种方法。在非龟[{1}}用法中,您自己创建tkinter
对象作为顶级(或#34; root&#34;)小部件。当我们使用Tk
模块提供的小部件时,我们如何访问顶级小部件?它可以通过 turtle
方法获得画布(可以通过winfo_toplevel
模块或屏幕对象访问)。
你观察到的错误是由于无限循环试图在窗口(以及它,画布)已经消失时绘制东西引起的。所以下一个棘手的问题是,我们怎样才能阻止它尝试呢?正如Apostolos' answer建议的那样,#34;如何处理Tkinter中的窗口关闭事件?&#34;,我们可以使用全局布尔标志。 (就像Apostolos一样,我称之为turtle
。但你可以选择任何对你有意义的名字。)有了它,我们的循环就不再那么无限了,它是一个条件循环。因为窗口可能在三个龟运动之间关闭,我也检查那里的旗帜:
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()
,因为无论如何,循环是程序中运行的最后一件事。 (注意我也不要调用on_close
)所以当我们突破循环,或循环结束因为它的状况不再是的,程序完成并关闭窗口。