Python label.configure有时有效为什么?

Python label.configure有时有效为什么?,python,tkinter,label,Python,Tkinter,Label,我的部分代码如下: def get_songs(): label6.configure(text='Wait') os.system('/home/norman/my-startups/grabsongs') label6.configure(text='Done') 标签不会在第一个.configure()处更新,而是在第二个处更新。 除非我在第一个错误之后立即导致故意错误,在这一点上它被更新,然后程序终止。 系统调用大约需要2分钟才能完成,因此似乎没有时间显示第一个

我的部分代码如下:

def get_songs():
    label6.configure(text='Wait')
    os.system('/home/norman/my-startups/grabsongs')
    label6.configure(text='Done')
标签不会在第一个
.configure()
处更新,而是在第二个
处更新。
除非我在第一个错误之后立即导致故意错误,在这一点上它被更新,然后程序终止。
系统调用大约需要2分钟才能完成,因此似乎没有时间显示第一个调用

我正在使用Python 2.7.6


有人知道为什么吗?

我猜你用的是
Tkinter
。如果是这样,正如@albert刚才建议的那样,您需要调用
label.update\u idletasks()
label.update()
来告诉Tkinter刷新显示

作为重现您的问题的一个非常粗糙的示例,让我们制作一个程序,该程序将:

  • 等一秒钟
  • 做点什么(睡眠2秒钟)并将文本更新为“等待”
  • 之后显示“完成”
  • 例如:

    import Tkinter as tk
    import time
    
    root = tk.Tk()
    label = tk.Label(root, text='Not waiting yet')
    label.pack()
    
    def do_stuff():
        label.configure(text='Wait')
        time.sleep(2)
        label.configure(text='Done')
    
    label.after(1000, do_stuff)
    tk.mainloop()
    
    请注意,“等待”将永远不会显示

    为了解决这个问题,我们在初始设置文本后调用
    update\u idletasks()

    import Tkinter as tk
    import time
    
    root = tk.Tk()
    label = tk.Label(root, text='Not waiting yet')
    label.pack()
    
    def do_stuff():
        label.configure(text='Wait')
        label.update_idletasks()
        time.sleep(2)
        label.configure(text='Done')
    
    label.after(1000, do_stuff)
    tk.mainloop()
    

    至于为什么会发生这种情况,实际上是因为Tkinter没有时间更新标签

    调用
    configure
    不会自动强制刷新显示,它只是在下次空闲时排队。因为您立即调用将暂停mainloop执行的东西(调用可执行文件并强制python暂停直到它完成),Tkinter永远没有机会处理对标签的更改

    请注意,当gui显示“Wait”(进程/睡眠正在运行时)时,它不会对调整大小等做出响应。Python已暂停执行,直到另一个进程完成运行

    为了解决这个问题,考虑使用<代码>子进程。Popen < /C> >(或类似的),而不是<代码> OS.Stase。然后,您需要定期轮询返回的管道,以查看子流程是否已完成

    例如(我也将其移动到一个类中,以防止范围变得过于混乱):


    这里的关键区别在于,我们可以在等待外部进程完成时调整窗口的大小/移动/与窗口交互。还请注意,我们从不需要调用
    update\u idletasks
    /
    update
    ,因为Tkinter现在确实有空闲时间来更新显示。

    我想我已经修复了您的缩进。如果缩进不正确,请随时重新编辑。另外,您还没有指定对象
    标签的类型。我猜这是一个
    tkinter.Label
    ,但你可能应该在某个地方编辑这些信息(或者用
    tkinter
    标记问题)。或者结合使用a可以完成这项工作。谢谢各位,我添加了{label.update_idletasks()},它现在可以工作了。@Buteman:如果可以,请接受答案,以便结束您的问题并将其标记为已回答
    import Tkinter as tk
    import subprocess
    
    class Application(object):
        def __init__(self, parent):
            self.parent = parent
            self.label = tk.Label(parent, text='Not waiting yet')
            self.label.pack()
            self.parent.after(1000, self.do_stuff)
    
        def do_stuff(self):
            self.label.configure(text='Wait')
            self._pipe = subprocess.Popen(['/bin/sleep', '2'])
            self.poll()
    
        def poll(self):
            if self._pipe.poll() is None:
                self.label.after(100, self.poll)
            else:
                self.label.configure(text='Done')
    
    root = tk.Tk()
    app = Application(root)
    tk.mainloop()