使用 tkinter root.after 的递归错误

Recursion error using tkinter root.after

我正在制作一个 tkinter 程序,其中需要通过串口与 Arduino 建立连接(但这不是很重要)。

在解释我的问题之前,这里是代码:

def arduino_makeConnection():

    global arduino

    try:
        arduino = serial.Serial('/dev/ttyACM0', 9600, timeout = 0)

    except:
        print "Failed to connect"
        if(time.time()-time_start<20):             
            root.after(0,arduino_makeConnection())



global time_start
time_start=time.time()
arduino_makeConnection()

所以,我想尝试仅在 20 秒内通过串口与 arduino 建立连接。过了那段时间,我要它放弃了。

问题是我的 tkinter window 没有打开,即使它在我的控制台中打印了很多次 "Failed to connect" 直到它收到消息(20 秒之前 运行 off): RuntimeError: cmp

超出最大递归深度

我曾尝试在 root.after 上将时间从 0 更改为 10 或 100 毫秒,但这并没有解决问题。

我认为这与事件处理程序或类似的东西有关。但是我认为由于我没有使用 While 或任何其他类型的循环,Tkinter 会工作...

实际上,在使用 root.after 之前,我正在制作一个 While,它仅在 20 年代或 insead if arduino 是在那段时间插入的。然而,当我在互联网上搜索时,我意识到 Tkinter 中的循环不是一个好主意。所以,我改成root.after方法,现在也不管用了!

有什么帮助吗? 提前致谢!

如果您尝试制作 MCVE,您可能会想出

import tkinter as tk
root = tk.Tk()

def callback():
    print('callback')
    root.after(0, callback())
callback()

这可能会使调用 callback() 调用 callback() 调用 ... 变得更加明显,直到出现递归错误。删除 root.after 调用中的 ()。也使用非零延迟。尝试上面的方法,例如,`root.after(100, callback).

考虑这段代码:

root.after(0,arduino_makeConnection())

这与此代码完全相同:

result = arduino_makeConnection()
root.after(0, result)

并且,假设您的函数没有 return 任何东西,它与此完全相同:

root.after(0, None)

看到问题了吗? after 命令必须提供对可调用对象的引用。简而言之,去掉括号:

root.after(0,arduino_makeConnection)

另外,我强烈建议不要使用 0(零)作为第一个参数。至少你应该使用 1(一)。零值可能会产生令人惊讶的副作用,因为您实际上创建了一个永不清空的无限事件队列。