質問

Part of my program asks the user for their name and class (as in high school class). In the first text entry I would like the program to only accept a name of say no more than 10 characters but more importantly LETTERS ONLY. For the second text entry the user has to enter their class - the program should expect one of the following: 5A1, 5A2, 5B1, 5B2, 5C1, 5C2 ... 6C1, 6C2.

How to do these validations?

class Enter_Name_Window(tk.Toplevel):
'''A simple instruction window'''
def __init__(self, parent):
    tk.Toplevel.__init__(self, parent)
    self.text = tk.Label(self, width=40, height=2, text= "Please enter your name and class." )
    self.text.pack(side="top", fill="both", expand=True)


    name_var = StringVar()
    def validate_enter_0():
        self.Enter_0.config(state=(NORMAL if name_var.get() else DISABLED))
        print("validate enter worked")
    name_var.trace('w', lambda name, index, mode: validate_enter_0)
    enter_name = Entry(self, textvariable=name_var)
    enter_name.pack()
    enter_name.focus_set()


    def callback():
        self.display_name = tk.Label(self, width=40, height=2, text = "Now please enter your tutor group.")
        self.display_name.pack(side="top", fill="both", expand=True)


        tutor_var = StringVar()
        def validate_enter_2():
            self.Enter_0_2.config(state=(NORMAL if tutor_var.get() else DISABLED))
            print("validate enter worked")
        tutor_var.trace('w', lambda name, index, mode: validate_enter_0_2)
        tutor = Entry(self, textvariable=tutor_var)
        tutor.pack()
        tutor.focus_set()

        self.Enter_0.config(state="disabled")

        self.Enter_0_2 = Button(self, text="Enter", width=10, command=self.destroy)
        self.Enter_0_2.pack()


    self.Enter_0 = Button(self, text="Enter", width=10, command=callback)
    self.Enter_0.pack()
役に立ちましたか?

解決

For your first check

import string

if len(name) > 10 or any(l not in string.ascii_letters for l in name):
    # reject

for your second

if cls not in ["5A1", "5A2", ...]:
    # reject

or you could do something a bit more complex:

def validate_class(cls):
    if (len(cls) != 3 or 
        int(cls[0]) not in [5, 6] or
        cls[1] not in ["A", "B", "C"] or 
        int(cls[2]) not in [1, 2]):
        return False
    return True

This expresses a more general rule for what a valid class cls is.

他のヒント

The entry widget has built-in validation which works better than variable traces. See this answer for an example:

https://stackoverflow.com/a/4140988/7432

The basic concept is that you specify a callback for whenever the widget is modified. The validation feature can send the callback all sorts of useful information such as the character being inserted (or deleted), what the value is before the insertion or deletion, the value after, etc. You can use this information to decide whether to allow the modification or not -- if the callback returns False, the input will be rejected.

You can do other things in this callback as well, such as enabling or disabling buttons.

The advantage to doing this versus tracing a text variable is simply that the built-in validation gives you a lot of information on which to make a decision, and happens before the variable is changed rather than after.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top