【问题标题】:Python Input Validation for Spacebar and Backspace空格键和退格键的 Python 输入验证
【发布时间】:2018-04-03 00:40:58
【问题描述】:

我已经为 GUI 编写了一个代码,它允许我在 3 个条目小部件中输入电话号码,并在一个单独的小部件中将整个电话号码返回到侧面。我已经设法使用输入验证来限制可以输入到每个小部件中的字符数,并将它们限制为仅数字,但是存在一些问题。

一旦第一个数字输入到每个条目中,该数字就不能用退格键删除,同样在第一个条目之后,空格键可以填充每个条目中的剩余空间。如何验证空格键(空格?)的使用,并允许退格键删除 Entry 小部件的所有内容?

代码如下:

import tkinter as tk

window=tk.Tk()
window.geometry('325x75+750+350')
window.resizable(width=False,height=False)
window.title('Phone Number Test')

var=tk.StringVar(window,'')

def entrycheckone(inp):
    try:
        int(inp)
        if len(inp) == 3:
            entry2.focus_set()
            return True
        elif len(inp)<3:
            return True
        else:
            return False
        return True
    except:
        return False

def entrychecktwo(inp):
    try:
        int(inp)
        if len(inp) == 3:
            entry3.focus_set()
            return True
        elif len(inp) < 3:
            return True
        else:
            return False
        return True
    except:
        return False

def entrycheckthree(inp):
    try:
        int(inp)
        if len(inp) == 4:
            button1.focus_set()
            return True
        elif len(inp) < 4:
            return True
        else:
            return False
        return True
    except:
        return False


label1=tk.Label(text='Enter Phone Number(XXX-XXX-XXXX):', font='arial 10 bold')
label1.place(anchor='nw', x=38, y=3)

entry1=tk.Entry(width=3, font='arial 10 bold')
entry1.place(anchor='nw', x=3, y=30)
entry1.focus_set()

max1 = window.register(entrycheckone)
entry1.config(validate='key', validatecommand=(max1,'%P'))

label2=tk.Label(text='-', font='arial 20')
label2.place(anchor='nw', x=30, y=19)

entry2=tk.Entry(width=3, font='arial 10 bold')
entry2.place(anchor='nw', x=47, y=30)

max2 = window.register(entrychecktwo)
entry2.config(validate='key', validatecommand=(max2,'%P'))

label3=tk.Label(text='-', font='arial 20')
label3.place(anchor='nw', x=73, y=19)

entry3=tk.Entry(width=4, font='arial 10 bold')
entry3.place(anchor='nw', x=90, y=30)

max3 = window.register(entrycheckthree)
entry3.config(validate='key',validatecommand=(max3, '%P'))

display1=tk.Entry(width=13, textvariable=var, font='arial 10 bold',state='disabled')
display1.place(anchor='nw', x=200, y=30)

def setphone():
    num1 = entry1.get()
    num2 = entry2.get()
    num3 = entry3.get()
    wholenum = ('(' + num1 + ')-' + num2 + '-' + num3)
    print(wholenum)
    var.set(wholenum)

button1=tk.Button(text='ENTER', font='arial 10 bold', command=setphone)
button1.place(anchor='nw', x=130, y=26)

window.mainloop()

另外,使用类可以更轻松地完成所有三个的验证吗?我试过了,但失败了。

谢谢。

迈克

【问题讨论】:

  • 不确定是什么给您带来了麻烦...检查字符串是否包含空格或长度为 0 个字符有什么困难?
  • 问题是我以开飞机为生,没有上过计算机编程的学校。对我来说,这是我一个半星期前才开始的爱好。我意识到这个网站并不适合刚接触编码的人,但我会很感激有建设性的、有用的答案。谢谢。
  • 我想知道如何将附加功能添加到当前验证中。

标签: python validation input tkinter


【解决方案1】:

您应该做的第一件事是将三个几乎相同的entrycheck 函数变成一个函数。他们都做同样的事情,只是价值观不同。显而易见的解决方案是将这些值作为参数。

def entrycheckinp, length, focus_widget):
    try:
        int(inp)
        if len(inp) == length:
            focus_widget.focus_set()
            return True
        elif len(inp) < length:
            return True
        else:
            return False
        return True
    except:
        return False

这样做的问题是 tkinter 只会将一个参数传递给这个函数。在让 tkinter 调用此函数之前,我们需要找到一种方法来包含其他 2 个参数的值。使用functools.partial 很容易做到这一点。使用它,我们可以重写

max1 = window.register(entrycheckone)
max2 = window.register(entrychecktwo)
max3 = window.register(entrycheckthree)

from functools import partial
max1 = window.register(partial(entrycheck, length=3, focus_widget=entry2))
max2 = window.register(partial(entrycheck, length=3, focus_widget=entry3))
max3 = window.register(partial(entrycheck, length=4, focus_widget=button1))

(在执行此操作之前,您必须先创建所有小部件entry2entry3button1,否则会出现 NameError。)


除此之外,我们现在可以重写该函数以接受空字符串并拒绝空格。

def entrycheck(inp, length, focus_widget):
    if ' ' in inp:  # don't accept spaces
        return False
    try:
        int(inp)
        if len(inp) == length:
            focus_widget.focus_set()
            return True
        elif len(inp)<length:
            return True
        else:
            return False
        return True
    except:
        return inp == ''  # accept non-numeric input if it's the empty string

【讨论】:

  • 非常感谢,就像一个魅力!很高兴我现在知道部分模块!
  • 作为后续问题,* return inp == ' ' * 究竟如何允许删除最后一个字符?我对此有点模糊。
  • @MichaelSibille 好吧,如果验证函数返回 True,则 tkinter 接受输入,所以......如果输入为空,则返回 True,否则返回 False。 (请记住,只有在输入不是有效数字时才会到达该代码分支,因此不是空字符串的 所有 输入都是无效的。)
  • 哦!明白了!感谢您的解释!
猜你喜欢
  • 1970-01-01
  • 2018-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-10
相关资源
最近更新 更多