So I have tried extensively to figure out the best way to run my code. The best suggestions have been to run a root.after recursively until a condition is met. This works but it freezes the window until the condition is met. I cannot figure out what is wrong or how to fix this. I would like to display the tkinter dialog window, check every 1000 ms if a condition has been met, once met allow the "NEXT" button to become clickable. This all works except if the condition is never met, there is no way to exit the program because the nav bar is stuck in "not responding". I really need this nav bar to not be messed up. I prefer it over a close button. Here is the code
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)
is effectively the same as time.sleep(1)
- it freezes the UI until the time has expired. It doesn't allow the event loop to process events.
If you want to call checkForPortConnection
every second, this is the proper way to do it:
def checkForPortConnection(root, initial_ports):
new_ports = listSerialPorts()
if initial_ports == new_ports:
root.after(1000, checkForPortConnection, root, initial_ports)
That will call checkForPortConnection
one second in the future (more or less), passing root
and initial_ports
as arguments. Each time it runs, it will schedule itself to be run again in the future until the condition is no longer met.
Until the time period has expired, mainloop
is able to continue to process events as normal.