不了解 Tkinter 输入框验证 [英] Dont understand Tkinter entry box validatiom

查看:21
本文介绍了不了解 Tkinter 输入框验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有输入框的 tkinter GUI,我只想允许输入数字.有人可以向我解释验证中的每个命令/代码行的作用.我不明白 vcmd 变量和所有 '%i' '%s' 的东西.谢谢:)

I have a tkinter GUI with an entry box I want to allow only numbers. Can someone explain to me what each command / line of code in validation does. I don't understand the vcmd variable and all the '%i' '%s' stuff. Thanks :)

更新:我有一个不同的应用程序来使用这个 vcmd 命令,但并不完全理解它.这是我的验证码:

UPDATE: I have a different application to use this vcmd command with and dont understand it entirely. Here is my validation code:

def validate(self, action, index, value_if_allowed, prior_value, text, validation_type, trigger_type, widget_name):
    if not int(action):
        return True
    elif text in '0123456789.-+':
        try:
            float(value_if_allowed)
            return True
        except ValueError:
            return False
    else:
        return False

我不明白为什么在这段代码中我需要所有这些:

I dont get why in this code i need all of these:

action, index, value_if_allowed, prior_value, text, validation_type, trigger_type, widget_name

为什么我需要所有这些特定于我的验证代码才能使其正常运行,它们有什么用?您提供的文档很有意义,但其中一些%s"、%i"内容对于我的特定代码似乎是不必要的,但它仅适用于包含的所有内容,如下所示:

Why do i need all of these specific to my validation code for it to function correctly and what use are they? The documentation you provided made sense but some of those '%s', '%i' stuff seemed unnecessary for my specific code yet it only works with all of them included like so:

vcmd = (self.master.register(self.validate), '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')

我也想知道 self.master.register 是做什么的,我还是想不通.

I also want to know what self.master.register does please, i still cant figure that one out.

推荐答案

如果不需要任何特殊参数,则不需要调用 register.例如,以下代码将在不带任何参数的情况下正确调用 do_validation:

If you do not need any of the special arguments, you don't need to call register. For example, the following code will correctly call do_validation without any arguments:

import tkinter as tk

def do_validation():
    value = entry.get()
    if value == "" or value.isnumeric():
        return True
    return False

root = tk.Tk()
entry = tk.Entry(root, validate='key', validatecommand=do_validation)
entry.pack(fill="x", padx=20, pady=20)

root.mainloop()

然而,在上述情况下,验证将始终落后一个字符.这是因为验证发生在之前将字符插入到条目小部件中(即:第一次调用它时,entry.get() 将返回一个空字符串).验证的全部意义在于防止非法字符,因此在字符插入之前而不是之后调用命令是有意义的.

However, in the above case the validation will always be one character behind. This is because validation happens before the character is inserted into the entry widget (ie: the first time it is called, entry.get() will return an empty string). The whole point of validation is to prevent illegal characters, so it makes sense to call the command before the character is inserted rather than after.

这就是特殊参数有用的原因——它们提供了足够的上下文,以便在将字符插入小部件之前确定一个或多个字符是否合法.

This is why the special arguments are useful -- they provide sufficient context in order to decide whether the character or characters are legal before they are inserted into the widget.

Tkinter 是 Tcl 解释器的包装器,因为 tk(tkinter 背后的核心技术)是在 Tcl 中实现的.Tcl 是一种编程语言,就像 Python 一样.

Tkinter is a wrapper around a Tcl interpreter, because tk (the core technology behind tkinter) is implemented in Tcl. Tcl is a programming language just like python.

在 Tcl 程序中,您将使用如下验证功能:

In a Tcl program, you would use the validation features like this:

proc do_validation(new_value) {
    return $new_value == "" || [string is integer $new_value]
}
entry .entry -validate key --validatecommand [list do_validation %P]

当 Tcl 检测到变化时,它对参数执行替换,然后用替换的参数调用定义的过程.例如,如果您键入A",%P 将转换为 "A" 并以 "A" 作为调用函数唯一的论据.

When Tcl detects a change, it performs substitution on the arguments, and then calls the defined procedure with the substituted arguments. For example, if you type "A", %P is converted to "A" and the function is called with "A" as the only argument.

在 Tkinter 的情况下,没有直接的推论来定义带有在运行时替换的参数的函数.

In the case of Tkinter, there is no direct corollary for defining the function with arguments to be substituted at runtime.

不幸的是,验证功能在 tkinter 包装器中没有很好地实现,因此为了正确使用验证,我们必须使用一个小的解决方法,以便将这些特殊参数传递给我们的函数.

Unfortunately, the validation feature wasn't implemented very well in the tkinter wrapper, so to properly use the validation we have to use a small workaround in order to get these special arguments passed to our function.

register 所做的是创建一个新的 Tcl 命令来调用您的 python 命令.它还创建了一个新的 python 命令,它是对这个新 Tcl 命令的引用.您可以像使用任何其他 python 命令一样使用此引用.

What register does is to create a new Tcl command that calls your python command. It also creates a new python command that is a reference to this new Tcl command. You can use this reference exactly like any other python command.

在最简单的情况下,您只需要允许编辑时字符串的外观.然后,您可以决定编辑是否会导致有效输入,或者是否会导致无效输入.如果编辑不会产生有效的输入,您可以在实际发生之前拒绝编辑.

In the simplest case, all you need is what the string would look like if the edit was to be allowed. You can then decide whether the edit is something that will result in valid input, or if it will result in invalid input. If the edit won't result in valid input, you can reject the edit before it actually happens.

表示允许编辑的值的特殊参数是%P 1.我们可以修改我们正在注册的函数来接受这个参数,我们可以在注册时添加这个参数:

The special argument that represents the value if the edit is allowed is %P 1. We can modify the function we are registering to accept this argument, and we can add this argument when we do the registering:

def do_validation(new_value):
    return new_value == "" or new_value.isnumeric()

...
vcmd = (root.register(do_validation), '%P')
entry = tk.Entry(..., validatecommand=vcmd)

这样,当底层 Tcl 代码检测到更改时,它将调用创建的新 Tcl 命令,传入一个与特殊 %P 替换相对应的参数.

With that, when the underlying Tcl code detects a change it will call the new Tcl command which was created, passing in one argument corresponding to the special %P substitution.

1此处的 tcl 文档中详细描述了所有验证机制:http://tcl.tk/man/tcl8.5/TkCmd/entry.htm#M7

1All of the mechanics of the validation are described thoroughly in the tcl documentation here: http://tcl.tk/man/tcl8.5/TkCmd/entry.htm#M7

这篇关于不了解 Tkinter 输入框验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆