Home > Software engineering >  Timer never updates when using `after`
Timer never updates when using `after`

Time:01-02

So I'm trying to make a countdown counter on tkinter that starts from 03:00 minutes and ends on 00:00, actively updated every second. At first I used a while loop with time.sleep() but it freezed my tkinter, so I tried to use tkinter after() method but without any success. What I'm trying to do is to start a timer from 03:00 minutes, goes down - 02:59, 02:58, 02:57,....,00:00 the timer is being represented using a tk.StringVar and should start just when the tkinter window open

This code I wrote raises a maximum recursion depth exception:

class BoggleGUI:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("Boggle Game")
        self.root.resizable(False, False)

        self.__sec = tk.StringVar()
        self.__sec_entry = tk.Entry(self.root, textvariable=self.__sec,
                                    width=2, font="Helvetica 14")
        self.__sec_entry.place(x=220, y=12.5)
        self.__sec.set("00")

        self.__mins = tk.StringVar()
        self.__mins_entry = tk.Entry(self.root, textvariable=self.__mins,
                                     width=2, font="Helvetica 14")
        self.__mins_entry.place(x=190, y=12.5)
        self.__mins.set("03")

        self.countdown_timer()

    def countdown_timer(self):
        times = int(self.__mins.get()) * 60   int(self.__sec.get())
        if times > -1:
            minute, second = divmod(times, 60)
            self.__mins.set("{0:2d}".format(minute))
            self.__sec.set("{0:2d}".format(second))

            self.root.update()

            if times == 0:
                self.__sec.set('00')
                self.__mins.set('00')
            times -= 1
        self.root.after(1000, self.countdown_timer)

CodePudding user response:

You need to move times =- 1 above:

            minute, second = divmod(times, 60)
            self.__mins.set("{0:2d}".format(minute))
            self.__sec.set("{0:2d}".format(second))

otherwise the update of the time does not happen and realign self.root.after(1000, self.countdown_timer)

Change the function to this and it will work:

    def countdown_timer(self):
        times = int(self.__mins.get()) * 60   int(self.__sec.get())
        if times > 0:
            times -= 1

            minute, second = divmod(times, 60)
            self.__mins.set("{0:2d}".format(minute))
            self.__sec.set("{0:2d}".format(second))

            self.root.update()

            if times == 0:
                self.__sec.set('00')
                self.__mins.set('00')
            self.root.after(1000, self.countdown_timer)

I have edited the response, also change if times > -1: to if times > 0: for when it reaches zero, otherwise goes negative.

CodePudding user response:

You can also use the threading library. And create a timer function with the sleep method and after utilize

threading.Thread(target=timer).start()

You can read more in the library documentation.

CodePudding user response:

Maybe try setting the recursion limit to an higer limit(default is set to 1000).

import sys
sys.setrecursionlimit(your_limit)

Let me know if this solve can halp.

  • Related