递归错误在 macOS 上使用 tkinter 移动对象



我正在学习tkinter,这涉及到形状的流畅运动。这就是我现在被困的地方。

我收到不一致的递归错误。该代码在Windows 1O上没有问题,但是在我的macOS上它崩溃了。

此外,如果递归之间的时间≥ 17 毫秒,它就会停止出错并按预期运行。我简化了代码,只是为了包含一个问题。

from tkinter import *
master = Tk()
canvas = Canvas(bg = "gray", width = 1000, height = 800)
canvas.pack()
cara = canvas.create_line(100,100,900,100, width = 5, fill = "red")
def moveCara():
canvas.move(cara, 0,1)
canvas.after(16, moveCara)  # Here is the time setting, change it to 17 and the thing
# does not crash.
canvas.update()
moveCara()
mainloop()

此代码导致我的 MacBook 崩溃:

RecursionError: maximum recursion depth exceeded during compilation

但是,如果我将canvas.after()中的时间更改为 17 或更大,则一切正常。 这是为什么呢?

问题是这行代码:

canvas.update()

您绝对不应该在从事件处理程序调用的函数中调用update(并且通过after运行函数被视为事件处理程序(。完全没有必要让你的程序工作,需要删除。

正在发生的事情是,您对after的调用增加了一些工作,mainloop在给定的时间后要完成。当您调用update时,如果经过了给定的时间量,它会执行该工作,否则它可能根本不执行任何操作。

如果您的计算机足够慢,那么当您调用update时,将是时候进行下一帧动画了。这会导致在第一个调用返回之前通过canvas.update()再次调用moveCora。这就是您收到递归错误的原因。

我无法在 16 毫秒时在我的机器上复制问题,但当我将时间移动到 5 毫秒时,我能够重现它。您必须有一台移动线路需要 16 毫秒以上的机器,然后调用after。当我删除对canvas.update()的调用时,我可以毫无问题地将值设置为 1ms。

最新更新