tkinter root.after 到 运行 直到满足条件,冻结 window 导航栏直到满足条件。为什么?

tkinter root.after to run until condition is met, freezes window nav bar until the condition is met. Why?

所以我已经广泛尝试找出 运行 我的代码的最佳方法。最好的建议是递归地 运行 a root.after 直到满足条件。这有效,但它会冻结 window 直到满足条件。我不知道出了什么问题或如何解决这个问题。 我想显示 tkinter 对话框 window,每 1000 毫秒检查一次是否满足条件,一旦满足允许“下一步”按钮变为可点击。这一切都有效,除非条件从未满足,没有办法退出程序,因为导航栏卡在“未响应”状态。我真的需要这个导航栏不要搞砸了。我更喜欢它而不是关闭按钮。这是代码

def checkForPortConnection(root, initial_ports):
    new_ports = listSerialPorts()
    root.after(1000)
    if initial_ports == new_ports:
        checkForPortConnection(root, initial_ports)
    else:
        return
    

def welcomeGui():
    
    root = tk.Tk()
    root.title('Setup Wizard')
    canvas1 = tk.Canvas(root, relief = 'flat')
    welcome_text='Welcome to the setup wizard for your device'
    text2 =  'Please plug your device into a working USB port'
    text3 = 'If you have already plugged it in, please unplug it and restart the wizard. \n Do not plug it in until the wizard starts. \n The "NEXT" button will be clickable once the port is detected'
    label1 = tk.Label(root, text=welcome_text, font=('helvetica', 18), bg='dark green', fg='light green').pack()
    label2 = tk.Label(root, text=text2, font=('times', 14), fg='red').pack()
    label3 = tk.Label(root, text=text3, font=('times', 12)).pack()

    nextButton = ttk.Button(root, text="NEXT", state='disabled')
    nextButton.pack()
    initial_ports = listSerialPorts()
    
    root.update()
    checkForPortConnection(root, initial_ports)
    new_ports = listSerialPorts()
    correct_port = [x for x in initial_ports + new_ports if x not in initial_ports or x not in new_ports]
    print(correct_port)
    nextButton.state(["!disabled"])
    root.mainloop()

root.after(1000) 实际上与 time.sleep(1) 相同 - 它冻结 UI 直到时间到期。它不允许事件循环处理事件。

如果你想每秒调用 checkForPortConnection,这是正确的方法:

def checkForPortConnection(root, initial_ports):
    new_ports = listSerialPorts()
    if initial_ports == new_ports:
        root.after(1000, checkForPortConnection, root, initial_ports)

这将在未来一秒(或多或少)调用 checkForPortConnection,将 rootinitial_ports 作为参数传递。每次运行s,它都会安排自己在以后再次运行,直到不再满足条件。

在时间段到期之前,mainloop 能够继续正常处理事件。