Vrajesh Doshi
Vrajesh Doshi

Reputation: 764

Tkinter after() function showing Unusual Behavior

from tkinter import *
##from sys import exit

class Timer:
    def __init__(self, master):
        self.master=master
        buttonstart = Button(master, text = "Start", fg = "blue", command = self.start)
        buttonstart.grid(row = 1, column = 0)

        buttonquit = Button(master, text = "Quit", fg = "blue", command=self.quitit)
        buttonquit.grid(row = 1, column = 2)

        self.timertext = DoubleVar()
        self.timertext.set(0)
        display = Label(master, textvariable = self.timertext)
        display.grid(row = 0, column = 0)    
        self.timeit=False

    def increment_timer(self):
        if self.timeit:
            ctr=int(self.timertext.get())
            self.timertext.set(ctr+1)
            self.master.after(3000, self.input_delay)
            self.master.after(4000, self.output_delay)
        if self.timeit:
            self.master.after(5000, self.increment_timer)

    def input_delay(self):
        print("Input Delay")

    def output_delay(self):
        print("Output Delay")

    def start(self):
        self.timeit=True
        self.increment_timer()

    def quitit(self):
        self.timeit=False

root = Tk()
app = Timer(root)
root.mainloop()

In the increment_timer() method, the delay of 5000 works fine but the delay of 3000 and 4000 doesn't work at all. If I change the delay of 5000 to 0 then it only keeps on giving the outcome of only input_delay method. I want to call input_delay after 3 sec delay and output_delay after 4 sec delay after that in every Iteration. Its fine to change 5000 to 0 as I dont want the delay there, rather I want the delay twice within each iteration. Please guide me for this..

Upvotes: 1

Views: 192

Answers (1)

j_4321
j_4321

Reputation: 16169

The goal is to repeat the following sequence:

  • wait 3s
  • execute self.input_delay
  • wait 4s
  • execute self.output_delay

The issue in your code is that you do

self.master.after(3000, self.input_delay)
self.master.after(4000, self.output_delay)

So you simultaneously schedule the execution of self.input_delay in 3s and of self.output_delay in 4s. So in the end both execution will be separated by only 1s. To correct this, you need to schedule the execution of self.output_delay in self.input_delay so that it will be executed 4s after the execution of self.input_delay.

Here is the relevant part of the code:

def increment_timer(self):
    if self.timeit:
        ctr=int(self.timertext.get())
        self.timertext.set(ctr+1)  # increment timer
        # schedule self.input_delay execution
        self.master.after(3000, self.input_delay) 

def input_delay(self):
    print("Input Delay")
    # schedule self.output_delay execution after executing `self.input_delay`
    self.master.after(4000, self.output_delay)

def output_delay(self):
    print("Output Delay")
    self.increment_timer()  # restart the whole sequence

Upvotes: 1

Related Questions