-1

When the start timer is called by the button click, how is it that the lines following the count_down function call are executed immediately before the counter is completed and returned?

Also, if we double click the start button it behaves weirdly.

Please explain the program flow in event-driven programs in python.

from tkinter import *
import math

def start_timer():

    work_sec = 15
    count_down(work_sec)
    timer_label.config(text="Work", fg="red")
    print("Debug")


def count_down(count):

    count_min = math.floor(count/60)
    count_sec = count % 60

    canvas.itemconfig(timer_text, text=f"{count_min}:{count_sec}")
    if count > 0:
        window.after(1000, count_down, count-1)



window = Tk()

timer_label = Label(text="Timer", fg="green", font=("Courier", 48, "bold"))
timer_label.pack()

canvas = Canvas(width=300, height=250, bg="black")
timer_text = canvas.create_text(150, 125, text="00:00", fill="white", font=("Arial", 35))
canvas.pack()

start_button = Button(text="start", command=start_timer)
start_button.pack()

window.mainloop()
Tls Chris
  • 3,564
  • 1
  • 9
  • 24
Mohan
  • 11
  • 4
  • Perhaps you would like to post a [mre] to reproducibly demonstrate the issue you are asking about. – khelwood May 20 '22 at 13:10
  • According to the code you shared, you are executing the count_down function before setting the timer_label.config. So it is counting down until it has to move to the else part and there it calls the start_timer function again and seems like never gets to the label setting part. Also when you say immediately, I wonder what constants values you are using. And one more thing, I don't think the Tkinter after is returning any value, so 'timer' will always be None. – Ze'ev Ben-Tsvi May 20 '22 at 15:08
  • sorry, this was my first question. I have edited it to include a minimal reproducible example – Mohan May 21 '22 at 09:46

1 Answers1

0

The point of tk.after is that it doesn't freeze the GUI. In the code count_down updates the count and the canvas and then returns to keep the GUI responsive. In the code below I've added some print statements which show what's being called when in the console. I hope this makes the sequence of calls more obvious. Try clicking the 'start' button more than once a few seconds apart.

import tkinter as tk
from math import floor

start_timer_count = 0

def start_timer():
    global start_timer_count
    start_timer_count += 1
    print( f"start_timer_called for {start_timer_count} th time."  )
    work_sec = 15
    count_down(work_sec, start_timer_count )
    print("start_completes")


def count_down(count, start_count ):

    print( f"count_down called. count = {count}. Called by start_timer {start_count}." )
    count_min = floor(count/60)
    count_sec = count % 60

    canvas.itemconfig(timer_text, text=f"{count_min}:{count_sec}")
    if count > 0:
        window.after(1000, count_down, count-1, start_count )



window = tk.Tk()

timer_label = tk.Label(text="Timer", fg="green", font=("Courier", 48, "bold"))
timer_label.pack()

canvas = tk.Canvas(width=300, height=250, bg="black")
timer_text = canvas.create_text(150, 125, text="00:00", fill="white", font=("Arial", 35))
canvas.pack()

start_button = tk.Button(text="start", command=start_timer)
start_button.pack()

window.mainloop()
Tls Chris
  • 3,564
  • 1
  • 9
  • 24