【问题标题】:TKinter Entry validation not working after setting its StringVarTKinter 条目验证在设置其 StringVar 后不起作用
【发布时间】:2020-11-26 09:42:44
【问题描述】:

我有一个 TKinter 条目小部件,我想在其中验证输入,并且一切都按预期工作。

但是当我设置 Entry 小部件的 StringVariable 时,不再调用验证函数。 有人可以解释一下这种行为吗?

这是我的问题的一个示例,我验证输入是否为数字

import tkinter as tk


class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.var1 = tk.StringVar()

        valid_cmd = (self.register(self.on_validate), '%S')
        self.entry = tk.Entry(self, textvariable=self.var1, validate="key", validatecommand=valid_cmd)
        self.entry.pack(side="top", fill="x")

        self.var1.set("25")         # comment out this line and validation function works as expected

    def on_validate(self, S):
        print("in validation function")
        if S.isdigit():
            return True
        else:
            return False


if __name__ == "__main__":
    root = tk.Tk()
    tk.Tk.geometry(root, '200x40')
    Example(root).pack(fill="both", expand=True)
    root.mainloop()

我希望能够在不丢失验证功能的情况下更改 StringVar 的值(进而更改 Entry Widget 的内容)。

【问题讨论】:

    标签: python validation tkinter tkinter-entry


    【解决方案1】:

    这是canonical documentation 所说的同时使用变量和条目验证的内容:

    一般来说,textVariablevalidateCommand 混用会很危险。所有问题都已解决,因此使用 validateCommand 不会干扰条目小部件的传统行为。将 textVariable 用于只读目的绝不会导致问题。当您尝试将 textVariable 设置为 validateCommand 不接受的内容时,危险就来了,这会导致 validate 变为 none( invalidCommand 不会被触发)。当评估 validateCommand 发生错误时也会发生同样的情况。

    主要是,当 validateCommandinvalidCommand 在评估时遇到其脚本错误或 validateCommand 没有返回有效的Tcl 布尔值。当您从 validateCommandinvalidCommand 中编辑条目小部件时,validate 选项也会将自身设置为 none >。此类版本将覆盖正在验证的版本。如果您希望在验证期间编辑条目小部件(例如将其设置为 {})并且仍然设置了验证选项,则应包含命令

    在您的情况下,当您调用 self.var1.set("25") 时,会触发验证功能。发生这种情况时,将向验证函数发送一个空字符串。这是因为%S 表示要插入的数据,而您不是在插入文本,而是在设置文本。这会导致您的函数返回 False,从而关闭验证。

    解决方案是不使用textvariable 选项。相反,直接使用insert 将文本插入到小部件中,这会将值“25”传递给您的验证函数。

    self.entry.insert(0, "25")
    

    【讨论】:

    • 非常感谢您解决了我的问题。我一直在我的代码中设置 StringVars。现在将其更改为将所有值直接插入到小部件中,它就像一个魅力
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多