The following code shows a straightforward example of how a callback can block the main loop.
This application consists of a single button that gets disabled when it is clicked, waits 5 seconds, and is enabled again. A trivial implementation would be the following one:
import time
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.button = tk.Button(self, command=self.start_action,
text="Wait 5 seconds")
self.button.pack(padx=20, pady=20)
def start_action(self):
self.button.config(state=tk.DISABLED)
time.sleep(5)
self.button.config(state=tk.NORMAL)
if __name__ == "__main__":
app = App()
app.mainloop()
If you run the preceding program, you will note that the Wait 5 seconds button is not disabled at all, but clicking on it freezes the GUI for 5 seconds. We can directly note that in the button styling, which looks active instead of disabled; also, the title bar will not respond to mouse clicks until the 5 seconds have elapsed:
If we had included additional widgets, such as entries and scroll bars, this would also have affected them.
We will now take a look at how to achieve the desired functionality by scheduling the action instead of suspending the thread execution.