Search code examples
pythontkintertimer

How to set the countdown function to stop when the time is over in Tkinter?


I am trying to make a timer that restarts when I click the time button. It works, but time keeps running after it's over. It continues from -1:59 How to fix this problem?

from tkinter import *
import time

class Application(Frame):
    def __init__(self,master):
        super(Application,self).__init__(master)
        self.pack()
        self.createWidgets()
        self._alarm_id = None

    def createWidgets(self):

        self.labelvariable = StringVar()
        self.labelvariable.set("00:00")

        self.thelabel = Label(self,textvariable = self.labelvariable,font=('Helvetica',50))
        self.thelabel.pack(side=TOP)

        self.Button_5min = Button(self,text="5 sec", bd='5', height=2, width=6, command=self.run5sec)
        self.Button_5min.pack(side=LEFT)

    def run5sec(self):
        if self._alarm_id is not None:
            self.master.after_cancel(self._alarm_id)
        self.countdown(5)    
        
    def countdown(self, timeInSeconds):
        mins,secs = divmod(timeInSeconds, 60)
        timeformat = "{0:02d}:{1:02d}".format(mins, secs)
        app.labelvariable.set(timeformat)
        self._alarm_id = self.master.after(1000, self.countdown, timeInSeconds-1)

if __name__ == '__main__':
    root = Tk()
    root.title("Timer")
    app = Application(root)
    root.mainloop()

Solution

  • .after() should be called when timeInSeconds is still greater than zero:

    def countdown(self, timeInSeconds):
        mins,secs = divmod(timeInSeconds, 60)
        timeformat = "{0:02d}:{1:02d}".format(mins, secs)
        app.labelvariable.set(timeformat)
        if timeInSeconds > 0:
            self._alarm_id = self.master.after(1000, self.countdown, timeInSeconds-1)