简体   繁体   English

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

[英]Why does time.sleep pause tkinter window before it opens

I'm developing a program for a stadium and time.sleep() pauses the program before the window opens instead of when I want it to. 我正在为体育场开发程序, time.sleep()在窗口打开之前而不是在我希望的时间暂停程序。 What is the explanation for this behavior? 这种现象的解释是什么?

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

What time.sleep does is suspend the execution of your program. time.sleep作用是暂停程序的执行。 If you do that 6-16 times, for 1 second each time, before ever calling mainloop() , you're asking it to wait for 6-16 seconds before starting up your GUI. 如果您执行6-16次操作(每次1秒),然后再调用mainloop() ,则要求它等待6-16秒才能启动GUI。

You probably don't understand how event loop programming works. 您可能不了解事件循环编程的工作原理。 Reading through some Tkinter tutorials should get the idea across nicely. 通读一些Tkinter教程应该可以很好地理解这个想法。 If you want a less Tkinter-focused explanation and more information about the details of what's happening and the different ways to get around it, see Why your GUI app freezes . 如果您需要较少关注Tkinter的说明,而需要更多有关发生的事情的详细信息以及解决该问题的不同方法的信息,请参阅GUI应用为何冻结

At any rate, I think I can guess what you want to do, even though it isn't clear from your question: You want to start the GUI up, and then, every second, replace the Label . 无论如何,我想我都能猜到您想做什么,即使您的问题尚不清楚:您想启动GUI,然后每秒更换Label To do that, you have to wait while the GUI is running , not before it starts. 为此,您必须在GUI运行时等待, 不是在启动之前。

But you can't just call sleep while the GUI is running, either. 但是,您也不能仅在GUI运行时调用sleep The GUI can't run while your program is asleep (again, that's what sleep means). 当程序处于sleep时,GUI无法运行(再次,这就是sleep意思)。

The easiest way out of this is to turn your loop into a sequence of function calls, each of which schedules the next one to run a second later, using the after method. 最简单的方法是将循环转换为一系列函数调用,每个函数都使用after方法将下一个函数调度为稍后运行一秒。 For example: 例如:

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

When you first call add_label() , it creates the initial label, asks Tkinter to call add_label() again in 1000 milliseconds, and returns. 首次调用add_label() ,它将创建初始标签,要求Tkinter在1000毫秒内再次调用add_label()并返回。 So, a second after you start the loop, it gets called again, which creates the next label and asks Tkinter to call it again a second later. 因此,在您启动循环后的一秒钟,它再次被调用,这将创建下一个标签,并要求Tkinter在第二秒后再次调用它。 This keeps going until you decrement rand all the way to 0 , at which point you call quit instead of after , which ends the main loop, which ends the program. 这一直持续到您将rand一直递减到0为止,这时您调用quit而不是after ,这将结束主循环并结束程序。

There are other things you probably want to fix about this program. 您可能还需要解决此程序的其他问题。 For example, instead of destroying and creating a new Widget label each time, you can just change its text—or, maybe even more simply, make rand an IntVar connected to the label, so just updating rand automatically changes the text. 例如,您不必更改每次创建和创建新的Widget标签的方式,而是只需更改其文本,或者甚至可以更简单地使rand成为与标签连接的IntVar ,因此只需更新rand自动更改文本。 Also, for anything less trivial than this program, you'd probably want to replace the global variables with something cleaner—most Tkinter tutorials show you how to use a Frame subclass by about the second or third example, which gives you a convenient place to organize both widgets and member variables like rand . 此外,对于任何比该程序更简单的事情,您可能都想用更干净的东西替换全局变量-大多数Tkinter教程大约在第二个或第三个示例中向您展示了如何使用Frame子类,这为您提供了一个方便的位置。组织小部件和成员变量(例如rand

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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