use*_*142 1 python time sleep tkinter
当试图中断tkinter应用程序时,似乎time.sleep()将一些先前的命令置于保持状态.根据我的理解和以前的经验,label1的文本应设置为"之前"一秒钟,然后更改为"之后".但是,"before"值永远不会显示,并且"after"在执行后正常打印一秒钟.
from tkinter import *
import time
class Display(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
label1 = Label(text = "before")
label1.grid()
self.after(1000, label1.config(text = "after"))
def main():
root = Tk()
Display(root)
root.mainloop()
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
请注意,在(...)之后使用time.sleep(...)会产生与tkinter相同的结果
from tkinter import *
import time
class Display(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
label1 = Label(text = "before")
label1.grid()
time.sleep(1)
label1.config(text = "after")
def main():
root = Tk()
Display(root)
root.mainloop()
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
我想tkinter正在等待某些东西来执行图形工作(控制台没有问题)但是我没有看到什么,而且tkinter doc没有解决这个问题.
是否有一种简单的方法来获得明显的预期结果?
time.sleep(...)
没有给出与after(...)
通话相同的结果.
该time.sleep
方法运行,但在第二个过去之前没有显示任何内容.你可以通过print('before')
在睡觉前打电话来看到这一点.在创建窗口之前,您将看到print语句执行一秒钟.这是因为Tkinter在睡眠期间没有更新任何内容.因此,在睡眠结束之前不会发生任何事情,之后标签会立即更新.而且,在睡眠结束之前不会调用mainloop,因此Tkinter还没有在它的主循环中.您可以self.parent.update()
在睡眠呼叫之前使用强制Tkinter进行更新.您将看到窗口显示,有标签'before'
,等待一秒钟,标签变为'after'
.然而,在这第二个窗口期间,窗口没有响应,这就是为什么与Tkinter一起使用睡眠是一个坏主意.
而不是睡眠,后来几乎总是更好的选择,因为它立即返回,因此它不会阻止进一步执行,并安排指定的函数在指定的时间后执行.但是,在期望传递函数名称之后,却传递函数调用.这意味着在计算后调用时,运行该函数并将返回值(即None
)作为函数名传递.因此,您会看到标签在窗口打开时更改,因为更改是在评估后调用时进行的.你应该做的是将函数名传递给after:
def update_label:
label1.config(text = "after")
self.after(1000, update_label)
Run Code Online (Sandbox Code Playgroud)
或者更短,通过创建匿名函数:
self.after(1000, lambda: label1.config(text = "after"))
Run Code Online (Sandbox Code Playgroud)
这将为您提供显示标签的预期结果,该标签在一秒钟后'before'
更改'after'
,而不会阻止Tkinter的主循环.