将textvariable分配给条目会导致在DoubleVar上禁用验证

时间:2019-07-15 18:49:47

标签: python-3.x validation exception tkinter

我正在修改tk.Entry()以验证数字输入,并在应用时出现错误时通知用户。

从下面的代码开始:

import tkinter as tk

class FloatEntry(tk.Entry):
    def __init__(self, parent, *args, **kwargs):

        tk.Entry.__init__(self, parent, validate="focusout", validatecommand=self.validate, *args, **kwargs)

    def validate(self):
        try:
            print(float(self.get()))
            return True
        except ValueError as e:
            print(e)
            return False


if __name__ == "__main__":
    root = tk.Tk()
    root.bind_all("<1>", lambda event:event.widget.focus_set()) # make all widgets focusable
    var = tk.DoubleVar()
    frame = tk.Frame()
    frame.pack(fill="both", expand=True)
    FloatEntry(frame, textvariable=var).pack()
    tk.Label(frame, textvariable=var).pack()
    root.mainloop()

这将导致异常触发并打印,“无法将字符串转换为float:”。此后,try和validate()中的except都不会再次被触发,因此我认为它以某种方式返回了None并禁用了验证(在这里我可能是错误的)。

如果我将变量var = DoubleVar()更改为var =tk.StringVar(),则验证将按预期工作,如果可以将字符串解析为浮点数,则打印浮点数,否则打印异常。

最后,如果我在try / except块之前将get()返回的值添加了检查,验证也将按预期进行。

def validate(self):
        try:
        val = self.get()
            if(val is not ''):
            print(float(self.get()))
            return True
        except ValueError as e:
            print(e)
            return False

是什么导致在创建FloatEntry对象时禁用验证?(或者如果没有发生,那是什么?)

1 个答案:

答案 0 :(得分:0)

老实说,我不完全理解为什么会这样。但是,一种简单的解决方法似乎是在调用超类的validatecommand之后配置__init__

class FloatEntry(tk.Entry):
    def __init__(self, parent, *args, **kwargs):

        tk.Entry.__init__(self, parent, validate="focusout", *args, **kwargs)
        self.configure(validatecommand=self.validate)

进行上述更改后,每次小部件失去焦点时,都会看到validate被调用。