how to enter dynamic delay in tkinter so that the numbers printed on the screen appears after that delay

1.1k views Asked by At

I want to introduce some delay in my code. I am using text.after() to get the delay but my tkinter window opens after that specified delay and the ouput is already printed on it.

Basically I am trying to replicate the functionality of sleep(), that is the lines of code should get executed before the timer starts. Then the timer should introduce 4 secs of delay and then the following lines of code should execute. I want to automate some test equipment and I want the next equipment to turn on after 4 secs of delay after the previous equipment was turned on.

To explain this situation, I will use a very simple code. I want the "Start Timer" to appear first. Then I want the numbers 1,2,3,4 appear on the tkinter GUI after 1 sec interval, like a timer going on from 1 to 4. Then I want "Stop Timer to appear". In this way the execution of the code is delayed by 4sec in between.

Is there a way to do this ?

Here is my updated example code:

from Tkinter import *
root = Tk()
text = Text(root)
text.pack()
def append_number(n):
    text.insert(END, str(n) + "\n")
    text.see(END)
    # add one, and run again in one second
    if n > 0:
    root.after(1000, append_number, n-1)

# start the auto-running function
text.insert(END, "Start Timer")
append_number(5)
text.insert(END, "Stop Timer")
root.mainloop()
2

There are 2 answers

3
Bryan Oakley On

You can use after to cause a function to run in the future. A simple solution is to call that immediately in the loop and schedule all of the updates:

from Tkinter import *
root = Tk()
text = Text(root)
text.pack()
def append_number(n):
    text.insert(END, str(n) + "\n")
    text.see(END)

for i in range(1, 5, 1):
    root.after(i*1000, append_number, i)
root.mainloop()

Another common pattern is to have the function automatically reschedule itself, and then quit after a certain condition. For example:

from Tkinter import *
root = Tk()
text = Text(root)
text.pack()
def append_number(n):
    text.insert(END, str(n) + "\n")
    text.see(END)
    # add one, and run again in one second
    if n < 4:
        root.after(1000, append_number, n+1)

# start the auto-running function
append_number(1)

root.mainloop()
2
MrAlexBailey On

Change the loop into a function that you can call and don't run a loop inside of it, instead keep track of the values as they change:

from Tkinter import *
root = Tk()
text = Text(root)
text.pack()

def updater(i, j):
    if i <= j:
        text.insert(END, i)
        text.insert(END, "\n")
        text.yview_pickplace("end")
        i += 1
        text.after(1000, updater, *[i, j])

root.after(1000, updater, *[0, 10])
root.mainloop()

This of course is a very general example that you will need to form to fit your own application.