Skip to content
Advertisement

Python tkinter after method not working as expected

I’m trying to learn Tkinter module, but I can’t undestand why the after method doesn’t behave as expected. From what I know, it should wait ms milliseconds and then execute the function, but in my case the function gets executed many more time, not considering the time I write. Here’s the code:

from tkinter import *

def doSomething():
    x = int(l["text"])
    l["text"] = str(x + 1)

root = Tk()
root.geometry("300x300")
l = Label(root, text="0")
l.pack()

while True:
    l.after(1000, doSomething)
    root.update()
    if int(l["text"]) >= 5:
        break

root.mainloop() 

After the first 2 seconds the label starts displaying humongous numbers

Advertisement

Answer

After the first 2 seconds the label starts displaying humongous numbers

Keep in mind, while True, is an infinite loop, you are making infinite calls to root.after() means alot of events are being scheduled to be called after 1 second. Better way to do this is to remove your while and move it all inside your function.

from tkinter import *

root = Tk()

def doSomething():
    x = int(l["text"])
    l["text"] = x + 1
    if int(l["text"]) < 5: # Only repeat this function as long as this condition is met
        l.after(1000, doSomething)

root.geometry("300x300")
l = Label(root, text="0")
l.pack()

doSomething()

root.mainloop() 

Though the best way to write the function would be to create a variable and increase the value of that variable inside the function and then show it out:

from tkinter import *

root = Tk()

count = 0 # Initial value
def doSomething():
    global count # Also can avoid global by using parameters
    count += 1 # Increase it by 1 
    l['text'] = count # Change text
    if count < 5:
        l.after(1000, doSomething)

root.geometry("300x300")
l = Label(root, text=count)
l.pack()

doSomething() # If you want a delay to call the function initially, then root.after(1000,doSomething)

root.mainloop() 

This way you can reduce the complexity of your code too and make use of the variable effectively and avoid nasty type castings ;)

Advertisement