如何在python中验证条目小部件?

2024-03-28 16:51:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Tkinter创建一个GUI,用于从用户那里收集信息。我需要验证:

  • 名字和姓氏只包含字母、撇号和破折号
  • 地址
  • 电话号码的位数正确
  • 有效生日(2月31日不存在,出生年份在1900年至2014年之间)
  • 包含“@”和“@”

这是我的代码:

from tkinter import *
import datetime

class tkwindow:

def __init__(self):

    window = Tk() # Create window
    window.title("Contact Form") # Give window a title

    menubar = Menu(window) # Create menu bar
    window.config(menu = menubar) # Display menu bar

    '''Using the pulldown menu allows easier access to the menu items instead of using a pop-up menu '''

    # Create pulldown menu and add to menu bar
    messagesMenu = Menu(menubar, tearoff = 0)
    menubar.add_cascade(label = "Messages", menu = messagesMenu)
    messagesMenu.add_command(label = "Send a Birthday Greeting", command = self.bdayGreeting)
    messagesMenu.add_command(label = "Print Address", command = self.printAddress)

    # Create another menu option
    endMenu = Menu(menubar, tearoff = 0)
    menubar.add_cascade(label = "End", menu = endMenu)
    endMenu.add_command(label = "Reset Form", command = self.resetForm)
    endMenu.add_command(label = "Exit Program", command = window.quit)

    # Using Label widget
    labelFirst = Label(window, text = "First Name: ").grid(row = 1, column = 1, sticky = E)
    labelLast = Label(window, text = "Last Name: ").grid(row = 2, column = 1, sticky = E)
    labelAddress = Label(window, text = "Address: ").grid(row = 3, column = 1, sticky = E)
    labelPhone = Label(window, text = "Phone Number (8005551234): ").grid(row = 4, column = 1, sticky = E)
    labelBday = Label(window, text = "Birthday (MM/DD/YYYY): ").grid(row = 5, column = 1, sticky = E)
    labelEmail = Label(window, text = "Email Address (user@domain.com): ").grid(row = 6, column = 1, sticky = E)

    # Using Entry widget
    self.firstName = StringVar()
    entryFirst = Entry(window, textvariable = self.firstName, justify = LEFT).grid(row = 1, column = 2, sticky = W)

    self.lastName = StringVar()
    entryLast = Entry(window, textvariable = self.lastName, justify = LEFT).grid(row = 2, column = 2, sticky = W)

    self.address = StringVar()
    entryAddress = Entry(window, textvariable = self.address, justify = LEFT).grid(row = 3, column = 2, sticky = W)

    self.phone = StringVar()
    entryPhone = Entry(window, textvariable = self.phone, justify = LEFT).grid(row = 4, column = 2, sticky = W)

    self.bday = StringVar()
    entryBday = Entry(window, textvariable = self.bday, justify = LEFT).grid(row = 5, column = 2, sticky = W)

    self.email = StringVar()
    entryEmail = Entry(window, textvariable = self.email, justify = LEFT).grid(row = 6, column = 2, sticky = W)

    self.errorLblFirst = Label(window, fg = "red")
    self.errorLblFirst.grid(row = 1, column = 3)

    self.errorLblLast = Label(window, fg = "red")
    self.errorLblLast.grid(row = 2, column = 3)

    self.errorLblAddress = Label(window, fg = "red")
    self.errorLblAddress.grid(row = 3, column = 3)

    self.errorLblPhone = Label(window, fg = "red")
    self.errorLblPhone.grid(row = 4, column = 3)

    self.errorLblBday = Label(window, fg = "red")
    self.errorLblBday.grid(row = 5, column = 3)

    self.errorLblEmail = Label(window, fg = "red")
    self.errorLblEmail.grid(row = 6, column = 3)

    # Using Button widget
    buttonSubmit = Button(window, text = "Submit", command = self.submit).grid(row = 7, column = 2, sticky = E)

    window.mainloop()

def resetForm(self):

    self.firstName.set('')
    self.errorLblFirst["text"] = ''
    self.lastName.set('')
    self.errorLblLast["text"] = ''
    self.address.set('')
    self.errorLblAddress["text"] = ''
    self.phone.set('')
    self.errorLblPhone["text"] = ''
    self.bday.set('')
    self.errorLblBday["text"] = ''
    self.email.set('')
    self.errorLblEmail["text"] = ''

def validFirst(self):

    for letter in self.firstName.get():
        if not letter.isalpha() and letter not in "'-":
            self.errorLblFirst["text"] = " * Letters, apostrophes('), and hypens(-) only"
            return False

    return True

def validLast(self):

    for letter in self.lastName.get():
        if not letter.isalpha() and letter not in "'-":
            self.errorLblLast["text"] = " * Letters, apostrophes('), and hypens(-) only"
            return False

    return True

def validAddress(self):

    for letter in self.address.get():
        if not letter.isalnum() and letter not in "'- .,":
            self.errorLblAddress["text"] = " * No special characters"
            return False

    return True

def validPhone(self):

    D = 0

    for number in self.phone.get():
        if number.isdigit():
            D += 1
        if D == 10:
            return True
        else:
            self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
            return False

    return True

def validBday(self):

    '''try:
        valid_date = datetime.datetime.strptime(str(self.bday), '%m/%d/%Y')
    except ValueError:
        print('Invalid date!')'''
    return True

def validEmail(self):

    for letter in self.email.get():
        if not letter.isalnum() and letter not in "@.":
            self.errorLblEmail["text"] = " * Must have @ and ."
            return False

    return True

def bdayGreeting(self):
    if self.validBday() and self.validFirst() == True:
        print("Happy Birthday" + self.firstName.get() + "\n" + self.bday.get())

def printAddress(self):
    if self.validFirst() and self.validLast() and self.validAddress() == True:
        print(self.firstName.get() + " " + self.lastName.get() + "\n" + self.address.get())


def submit(self):
    self.validFirst()
    self.validLast()
    self.validAddress()
    self.validPhone()
    self.validBday()
    self.validEmail()

tkwindow()

我有几个问题。在

  1. 从def validFirst(self)开始,如何验证不同的输入字段?当我修改代码时,我一直得到NameError: name "asdf" is not definedSyntaxError: unexpected EOF while parsing,和{},但我仍然坚持validFirst(self)。在
  2. 我在第3列中为错误消息保留了一组标签:errorLblFirst = Label(window, text = " ", fg = "red").grid(row = 1, column = 3)。当对该条目的验证失败时,是否可以将其设置为" * Invalid Entry", fg = "red"?有没有其他方法可以显示错误消息?在

提前感谢您的投入!在

编辑:我更新了我的最新代码。除了validBday和{}之外,大多数验证现在都可以工作了,如果您可以检查的话。在


Tags: andtextselfgetreturndefcolumnwindow
1条回答
网友
1楼 · 发布于 2024-03-28 16:51:12
errorLblFirst = Label(...).grid(...)

这样您就可以将grid()的结果赋给errorLblFirst,但是grid()总是返回{}

总是这样做

^{pr2}$

现在你可以做了(例如)

errorLblFirst["text"] = " * Invalid Entry"
errorLblFirst["fg"] = "red"

编辑:

你把len()忘在for i in range(first):里了validFirst() 你不需要eval()。 (您在validPhone()中遇到了相同的问题)

F = 0

fName = True

first = self.firstName.get() # without eval()

for i in range(len(first)): # len()
    if first[i].isdigit():
        F += 1
    if F > 0:
        return False
    else:
       return fName

return fName

但你可以做得短一点

for letter in self.firstName.get():
    if letter.isdigit():
        return False

return True

如果你只需要字母(没有空格、逗号等),你可以这样做

return self.firstName.get().isalpha()

编辑:

我看名字可以有撇号和破折号

for letter in self.firstName.get():
    if not letter.isalpha() and letter not in "'-":
        return False

return True

编辑:self.phoneStringVar有关的问题

self.phoneStringVar()-不是{} 但是StringVar()有{}来得到{}

for number in range(len( self.phone.get() )): 

顺便说一句:你可以做for循环更多的python-而不使用range(len())

for char in self.phone.get(): 
    if char.isdigit():     

编辑:validEmail()validBday()有关的问题

电子邮件验证需要更多if。在

例如,您可以添加

email = self.email.get()
if '@' not in email and '.' not in email::
    print( 'email needs @ and . at the same time')

但是“@”将通过此测试:/

真正的电子邮件验证要复杂得多。在

请参阅有效的电子邮件示例:https://fightingforalostcause.net/content/misc/2006/compare-email-regex.php


self.bdayStringVar-使用self.bday.get()代替{}


编辑:

def validPhone(self):

    D = 0

    for number in self.phone.get():
        if number.isdigit():
            D += 1

    # outside 

    if D == 10:
        return True
    else:
        self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
        return False

    return True

甚至是

def validPhone(self):

    # remove previous error message
    self.errorLblPhone["text"] = ""

    D = 0

    for number in self.phone.get():
        if number.isdigit():
            D += 1

    if D != 10:
        self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
        return False

    return True

如果数字只能有10位数字(无空格、无-等):

def validPhone(self):

    # remove previous error message
    self.errorLblPhone["text"] = ""

    D = True

    for number in self.phone.get():
        if not number.isdigit():
            D = False
            break  

    if not D or len(number) != 10:
        self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
        return False

    return True

相关问题 更多 >