Tkinter grid和time.sleep()

时间:2018-04-04 14:15:54

标签: time tkinter grid sleep

我想要一个标签为.grid()然后程序等待3秒,然后是.grid_forget()。我很困惑.grid被执行了。例如:

def remove_choice(self):
    while True:
        try:
            get = int(self.entry_remove_choice.get())
        except ValueError:
            self.label_error_remove.grid(row=10,column=6) #A
            time.sleep(3)
            self.label_error_remove.grid_forget() #B
            #Empty entry box
            break
        else:
            #continue code
            break

按下按钮并执行remove_choice后,按钮显示按下三秒钟,然后#A和#B一次执行,不显示任何内容。

如果删除#B,则会在三秒钟后显示错误消息。

如果将#A和#B换成打印到终端,那么程序将按照您的想法运行,只需一条消息,等待三秒钟,然后再发送另一条消息。

如果你做了一个非常草率的解决方案(我不喜欢这个程序)并且这样做:

def remove_choice(self):
    while True:
        try:
            get = int(self.entry_remove_choice.get())
        except ValueError:
            self.label_error_remove.grid(row=10,column=6) #A
            for n in range (1,1000):
                print("abc")
            self.label_error_remove.grid_forget()
            break
        else:
            #continue code
            break

执行时#34; abc"打印1000次约1.5秒,然后程序显示网格。

有关如何让TKinter等待的任何建议。

也有人可以解释为什么网格会像这样工作,谢谢。

1 个答案:

答案 0 :(得分:0)

而不是试图忘记'每次标签,为什么不只是清除错误信息文本?

下面的示例将等待用户按下按钮并显示错误消息3秒钟。我使用.after方法在显示错误消息后3秒(3000毫秒)安排hideError方法。

try:
    import tkinter as tk
except:
    import Tkinter as tk

import time

class App(tk.Frame):
    def __init__(self,master=None,**kw):
        tk.Frame.__init__(self,master=master,**kw)
        self.errorMessage = tk.StringVar()
        self.ErrorLabel = tk.Label(textvar=self.errorMessage)
        self.ErrorLabel.grid()
        self.button = tk.Button(text="Press Me",command=self.showError)
        self.button.grid()


    def showError(self):
        # Disable the button and show the error message
        self.button['state'] = tk.DISABLED
        self.errorMessage.set("Error Message!!!!")
        self.after(3000,self.hideError)
    def hideError(self):
        #Enable the button and clear the error message.
        self.button['state'] = tk.NORMAL
        self.errorMessage.set("")

if __name__ == '__main__':
    root = tk.Tk()
    App(root).grid()
    root.mainloop()

在GUI应用程序中使用while True循环或time.sleep被认为是不好的做法。它们阻止GUI更新,因此在您的代码中,这两个操作似乎同时发生,因为time.sleep操作阻止了GUI并阻止重新绘制屏幕。

编辑:从回调中传递参数。

当前的问题是after方法期望接收对函数的引用。 self.hideError(3)返回NoneType不引用函数调用。我们可以使用匿名函数和lambda来解决这个问题。 我已经开始使用这段代码来帮助它,它来自guizero

def with_args( func_name, *args):
    """Helper function to make lambda functions easier
    Thanks to guizero"""
    return lambda: func_name(*args)

然后在代码的主要部分中,该行将如下所示。

self.after(3000,with_args(self.hideError,3))
编辑:有一种更简单的方法。 .after方法本身可以使用参数。

self.after(3000,self.hideError,3)