为什么time.sleep在打开之前暂停tkinter窗口

Ben*_*ome 2 python tkinter python-2.7

我正在为体育场开发一个程序,并time.sleep()在窗口打开之前暂停程序,而不是在我想要的时候.这种行为有什么解释?

import Tkinter as tk
import time
import random
root = tk.Tk()

label = tk.Label(root, text="Navigating To Seat")
label.pack(pady=10, padx=10)

rand = random.randint(6, 16)

while rand != 0:
    label2 = tk.Label(root, text="Foward:  " + str(rand) + "m")
    label2.pack()
    rand = rand - 1
    time.sleep(1)
    label2.pack_forget()

root.mainloop()
Run Code Online (Sandbox Code Playgroud)

aba*_*ert 5

什么time.sleep是暂停程序的执行.如果你这样做了6-16次,每次1秒,在打电话之前mainloop(),你要求它在启动你的GUI之前等待6-16秒.

您可能不了解事件循环编程的工作原理.阅读一些Tkinter教程应该很好地理解这个想法.如果您想要更少的以Tkinter为中心的解释以及有关正在发生的事情的详细信息以及绕过它的不同方法的更多信息,请参阅为什么您的GUI应用程序冻结.

无论如何,我想我可以猜到你想做什么,即使你的问题不清楚:你想要启动GUI,然后,每一秒,替换Label.要做到这一点,你必须等待GUI运行,而不是在它启动之前.

但是,您也不能sleep在GUI运行时调用.当程序处于睡眠状态时,GUI无法运行(同样,这sleep意味着什么).

最简单的方法是将循环转换为一系列函数调用,每个函数调用使用该after方法调度下一个函数调用以后运行一秒钟.例如:

import Tkinter as tk
import random
root = tk.Tk()

label = tk.Label(root, text="Navigating To Seat")
label.pack(pady=10, padx=10)

rand = random.randint(6, 16)
label2 = None

def add_label():
    global rand
    global label2
    if not rand:
        root.quit()
    if label2:
        label2.pack_forget()
    label2 = tk.Label(root, text="Foward:  " + str(rand) + "m")
    label2.pack()
    rand = rand - 1
    root.after(1000, add_label)

add_label()
root.mainloop()
Run Code Online (Sandbox Code Playgroud)

当您第一次调用时add_label(),它会创建初始标签,要求在1000毫秒内再次Tkinter调用add_label(),然后返回.因此,在您启动循环后的第二个时间,它会再次被调用,这将创建下一个标签,并要求Tkinter稍后再次调用它.继续这样跌下去,直到你递减rand所有的方式0,在这一点上,你打电话quit,而不是after,它结束主循环,从而结束该程序.

您可能想要解决此计划的其他事项.例如,而不是破坏和每次创建一个新的Widget标签,你可以改变它的文本,或者甚至更简单,使rand一个IntVar连接到标签,所以只更新rand自动更改文本.此外,对于任何比这个程序更简单的东西,你可能想要用更干净的东西替换全局变量 - 大多数Tkinter教程向你展示如何Frame通过第二或第三个例子使用子类,这为你提供了一个方便的组织场所小部件和成员变量都喜欢rand.