canvas.itemconfig not working with time.sleep

def start_timer():

    for mins in range(WORK_MIN - 1, 0, -1):
        for secs in range(59, 0, -1):
            print(mins, secs)
            timer.itemconfig(timer_text, text=(f"{mins}:{secs}"))
            time.sleep(1)

I call this function with a button click which is supposed to start a countdown timer and update the Canvas (timer = Canvas()) text every second. If I comment out the time.sleep(1) command the displayed text seems to change as it ends at 1:1. However, with the time.sleep(1) command active, then the Canvas text never updates. I added The print(mins, secs) to verify that the loops were executing properly.

Question: anyone see anything that would prevent the timer.itemconfig from working properly with the time.sleep statement?

1 answer

  • answered 2021-04-08 04:14 acw1668

    It is because time.sleep() will block tkinter mainloop from updating widgets. It is better to use after() instead.

    Below is an example:

    import tkinter as tk
    
    WORK_MIN = 1
    
    def start_timer(seconds=WORK_MIN*60):
        mins, secs = divmod(seconds, 60)
        timer.itemconfig(timer_text, text=f"{mins:02}:{secs:02}")
        if seconds > 0:
            timer.after(1000, start_timer, seconds-1)
    
    root = tk.Tk()
    
    timer = tk.Canvas(root)
    timer.pack(fill="both", expand=1)
    
    timer_text = timer.create_text(10, 10, font="Courier 48 bold", anchor="nw")
    
    start_timer()  # start the countdown timer
    root.mainloop()