![](/img/trans.png)
[英]How to make a Label appear then disappear after a certain amount of time in python tkinter
[英]Waiting certain amount of time with Tkinter
我有一個 Tkinter 程序,我想暫停 3 秒。 time.sleep
不起作用,並且after
方法不完全符合我的要求。
這是一個示例代碼:
from Tkinter import *
def waithere():
print "waiting..."
root = Tk()
print "1"
root.after(3000,waithere)
print "2"
root.mainloop()
output:
1
2
*3 seconds*
waiting...
我想要的 output:
1
waiting...
*3 seconds*
2
謝謝。
通常,讓 GUI 等待某事是一個非常糟糕的主意。 這並不意味着基於事件的程序如何工作。 或者更准確地說,GUI 已經處於永久等待狀態,您不想用自己的等待來阻止它。
話雖如此,tkinter 有辦法等到某些事情發生。 例如,您可以使用“等待”函數之一,例如wait_variable 、 wait_window或wait_visibility 。
假設您希望waithere
進行等待,您可以使用wait_variable進行等待,並after
給定的時間after
設置變量。
這是基於您的原始代碼的解決方案:
from Tkinter import *
def waithere():
var = IntVar()
root.after(3000, var.set, 1)
print("waiting...")
root.wait_variable(var)
root = Tk()
print "1"
waithere()
print "2"
root.mainloop()
使用這些方法的優點是您的代碼在等待時仍然能夠響應事件。
僅供將來參考,不要在Tkinter
使用長循環或無限循環; 它們將阻止 UI 響應用戶事件(也稱為凍結)。 我學到的方法是使用after()
函數定期更新字段。
after()
函數創建一個警報回調,意思是在調用時(使用正確的參數)它將對目標方法的調用(在下面的示例中def update(self)
與我們輸入的延遲一起排隊。您可以在class 退出循環。在__init__
上創建,然后當設置為False
時不再調用after()
。
這是創建一個繼承 Tkinter.Frame 的類以繼承功能的示例。
try:
import tkinter as tk
except:
import Tkinter as tk
import datetime
class DelayedUpdateUI(tk.Frame):
def __init__(self, master=None, **kw):
# Create widgets, if any.
tk.Frame.__init__(self, master=master, **kw)
self.timeStr = tk.StringVar()
self.lblTime = tk.Label(self, textvariable=self.timeStr)
self.lblTime.grid()
# Call update to begin our recursive loop.
self.update()
def update(self):
self.timeStr.set(datetime.datetime.now())
# We use after( milliseconds, method_target ) to call our update
# method again after our entered delay. :)
self.after(1000, self.update)
if __name__ == '__main__':
root = tk.Tk()
DelayedUpdateUI(root).grid()
root.mainloop()
基於布賴恩回答的建議:
我從基於事件的角度理解推薦的方式,但對我來說感覺不是很直觀。 每次需要時我都必須查找技巧。 因此,我創建了一個小的 mixin 類,使其更易於閱讀:
class TkWaitMixin:
"""Simple wait timer that makes Tk waiting functionality
more intiutive. Applies the recommended way according to
https://stackoverflow.com/a/51770561/12646289.
"""
def start_wait_timer(self, milliseconds):
self.resume = tk.BooleanVar(value=False)
self.master.after(milliseconds, self.resume.set, True)
# Assume master attribute is available:
# https://stackoverflow.com/a/53595036/12646289
def wait_on_timer(self):
self.master.wait_variable(self.resume)
用法示例:
import tkinter as tk
class MyWindow(tk.Tk, TkWaitMixin):
def __init__(self, master):
self.master = master
self.message_label = tk.Label('')
self.message_label.pack(padx=50, pady=50)
def show_message(self, message, milliseconds):
self.start_wait_timer(milliseconds)
self.message_label['text'] = message
self.wait_on_timer()
self.message_label['text'] = ''
root = tk.Tk()
mywin = MyWindow(master=root)
mywin.show_message('Hello world', 2000)
root.mainloop()
顯然,這僅在您在 tkinter 代碼中使用類時才有用。
您忘記在root.after(3000,waithere <<<<-)
from tkinter import *
def waithere():
print("waiting...")
root = Tk()
print("1")
root.after(3000,waithere())
print("2")
root.mainloop()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.