是的,通过注册一个函数(我称之为on_close,但您可以选择任何函数名)来拦截窗口关闭事件,从而避免这种情况。在
一个棘手的问题是protocol是Tk类的一个方法。在非turtle tkinter用法中,您可以自己创建Tk对象作为顶层(或“根”)小部件。当我们使用turtle模块提供的小部件时,我们如何访问顶层小部件?它可以通过画布的winfo_toplevel方法获得(可以通过turtle模块或screen对象访问)。在
您观察到的错误是由于无限循环试图在窗口(以及画布)已经不存在的情况下绘制内容而引起的。所以下一个棘手的问题是,我们怎样才能阻止它这样做呢?正如Apostolos' answer对“如何处理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)
在我的电脑上,它也能正常工作,没有错误信息
^{pr2}$
但这可能是个幸运的时机,所以我不相信。(除非有人能解释为什么这样就足够了。)
注意:我不需要在on_close中调用root.destroy(),因为不管怎样,循环是程序中最后一个运行的东西。(注意我也不调用mainloop()),所以当我们跳出循环,或者循环因其条件不再为真而结束时,程序完成并关闭窗口。在