Tkinter:限制条目数据浮动

时间:2017-09-08 11:59:34

标签: python tkinter

我需要一个将用户输入限制为数值的函数。 我一直在寻找答案,但我发现的答案不允许' - ',' +'和','(逗号)。 这是验证方法的代码:

   def __init__(self, master1):
    self.panel2 = tk.Frame(master1)
    self.panel2.grid()
    vcmd = (master1.register(self.validate),
            '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
    self.text1 = tk.Entry(self.panel2, validate = 'key', validatecommand = vcmd)
    self.text1.grid()
    self.text1.focus()



def validate(self, action, index, value_if_allowed,
    prior_value, text, validation_type, trigger_type, widget_name):
    # action=1 -> insert
    if(action=='1'):
        if text in '0123456789,-+':
            try:
                float(value_if_allowed)
                return True
            except ValueError:
                return False
        else:
            return False
    else:
        return True

同样,这似乎只适用于数字,但限制逗号和加号和减号,这不是预期的。 怎么能修好?

1 个答案:

答案 0 :(得分:2)

正确的工具绝对是re模块。

这是一个应该完成工作的正则表达式:

(\+|\-)?\d+(,\d+)?$

让我们分解一下:

(\+|\-)?\d+(,\d+)?$

 \+|\-                  Starts with a + or a -...
(     )?                ... but not necessarily
        \d+             Contains a repetition of at least one digits
            ,\d+        Is followed by a comma and at least one digits...
           (    )?      ... but not necessarily
                  $     Stops here: nothing follows the trailing digits

现在,如果输入与正则表达式匹配,则validate函数只需返回True,如果不符合,则False

def validate(string):
    result = re.match(r"(\+|\-)?\d+(,\d+)?$", string)
    return result is not None

一些测试:

# Valid inputs
>>> validate("123")
True
>>> validate("123,2")
True
>>> validate("+123,2")
True
>>> validate("-123,2")
True

# Invalid inputs
>>> validate("123,")
False
>>> validate("123,2,")
False
>>> validate("+123,2,")
False
>>> validate("hello")
False

修改

我现在明白,如果输入有效,您想要实时检查。 所以这是你可以做的一个例子:

import tkinter as tk
import re

def validate(string):
    regex = re.compile(r"(\+|\-)?[0-9,]*$")
    result = regex.match(string)
    return (string == ""
            or (string.count('+') <= 1
                and string.count('-') <= 1
                and string.count(',') <= 1
                and result is not None
                and result.group(0) != ""))

def on_validate(P):
    return validate(P)    

root = tk.Tk()
entry = tk.Entry(root, validate="key")
vcmd = (entry.register(on_validate), '%P')
entry.config(validatecommand=vcmd)
entry.pack()
root.mainloop()

validate函数现在或多或少地检查相同的东西,但更松散。 然后,如果正则表达式导致匹配,则执行一些额外的检查:

  • 允许输入为空;
  • 防止输入有多个'+' / '-'和多个',';
  • 忽略与空字符串的匹配,因为该模式允许匹配,因此"a"会导致匹配但我们不想要它。

该命令已注册,并使用'%P'参数,如果输入被接受,则该参数对应于字符串。

但请不要强制输入始终正确有点苛刻,可能违反直觉。 更常用的方法是更新条目旁边的字符串,并让用户知道输入有效或无效。