如何在Tkinter中更新小部件?

jig*_*uda 3 python user-interface tkinter widget

好的,所以我只是想弄清楚为什么我的代码不像我想的那样工作.

我正在构建一个GUI,我希望在Label文本变量上显示文本.我已经创建了一个函数,在调用函数时更新Label,但当然这不是我的问题.

我的问题源于我试图实现"一次打印一个字母"类型的标签.虽然它打印到我想要​​的终端它,标签插件的整体功能后才更新已经完成(在视觉上它和上面一样打印整个字符串,而不是打印一次一个字母).

所以我错过了什么,我不明白什么?你们能帮助我吗?让我发布一些代码,以便你们可以看到我的错误.

我独立尝试了这两个,他们都给我带来了相同的结果,这不是我想要的.

def feeder(phrase):
    """Takes a string and displays the content like video game dialog."""
    message = ""
    for letter in phrase:       
        time.sleep(.15)
        message += letter
        information.set(message)
        #print message

def feeder2(phrase):
    """Same as feeder, but trying out recursion"""
    current.index += 1
    if current.index <= len(phrase):
        information.set(phrase[:current.index])
        time.sleep(.1)
        feeder2(current.status())
Run Code Online (Sandbox Code Playgroud)

如果我需要发布更多代码,我不是肯定的,所以你们可以更好地理解,但如果是这样的话,我会这样做.

这个功能使用了这两个功能

def get_info():
    """This function sets the textvariable information."""
    #information.set(current)
    feeder2(current.status())
Run Code Online (Sandbox Code Playgroud)

而这又用于此功能

def validate():
    """ This function checks our guess and keeps track of our statistics for us. This is the function run when we press the enter button. """
    current.turn += 1
    if entry.get() == current.name:
        if entry.get() == "clearing":
                print "Not quite, but lets try again."
                current.guesses -= 1
        if entry.get() != "clearing":
            print "Great Guess!"
            current.points += 1

    else:
        print "Not quite, but lets try again."
        current.guesses -= 1
    print current
    get_info()
    entry.delete(0, END)
    current.name = "clearing"
Run Code Online (Sandbox Code Playgroud)

Bry*_*ley 5

每次输入事件循环时,UI都会更新.这是因为绘画是通过事件(也称为"空闲任务")完成的,因为它们是在UI处于空闲状态时完成的.

你的问题是这样的:当你编写循环并执行时time.sleep,在循环运行时不会输入事件循环,因此不会重绘.

您可以通过至少几种不同的方式解决您的问题.首先,您可以调用update_idletasks哪个将刷新屏幕.这将解决重新绘制问题,但由于您正在睡觉,因此在循环期间UI将无响应(因为按钮和按键不是"空闲任务").

另一个解决方案是编写一个带字符串的函数,从字符串中提取一个字符并将其添加到窗口小部件.然后它安排自己通过事件循环再次调用.例如:

import Tkinter as tk

class App(tk.Tk):
    def __init__(self,*args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.label = tk.Label(self, text="", width=20, anchor="w")
        self.label.pack(side="top",fill="both",expand=True)
        self.print_label_slowly("Hello, world!")

    def print_label_slowly(self, message):
        '''Print a label one character at a time using the event loop'''
        t = self.label.cget("text")
        t += message[0]
        self.label.config(text=t)
        if len(message) > 1:
            self.after(500, self.print_label_slowly, message[1:])

app = App()
app.mainloop()
Run Code Online (Sandbox Code Playgroud)

这种类型的解决方案可确保您的UI保持响应,同时仍在循环中运行代码.只是,不是使用显式循环,而是将工作添加到已经运行的事件循环中.