简体   繁体   中英

tkinter and time.sleep

I am trying to delete text inside a text box after waiting 5 seconds, but instead the program wont run and does sleep over everything else. Also is there a way for me to just make my textbox sleep so i can run other code while the text is frozen?

from time import time, sleep
from Tkinter import *

def empty_textbox():
    textbox.insert(END, 'This is a test')
    sleep(5)
    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()

empty_textbox()

root.mainloop()

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

You can emulate time.sleep in tkinter. For this we still need to use the .after method to run our code alongside the mainloop , but we could add readability to our code with a sleep function. To add the desired behavior, tkinter provides another underestimated feature, wait_variable . wait_variable stops the codeblock till the variable is set and thus can be scheduled with after .

def tksleep(t):
    'emulating time.sleep(seconds)'
    ms = int(t*1000)
    root = tk._get_default_root('sleep')
    var = tk.IntVar(root)
    root.after(ms, var.set, 1)
    root.wait_variable(var)

Real world examples:

Limitation:

  • tkinter does not quit while tksleep is used.
    • Make sure there is no pending tksleep by exiting the application.
  • Using tksleep casually can lead to unintended behavior

UPDATE

TheLizzard worked out something superior to the code above here . Instead of tkwait command he uses the mainloop and this overcomes the bug of not quitting the process as described above, but still can lead to unintended output, depending on what you expect:

import tkinter as tk

def tksleep(self, time:float) -> None:
    """
    Emulating `time.sleep(seconds)`
    Created by TheLizzard, inspired by Thingamabobs
    """
    self.after(int(time*1000), self.quit)
    self.mainloop()
tk.Misc.tksleep = tksleep

# Example
root = tk.Tk()
root.tksleep(2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM