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 ;)