[英]Python Tkinter, destroy toplevel after function
我使用Tkinter作为GUI使用python编程一些驱动器。 当我的机器运行时,我想向用户显示一个顶层窗口,其中包含一些信息,这些信息应在函数完成后关闭。 这是我的最小例子:
from Tkinter import *
import time
def button_1():
window = Toplevel()
window.title("info")
msg = Message(window, text='running...', width=200)
msg.pack()
time.sleep(5.0)
window.destroy()
master = Tk()
frame = Frame(width=500,height=300)
frame.grid()
button_one = Button(frame, text ="Button 1", command = button_1)
button_one.grid(row = 0, column = 0, sticky = W + E)
mainloop()
主要问题是顶层窗口在5秒钟结束后才出现。 有什么建议? 谢谢!
在GUI有时间更新之前启动time.sleep(5)
,这就是为什么只在5秒结束后出现顶层的原因。 要更正此问题,可以在window.update_idletasks()
time.sleep(5)
之前添加window.update_idletasks()
time.sleep(5)
以强制更新显示。
但是,正如Bryan Oakley在他的回答中指出的那样,GUI在time.sleep(5)
被冻结。 我想你的最终目标不是执行time.sleep
而是耗费一些时间。 因此,如果您不想冻结GUI但不知道执行将花费多长时间,您可以在一个单独的线程中执行您的函数,并定期检查它是否在after
使用after
:
import Tkinter as tk
import time
import multiprocessing
def function():
time.sleep(5)
def button_1():
window = tk.Toplevel(master)
window.title("info")
msg = tk.Message(window, text='running...', width=200)
msg.pack()
thread = multiprocessing.Process(target=function)
thread.start()
window.after(1000, check_if_running, thread, window)
def check_if_running(thread, window):
"""Check every second if the function is finished."""
if thread.is_alive():
window.after(1000, check_if_running, thread, window)
else:
window.destroy()
master = tk.Tk()
frame = tk.Frame(width=500,height=300)
frame.grid()
button_one = tk.Button(frame, text ="Launch", command=button_1)
button_one.grid(row = 0, column = 0, sticky = "we")
master.mainloop()
一般的经验法则是你永远不应该在运行GUI的线程中调用sleep
。原因是sleep
完全按照它的说法运行,它会让整个程序进入睡眠状态。 这意味着它无法刷新窗口或对任何事件做出反应。
如果你想在一段时间后做一些事情,做正确的方法是用after
。 例如,这将在五秒后破坏窗口:
window.after(5000, window.destroy)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.