How do I update the Tkinter tag text before performing other functions?
I’m trying to write a small GUI program using Tkinter. What I want to do is create a window with buttons and input, and it works great. However, I’d like the button to run some function func
to update the tkinter window, and run whatever happens next once it’s done :
import tkinter as tk
import time
def func():
widgets = root.grid_slaves()
for widget in widgets:
if int(widget.grid_info()['row']) != 0:
widget.destroy()
startPrompt.configure(text="Updated Text")
startPrompt.update_idletasks()
# root.update_idletasks() -- I have tried both and neither work
# Just an example of something running, to verify that the loop executes
# before tkinter window gets updated
for i in range(10):
print(i)
time.sleep(0.5)
font = ("Helvetica", 20)
root = tk. Tk()
startPrompt = tk. Label(root, text="Starting Prompt", font=font)
inputPrompt = tk. Label(root, text="Input Prompt", font=font)
root.textEntry = tk. Entry(root, width=50)
submitButton = tk. Button(root, text="Enter", command=func, width=20, pady=10, font=font)
startPrompt.grid(row=0, columnspan=2, padx=10, pady=10)
inputPrompt.grid(row=1, padx=10, pady=10)
root.textEntry.grid(row=1, column=1, padx=10)
submitButton.grid(row=2, columnspan=2)
root.mainloop()
The problem I’m having is that no matter what I try, it doesn’t work. I’ve tried using after()
but the way my program is written makes it very difficult to rewrite everything to make it work. I’ve tried using update_idletasks()
but it doesn’t seem to work either.
Does anyone know why update_idletasks()
doesn’t work, or am I using it wrong? Is there any way to solve my problem?
Solution
Seems to work for me after changing something (others are mostly just minor optimizations).
- Change
func
() to not usetime.sleep
() as follows —after()
can (also) do this using the generic widget method, and using it doesn’t interfere with mainloop() to callsleep()
way to run. < - Call the generic widget method update() instead of
update_idletasks
()
after the widget is destroyed — but still before the count loop runs
Here are some documentation describes how to use the generic widget method in this way after()
(And what the update()
method does).
FWIW: If you add a line like
statement in the initialization section of the sample code in your question (not shown here), which will prevent the window from resizing after the widget is destroyed and the display update is displayed.root.geometry('600x400')
after root=, you'll be able to better understand what's going on. Tk()
def func():
widgets = root.grid_slaves()
for widget in widgets:
if widget.grid_info()['row']: # Don't need all that int() != 0 stuff.
widget.destroy()
startPrompt.configure(text="Updated Text") # Only need to call once.
root.update() # Update display (startPrompt.update() also works here)
# Just an example of something running, to verify that the loop executes
# AFTER the tkinter window has been updated.
for i in range(10):
print(i)
# time.sleep(0.5) # Don't use sleep in tkiner programs.
root.after(500) # Pause 500 millisecs.