Python tkinter窗口没有';t显示-如果循环内的事件时间为0

Python tkinter窗口没有';t显示-如果循环内的事件时间为0,python,tkinter,Python,Tkinter,我绞尽脑汁想弄明白为什么tkinter窗口只有在我停止脚本后才会出现。结果是,如果我的root.after中的延迟时间(即在我的无限水果循环中)设置为0,则不会出现延迟时间。将其设置为1或更高可使其正常工作。这是一个错误还是我错过了一些重要的关于如何工作的事情?我用MacOS上的Anaconda中的Python2.7运行这个 import time import Tkinter as tk import random root = tk.Tk() root.title("random numb

我绞尽脑汁想弄明白为什么tkinter窗口只有在我停止脚本后才会出现。结果是,如果我的root.after中的延迟时间(即在我的无限水果循环中)设置为0,则不会出现延迟时间。将其设置为1或更高可使其正常工作。这是一个错误还是我错过了一些重要的关于如何工作的事情?我用MacOS上的Anaconda中的Python2.7运行这个

import time
import Tkinter as tk
import random

root = tk.Tk()
root.title("random numbers")    
root.geometry("220x220+5+5")

frame = tk.Frame(root, width=210, height=210)
frame.pack()

luckynumber = tk.IntVar()

label1 = tk.Label(frame, text="random number").pack(side=tk.LEFT)

display1 = tk.Label(frame, textvariable=luckynumber)
display1.pack( side=tk.LEFT )

def askrandy():
    randy = random.randrange(0, 100, 1)
    luckynumber.set(randy)

def fruityloop():

    time.sleep(.5)
    askrandy()
    root.after(1, fruityloop)

root.after(0, fruityloop)
root.mainloop()

第二个问题:这段代码运行得不是很顺利。因为它很简单,我认为它会很坚固。但我发现启动需要几秒钟,移动窗户也会导致口吃。将主循环作为一个类运行会更好吗

如果没有
sleep()
,情况应该是这样的。但我不知道这是否有帮助。它在Linux上运行得很快

如果在
IDLE
中运行代码,则可能会出现问题,因为它使用
Tkinter
显示窗口并运行自己的
mainloop()
,但
Tkinter
应该只运行一个
mainloop()
。您可以直接在控制台
pythonscript.py
中进行尝试

import Tkinter as tk
import random

# --- functions ---

def fruityloop():
    randy = random.randrange(0, 100, 1)
    luckynumber.set(randy)

    # run again after 500ms = 0.5s
    root.after(500, fruityloop)

# --- main ---

root = tk.Tk()

root.title("random numbers")    
root.geometry("220x220+5+5")

luckynumber = tk.IntVar()

frame = tk.Frame(root, width=210, height=210)
frame.pack()

label = tk.Label(frame, text="random number")
label.pack(side=tk.LEFT)

display = tk.Label(frame, textvariable=luckynumber)
display.pack(side=tk.LEFT)

# run first time
fruityloop()

root.mainloop()

这是正常的行为

Tkinter在空闲时维护一个要完成的工作队列。这是“空闲”队列

在之后调用
时,您提供的函数将添加到此队列。当主事件循环(或在空闲后调用
)处理队列时,它会根据当前时间和项目应运行的时间在队列中查找应运行的项目。所有要运行的项目都将在处理队列停止之前运行

如果其中一个将值为零的项添加到队列中,则该项将在到期后运行。如果该项目本身向队列中添加了一个项目,那么您将从队列中删除一个项目,并立即放置一个项目,以便队列永远不会变为空。如果队列从未变为空,tkinter将无法处理其他类型的事件

程序看起来缓慢而急促的原因是调用了
sleep
。当您调用
sleep
时,tkinter的作用就是:它睡觉。它不能处理任何事件,甚至是只刷新窗口的事件。如果希望每隔半秒调用一次
askrandy
,只需使用值500调用
after
,而不是使用值0调用它,然后再休眠半秒


主窗口是否为类不会影响您的程序。您只需停止使用
sleep
,并在
之后向
提供正常值。如果您试图显示一个简单的动画,那么值30大约是您需要的最小值

这里的问题是什么?你不应该在GUI中使用
time.sleep
。@Stephen Rauch,Q1=这是个bug还是我很笨?Q2=这段代码应该运行顺利吗?@chm我已经试过了,没有遇到任何问题。@TigerhawkT3 True,得到了很多方法,
之后,
线程
,等等。。。