tkinter and time.sleep
You really should be using something like the Tkinter after method rather than time.sleep(...)
.
There's an example of using the after method at this other stackoverflow question.
Here's a modified version of your script that uses the after method:
from time import time, sleep
from Tkinter import *
def empty_textbox():
textbox.delete("1.0", END)
root = Tk()
frame = Frame(root, width=300, height=100)
textbox = Text(frame)
frame.pack_propagate(0)
frame.pack()
textbox.pack()
textbox.insert(END, 'This is a test')
textbox.after(5000, empty_textbox)
root.mainloop()
Python tkinter time.sleep() alternative
x = Tk()
x.after(miliseconds,function)
That's pretty much it.
How do I make time.sleep() work with tkinter?
I assume you want to show new number in place of old number, not below it.
import tkinter as tk
import random
def start():
# hide button
button.pack_forget()
# run `add_number` first time
add_number(level+2)
def add_number(x):
num = random.randint(1, 100)
my_list.append(num)
label['text'] = num
if x > 0:
# repeat after 2000ms (2s)
root.after(2000, add_number, x-1)
else:
# show button again after the end
button.pack()
# --- main ---
my_list = []
level = 1
root = tk.Tk()
label = tk.Label(root)
label.pack()
button = tk.Button(root, text="Click to start game", command=start)
button.pack()
root.mainloop()
Is it possible to use .after() and time.sleep() together in tkinter?
You can use after
and sleep
together, but they will each do what they are documented to do. sleep
will cause the program to sleep, and after will run the job sometime after the given time period. If the program is sleeping, it can't process event queues so the jobs scheduled by after
can't run until the program stops sleeping.
For example, if you do root.after(1000, something)
followed by time.sleep(5)
, Then the program will sleep for five seconds, and then when it wakes up it will run something
.
As a general rule of thumb, you should never call time.sleep
in the main thread of a GUI program.
time.sleep() Equivalent on Tkinter
To create an analog of:
for message in listOfMessages:
time.sleep(message.time)
change(message)
in tkinter
:
def update_widget(app, messages):
message = next(messages, None)
if message is None: # end of the loop
return
delay = int(message.time * 1000) # milliseconds
app.after(delay, change, message) # execute body
app.after(delay, update_widget, app, messages) # next iteration
update_widget(app, iter(listOfMessages))
If you want to wait until change(message)
finishes before continuing the loop:
def iterate(message, app, messages):
change(message)
update_widget(app, messages)
def update_widget(app, messages):
message = next(messages, None)
if message is None: # end of the loop
return
delay = int(message.time * 1000) # milliseconds
app.after(delay, iterate, message, app, messages)
update_widget(app, iter(listOfMessages))
Tkinter is not being stopped by sleep. Why?
As mentioned in one of the comments, time.sleep
locks the GUI and prevents any screen updates from taking place. If you want to schedule GUI function calls, you must use:
<widget>.after(<delay-in-milliseconds>, <function>)
I have used a constant sleep duration of 0.2 seconds to achieve the transition. You can modify the durations according to your preference.
time = int(sum(sleep_times[:i+1]) * 1000)
calculates the cumulated time from the start of the transition.
The reason for using lambda clr = fg_clrs[i]: W.config(fg = clr)
instead of lambda : W.config(fg = fg_clrs[i])
is explained in this answer.
Working Code:
from tkinter import *
root = Tk()
root.geometry("600x500")
fg_clrs = ("#000000", "#434343", "#8c8c8c", "#d2d2d2", "#eeeeee", "#ffffff")
sleep_times = (0.2,) * 6
label = Label(root, text="Welcome to google meet!", fg="#000000")
label.pack()
for i in range(len(sleep_times)):
time = int(sum(sleep_times[:i+1]) * 1000)
root.after(time, lambda clr = fg_clrs[i]: label.config(fg = clr))
root.mainloop()
Related Topics
Does "\D" in Regex Mean a Digit
Differencebetween a Function, an Unbound Method and a Bound Method
How to Escape Os.System() Calls
Store Different Datatypes in One Numpy Array
Stacked Bar Chart with Centered Labels
How to Get the Number of Elements in a List in Python
Fixed Digits After Decimal with F-Strings
What's the Scope of a Variable Initialized in an If Statement
Best Way to Find the Intersection of Multiple Sets
Change One Value Based on Another Value in Pandas
Strings in a Dataframe, But Dtype Is Object
Python Garbage Collector Documentation
How to Convert a String of Bytes into an Int