简体   繁体   English

ttk条目小部件-验证条目-无效的文本输入不会导致恢复为先前的文本

[英]ttk Entry widget - validate entry - invalid text entry does not cause reverting to previous text

Python 3.1 Python 3.1

I'm trying to validate that the string input to a ttk.Entry widget can be turned into a float. 我正在尝试验证输入到ttk.Entry小部件的字符串是否可以转换为浮点型。 The simple code below shows that the validate function is successful in its task, and is returning true/false correctly. 下面的简单代码显示validate函数已成功完成任务,并且正确返回了true / false。

I understood it to be the case that if the Entry widget gets 'false' back from its validatecommand, it should revert to whatever was stored in the textvariable before the attempted entry happened. 据我了解,如果Entry小部件从validate命令返回“ false”,它应该恢复为尝试输入之前在textvariable中存储的内容。

But that's not happening - the new entry appears, even though it's invalid. 但这并没有发生-即使无效,也会出现新条目。

Presumably I am missing something foolish... 想必我想念一些愚蠢的东西...

from tkinter import *
from tkinter.ttk import *
root = Tk()

text = StringVar()
text.set('100.0')

def validate(inp):
    print(inp)
    if inp in '0123456789.-+':
        try:
            float(inp)
            print('float')
            return True
        except ValueError:
            print('notfloat')
            return False
    else:
        print('notfloat')
        return False

vcmd = root.register(validate)

a = Entry(textvariable = text,
          validate = 'focusout',
          validatecommand = (vcmd,'%P'))
a.pack()

b = Entry()
b.pack()

root.mainloop()

Try following: 请尝试以下操作:

from tkinter import *
from tkinter.ttk import *
root = Tk()

text = StringVar()
text.set('100.0')

def validate(inp):
    try:
        float(inp)
    except ValueError:
        return False
    return True

vcmd = root.register(validate)

a = Entry(textvariable=text,
          validate='key',
          validatecommand=(vcmd, '%P'))
a.pack()

b = Entry()
b.pack()

root.mainloop()

I used validate='key' instead. 我改用validate='key'

and replaced validate function. 并替换了validate功能。 a in b check substring a in contained in b . a in b支票串a中所含的b

>>> '100.00' in '0123456789.-+'
False
>>> '100.00' in 'blah blah   100.00  blah blah'
True

ALTERNATIVE 替代

using focusout : 使用focusout

from tkinter import *
from tkinter.ttk import *
root = Tk()

text = StringVar()
text.set('100.0')
last_ok_value = text.get()

def validate(inp):
    global last_ok_value
    try:
        float(inp)
    except ValueError:
        return False
    last_ok_value = inp
    return True

def invalidate():
    text.set(last_ok_value)

vcmd = root.register(validate)
ivcmd = root.register(invalidate)

a = Entry(textvariable=text,
          validate='focusout',
          validatecommand=(vcmd, '%P'),
          invalidcommand=(ivcmd,))
a.pack()

b = Entry()
b.pack()

root.mainloop()

Using class: 使用类:

from tkinter import *
from tkinter.ttk import *

class FloatEntry(Entry):

    def __init__(self, *args, **kwargs):
        initial_value = kwargs.pop('initial_value', '100.00')
        assert self.validate(initial_value), 'Invalid initial_value given'
        self.last_valid_value = initial_value
        self.text = StringVar(value=initial_value)

        Entry.__init__(self, *args, textvariable=self.text, **kwargs)
        self.vcmd = self.register(self.validate)
        self.ivcmd = self.register(self.invalidate)
        self['validate'] = 'focusout'
        self['validatecommand'] = self.vcmd, '%P',
        self['invalidcommand'] = self.ivcmd,

    def validate(self, inp):
        try:
            float(inp)
        except ValueError:
            return False
        self.last_valid_value = inp
        return True

    def invalidate(self):
        self.text.set(self.last_valid_value)

root = Tk()
FloatEntry(initial_value='100.0').pack()
Entry().pack()
root.mainloop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM