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

LRDPRDX
  • 631
  • 1
  • 11
  • 23
  • This is similar to calling a function instead of passing the function for a Button command argument, as in [this question](https://stackoverflow.com/questions/8269096/why-is-button-parameter-command-executed-when-declared) – PM 2Ring Jul 20 '17 at 17:17
  • FWIW, you may find [this answer](https://stackoverflow.com/q/44372046/4014959) interesting. – PM 2Ring Jul 20 '17 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. – Karl Knechtel Sep 05 '22 at 05:34

1 Answers1

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)
mic4ael
  • 7,974
  • 3
  • 29
  • 42