python - macOS 上使用 tkinter 移动对象时出现 RecursionError

标签 python 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:编译期间超出最大递归深度

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

最佳答案

问题出在这行代码:

canvas.update()

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

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

如果您的计算机速度足够慢,那么当您调用update时,就已经到了动画下一帧的时间了。这会导致在第一次调用返回之前通过 canvas.update() 再次调用 moveCora。这就是为什么会出现递归错误。

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

关于python - macOS 上使用 tkinter 移动对象时出现 RecursionError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58440630/

相关文章:

python - 使用 tensorflow object detection api 计算检测到的对象数量

macos - 如何获取事件空间上每个可见窗口的框架(原点、大小)?

python tkinter entry 命令无法转换为 int

python - 如何在python的tkinter中设置Treeview的宽度

python - 只有部分长字符串用 pandas write_frame 写入数据库

python - 根据某些行/条件将表格格式化为多列

python - itertools.groupby() 没有正确分组

objective-c - 如何在 OS X 上查看文件更改?

ios - 在哪里可以找到有关 Mach 内核消息传递的良好文档

python - IOError 输入溢出 : Record audio with Tkinter interface