为什么 time.sleep 在打开之前暂停 tkinter 窗口 [英] Why does time.sleep pause tkinter window before it opens

查看:38
本文介绍了为什么 time.sleep 在打开之前暂停 tkinter 窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

推荐答案

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

What time.sleep does is suspend the execution of your program. 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.

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

You probably don't understand how event loop programming works. Reading through some Tkinter tutorials should get the idea across nicely. 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.

无论如何,我想我能猜到你想做什么,即使你的问题不清楚:你想启动 GUI,然后,每一秒,替换 Label.为此,您必须等待 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. To do that, you have to wait while the GUI is running, not before it starts.

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

But you can't just call sleep while the GUI is running, either. The GUI can't run while your program is asleep (again, that's what sleep means).

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

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

当您第一次调用 add_label() 时,它会创建初始标签,要求 Tkinter 在 1000 毫秒内再次调用 add_label(),并返回.因此,在您开始循环后一秒钟,它会再次被调用,这会创建下一个标签并要求 Tkinter 稍后再次调用它.这一直持续到您将 rand 一直递减到 0,此时您调用 quit 而不是 after,结束主循环,结束程序.

When you first call add_label(), it creates the initial label, asks Tkinter to call add_label() again in 1000 milliseconds, and returns. 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. 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.

您可能还想修复有关此程序的其他问题.例如,您不必每次都销毁和创建一个新的 Widget 标签,而只需更改其文本,或者更简单地,将 rand 设为 IntVar 连接到标签,所以只需更新 rand 自动更改文本.此外,对于比这个程序更重要的任何东西,您可能希望用更简洁的东西替换全局变量——大多数 Tkinter 教程通过大约第二个或第三个示例向您展示如何使用 Frame 子类,这为您提供了一个方便的位置来组织小部件和成员变量,例如 rand.

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. 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.

这篇关于为什么 time.sleep 在打开之前暂停 tkinter 窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆