-1

I am trying to create a timer in Tkinter. This is my working example:

# GUI packages                                                         
from Tkinter import *                       
from ttk import *           
from tkMessageBox import *  

sec = 0            
#_

class RunMeasurement(Tk):   

    def __init__(self, *args, **kwargs):

        Tk.__init__(self, *args, **kwargs)
        Tk.style = Style()  
        Tk.title = 'Data sheet creation'

        self.__timeLabel = None

        myFrame = Frame(self)
        myFrame.pack(fill='both')

        self.__timeLabel = Label(myFrame)
        timeButton = Button(myFrame, text='start', command=self.Tick)
        timeButton.grid(row=0, column=0)
        self.__timeLabel.grid(row=0, column=1)


    def Tick(self):  

        global sec
        sec += 1     

        self.__timeLabel['text'] = sec
        self.__timeLabel.after(1000, self.Tick)


if __name__ == '__main__':
    app = RunMeasurement()
    app.mainloop()

But if I try to change it a little bit in order to, for example, count each time by 2 or 3 in this way (only corresponding part of the previous code was changed):

...
timeButton = Button(myFrame, text='start', command=lambda: self.Tick(3))
...
def Tick(self, index):
   ...
   sec += index
   ...
   self.__timeFrame.after(1000, self.Tick(index))

I get this (see the picture) very fast. And then the RuntimeError:

RuntimeError: maximum recursion depth exceeded while calling a Python object

enter image description here

Question: how to handle this error? And how to create such kind of timer in Tkinter?

3
  • This is similar to calling a function instead of passing the function for a Button command argument, as in this question Commented Jul 20, 2017 at 17:17
  • FWIW, you may find this answer interesting. Commented Jul 20, 2017 at 17:24
  • The same problem applies to the Button's command as to the callback for .after, and it is fixed in the same way too. Commented Sep 5, 2022 at 5:34

1 Answer 1

3

The problem is in the line below

self.__timeFrame.after(1000, self.Tick(index))

You create recursion by calling self.Tick directly. To solve the problem pass index as another argument to after method like below

self.__timeFrame.after(1000, self.Tick, index)
Sign up to request clarification or add additional context in comments.

1 Comment

Definitely, I should learn after method better. Thank you.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.