使用tkinter root.after进行递归错误

时间:2017-04-08 23:20:38

标签: python tkinter while-loop window root

我正在制作一个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窗口没有打开,即使它在我的控制台“无法连接”中多次打印,直到它收到消息(在20秒运行之前的方式): RuntimeError: cmp中超出了最大递归深度

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

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

实际上,在使用 root.after 之前,我正在制作,这只是在20年代之后才会破坏,或者如果在此期间插入了arduino,则会出现问题。然而,当我在互联网上搜索时,我意识到Tkinter中的循环并不是一个好主意。所以,我改为root.after方法,但现在它也没有工作!

有任何帮助吗? 提前谢谢!

2 个答案:

答案 0 :(得分:1)

考虑以下代码:

root.after(0,arduino_makeConnection())

这与此代码完全相同:

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

并且,假设您的函数没有返回任何内容,它与此完全相同:

root.after(0, None)

看到问题?必须为after命令提供对可调用的引用。简而言之,删除括号:

root.after(0,arduino_makeConnection)

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

答案 1 :(得分:0)

如果您尝试制作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)。