Difference between a while loop and using after to repeatedly call a function

Viewed 38

What is the difference between

def after_func():
    while True:
        now_time.configure(text=datetime.datetime.now().strftime('%H: %M: %S'))
        time.sleep(1)

root = Tk()
now_time = Label(text=datetime.datetime.now().strftime('%H: %M: %S'))
now_time.pack()
root.after(10, after_func)
root.mainloop()

and

def after_func():
    now_time.configure(text=datetime.datetime.now().strftime('%H: %M: %S'))
    root.after(1000, after_func)            
root = Tk()
now_time = Label(text=datetime.datetime.now().strftime('%H: %M: %S'))
now_time.pack()
root.after(10, after_func)
root.mainloop()

Why does the first one give a not responding message while the second one results in a clock that updates every one second? In my opinion the two codes should yield the same result.

1 Answers

The critical difference is that the code using root.after allows the event loop (mainloop) to process events between each iteration. The while loop does not. Tkinter applications depend on the event loop for almost everything, including requests from the OS or the app itself to redraw the window when it detects a change in what should be displayed.

You can almost get the same results with a while loop by calling root.update within the loop, but that not recommended. Plus, the use of sleep does exactly what the name implies: the entire program goes to sleep for a second. During that second, your app will become completely unresponsive.

Technically speaking, the version with after isn't recursive. All it does is put itself on a queue to be called later. The call stack doesn't get any bigger.

Related