Tkinter and Time.Sleep

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



Leave a reply



Submit