0
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?

JacksonPro
  • 3,135
  • 2
  • 6
  • 29
SkiBum55
  • 1
  • 1
  • Does this answer your question? [tkinter and time.sleep](https://stackoverflow.com/questions/10393886/tkinter-and-time-sleep) Also check https://stackoverflow.com/questions/23084597/python-timer-without-blocking-the-window-in-tkinter – Nouman Apr 08 '21 at 03:46
  • Thanks Black Thunder. I saw that response before posting and tried the .after with the same result. I added timer.update() after the time.sleep statement and it now works. – SkiBum55 Apr 08 '21 at 04:01

1 Answers1

1

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()
acw1668
  • 40,144
  • 5
  • 22
  • 34