我想了解为什么这段代码:
import time
for i in range(1,11):
print(i)
time.sleep(1)
(按应有的方式)每1秒显示1到10之间的数字,而该代码为:
from tkinter import *
import time
root = Tk()
for i in range(1,11):
Label(root, text = i).grid(row=0, column=i-1, padx=5, pady =5)
time.sleep(1)
root.mainloop()
等待10秒钟,然后显示带有10个数字的窗口(而不是一个一个地添加)。 我知道这是一个愚蠢的问题,但我真的听不懂!非常感谢!亚历山德罗
答案 0 :(得分:3)
大多数GUI的工作方式与您期望的不同。
它们以异步方式工作,这意味着您可以设置窗口并启动事件循环。 此事件循环将显示您在调用事件循环之前设置的所有小部件,标签等,并等待任何事件(GUI事件,例如鼠标或键盘事件,计时器事件,甚至是网络事件)。
遇到任何事件时,将调用与该事件相关的代码,并且该代码可以请求更改GUI(显示或隐藏元素,更改图形小部件的标签或属性)但是只有当您将控制权交还给事件循环时(处理事件的代码完成时),才会执行GUI。
在给定的代码中,您可以使用睡眠语句在for循环中更改标签,但是只有在for循环完成后,才可以调用主循环,并且此时此刻将显示GUI的最终状态。
因此,您遇到的几乎是所有GUI /异步应用程序的已知问题。
您必须重写代码,以启动一个计时器事件,并在计时器事件触发时,一个函数将设置标签并将计数器增加1。如果计数器不是11,它将重新启动另一个计时器< / p>
答案 1 :(得分:3)
这是因为time.sleep函数位于root.mainloop函数之前。
root.mainloop是导致窗口显示在屏幕上并开始运行的原因。相反,我建议使用window.after,因为它告诉窗口在屏幕上显示一段时间后再运行一个函数。
这是您可以进行修改的一个示例(虽然不是很好,但是可以工作):
from tkinter import *
import time
root = Tk()
progress = 0
end = 10
def update_progress():
global progress
progress += 1
Label(root, text = progress).grid(row=0, column=progress-1, padx=5, pady =5)
if progress < end: root.after(1000,update_progress) # Tell the window to call this function in 1000ms (1 second)
root.after(0,update_progress) # Tell the window to run the update_progress function 0ms after now.
root.mainloop()
我建议您查看gelonida的答案,以解释您的原始代码为何不起作用以及以后使用GUI编程时需要记住的事情。