如何获得此验证代码来限制字符长度并只允许数字



我正在为我的申请创建一个出生日期输入表,并希望使其只能输入数字,并将输入的数字限制在所需的最大数量,例如每天2个。当我尝试实现这个时,它甚至不允许我在入口小部件中做任何事情。如何限制字符长度并只接受数字?

def onlyNumbers(char):
if (len(dayE.get()) >= 2):
return False
elif (len(monthE.get()) >= 2):
return False
elif (len(yearE.get()) >= 4):
return False
elif (char is ""):
return True
else:
return char.isdigit()
dayV = tk.StringVar(self, value = "DD")
monthV = tk.StringVar(self, value = "MM")
yearV = tk.StringVar(self, value = "YYYY")
validation = self.register(onlyNumbers)
dayE = tk.Entry(self, font = BASIC_FONT, textvariable = dayV, width = 5, justify = "center")
dayE.pack()
dayE.config(validate = "key", validatecommand = (validation, "%P"))
monthE = tk.Entry(self, font = BASIC_FONT, textvariable = monthV, width = 5, justify = "center")
monthE.pack()
monthE.config(validate = "key", validatecommand = (validation, "%P"))
yearE = tk.Entry(self, font = BASIC_FONT, textvariable = yearV, width = 5, justify = "center")
yearE.pack()
yearE.config(validate = "key", validatecommand = (validation, "%P"))

问题Entry验证,以限制字符长度并只允许数字

此示例实现:

  • 只允许输入数字
  • 根据'DD', 'MM', 'YYYY'限制位数
  • 根据位数自动'<Tab>'
  • 允许在'DD', 'MM'中使用前导零
  • 只允许数字范围1, 311, 12和参数years=(<from>, <to>)
  • 将编辑后的数据返回为:{'month': 3, 'day': 28, 'year': 2020}

参考

  • 验证

    Validation的工作原理是将validatecommand=选项设置为脚本(validateCommand(,该脚本将根据validate=选项进行评估
    所用百分比取代('%W', '%V', '%v', '%P', '%S'(的说明

  • SO:交互验证tkinter 中的入口窗口小部件内容

    注意那里的注释
    注意:验证命令返回TrueFalse非常重要。任何其他操作都会导致验证关闭。


注意
如果使用.insert(....delete(...<textvariable>.set(...)更改了Entry文本,则验证将关闭。


import tkinter as tk

class DateEntry(tk.Frame):
def __init__(self, parent, **kwargs):
years = kwargs.pop('years', (1900, 9999))
super().__init__(parent, **kwargs)

vcmd = (self.register(self._validate), '%W', '%V', '%v', '%P', '%S')
for name, text, v1, v2 in (('day', 'DD', 1, 31),
('month', 'MM', 1, 12),
('year', 'YYYY', years[0], years[1])):
e = tk.Entry(self, name=name, width=len(text) + 1, justify="center")
e.pack(side=tk.LEFT)
e.insert(0, text)
e._valid = (len(text), v1, v2)
e.config(validate="all", validatecommand=vcmd)

def get(self):
data = {}
for entry in [self.nametowidget(child) for child in self.children]:
text = entry.get()
data[entry.winfo_name()] = int(text) if text.isdigit() else None
return data
def _validate(self, widget, cmd, validate, value, text):
# get this entry reference
w = self.nametowidget(widget)
# Clear entry or do nothing
if cmd in ('focusin', 'forced') or value == '':
if not value.isdigit():
w.delete(0, tk.END)
# Set the 'validate' option again after edit
w.after_idle(w.config, {'validate': validate})
return True
# process key
elif cmd == 'key' and value.isdigit():
# get from this entry the valid parameter
l, v1, v2 = w._valid

# get the startswith chars if YYYY
if v1 > 1 and len(value) < l:
l2 = len(value)
v1, v2 = int(str(v1)[:l2]), int(str(v2)[:l2])
# allow leading zero in DD / MM
elif v1 == 1 and len(value) == 1 and int(value) == 0:
return True
# return True if all valid else False
valid = all((text.isdigit(), v1 <= int(value) <= v2, len(value) <= l))
if valid and len(value) == l:
self.event_generate('<Tab>', when='tail')
return valid
# else return False
return False

用法

class App(tk.Tk):
def __init__(self):
super().__init__()
tk.Button(self, text='print date', command=self.print_date).grid()

self.date_entry = DateEntry(self, years=(2000, 2020))
self.date_entry.grid()

def print_date(self):
print('print_date: {}'.format(self.date_entry.get()))
# >>> print_date: {'month': 3, 'day': 28, 'year': 2020}

if __name__ == "__main__":
App().mainloop()

用Python测试:3.5-"TclVersion":8.6"TkVersion":8.6

相关内容

  • 没有找到相关文章

最新更新