当我以编程方式编辑条目时调用 Validatecommand

Validatecommand is called when I edit the entry programmatically

我正在尝试创建一个具有非常特殊验证的条目。为此,我在玩弄 validatecommand。但是,我遇到了一个问题:

当条目中的某些内容被删除时,我无法判断它是通过删除还是返回space 键完成的(以及像这样的教程页面:https://www.pythontutorial.net/tkinter/tkinter-validation/ no substitution is indicated provide该信息)。

所以,我决定添加一个绑定。我 link returns “中断”并且必须注意删除字符并在其位置插入 space 的功能。

正如标题所说,问题在于 validatecommand 甚至会验证使用插入和删除方法所做的条目编辑。

为避免这种情况,我考虑在进行相应编辑时禁用验证(始终 returns 正确)。但这可能会导致其他条目无法验证。

有没有办法在以编程方式编辑条目时跳过该验证?

我把这段代码留给你,以便你有一些基础来帮助我:

from functools import partial

class ChrFormat:
    def __init__(self):
        self.charvalidators = []

    def register_in(self, widget):
        widget.config(validate="key", validatecommand=(widget.register(partial(self, widget)), "%d", "%i", "%P", "%s", "%S"))

    def add(self, obj):
        self.charvalidators.append(obj)

    def __call__(self, widget, accion, index, new_text, old_text, char):
        accion = int(accion)
        index = int(index)
        
        if(len(char) == 1):
            if(accion == 1):
                if(index < self.width):
                    for validator in self.charvalidators[index:]:
                        if(not isinstance(validator, str)):
                            break
                        index += 1
                    else:
                        return False

                    if(validator(char)):
                        widget.delete(index)
                        widget.insert(index, char)
                        widget.icursor(index + 1)

        return (accion != 1)

    def apply(self):
        self.width = len(self.charvalidators)
        self.null = "".join((part if(isinstance(part, str)) else " ") for part in self.charvalidators)

fecha = ChrFormat()
fecha.add(str.isdecimal)
fecha.add(str.isdecimal)
fecha.add("-")
fecha.add(str.isdecimal)
fecha.add(str.isdecimal)
fecha.add("-")
fecha.add(str.isdecimal)
fecha.add(str.isdecimal)
fecha.add(str.isdecimal)
fecha.add(str.isdecimal)
fecha.apply()

from tkinter import ttk
import tkinter as tk

root = tk.Tk()

sv = tk.StringVar()

entrada = ttk.Entry(textvariable=sv)
entrada.pack()

fecha.register_in(entrada)

sv.set(fecha.null)

我想我没有很好地解释自己,抱歉。我正在寻找的是,当用户按下返回 space 时,它会删除一个数字并在其位置放置一个 space。和删除类似的东西。但我需要知道将 space 放在光标的哪一侧。

显然,自然验证是正确的,也许通过绑定进行验证。

对Clipper programming languaje略有了解的朋友,我想模拟一下放图片时的情况,比如'@r 999.999'。我会 post 一个视频,但我现在不是录制的好时机,而且我没有找到任何视频来证明这一点。

Is there a way to skip that validation when programmatically editing an entry?

最简单的解决方案是在进行编辑之前将 validate 选项设置为“none”。然后,您可以通过 after_idle 重新打开验证,如 official tk documentation

中所述
widget.configure(validate="none")
widget.delete(index)
widget.insert(index, char)
widget.icursor(index + 1)
widget.after_idle(lambda: widget.configure(validate="key"))