Validating user input

Let's discuss input data validation in Tkinter.

Most of the applications that we have developed in our book are point-and-click-based (the drum machine, the chess game, and the drawing application), where a validation of user input is not required. However, data validation is a must in programs such as the phone book application, where a user enters some data and we store it in a database.

Ignoring user input validation can be dangerous in such applications because input data can be misused for SQL injection. In general, an application in which a user can enter textual data is a good candidate for the validation of user input. In fact, not trusting user inputs is almost considered a maxim.

Wrong user inputs may be intentional or accidental. In either case, if you fail to validate or sanitize data, unexpected errors may occur in your program. In a worst-case scenario, user input can be used to inject harmful code that may be capable of crashing a program or wiping out an entire database.

Widgets, such as Listbox, Combobox, and Radiobuttons, allow limited input options and hence, they normally cannot be misused to input wrong data. On the other hand, widgets such as the Entry widget, the Spinbox widget, and the Text widget allow a large possibility of user inputs, and hence, they need to be validated for correctness.

To enable validation on a widget, you need to specify an additional option of the validate = 'validationmode' form to the widget.

For example, if you want to enable validation on an Entry widget, you begin by specifying the validate option, as follows:

Entry( root, validate="all", validatecommand=vcmd)

Validation can occur in one of the following validation modes:

Validation Mode Explanation

none

This is the default mode. No validation occurs if validate is set to none.

focus

When validate is set to focus, the validate command is called twice—once when the widget receives focus, and once when the focus is lost.

focusin

The validate command is called when the widget receives focus.

focusout

The validate command is called when the widget loses focus.

key

The validate command is called when the entry is edited.

all

The validate command is called in all the aforementioned cases.

The 10.03_validation_mode_demo.py code file demonstrates all of these validation modes by attaching them to a single validation method. In the code, note the different ways in which different Entry widgets respond to different events. Some Entry widgets call the validation method on the focus events, others call the validation method at the time of entering keystrokes into a widget, and still others use a combination of the focus and key events.

Although we did set the validation mode to trigger the validate method, we need some data to validate against the rules. This is passed to the validate method using percent substitution. For instance, we passed the mode as an argument to the
validate method by performing a percent substitution on the validate command, as demonstrated in the following command:

vcmd = (self.root.register(self.validate_data), '%V')

This was followed by passing the value of v as an argument to the validate method:

def validate_data(self, v)

In addition to %V, Tkinter recognizes the following percent substitutions:

Percent substitutions Explanation

%d

The type of action that is performed on a widget (1 for insert, 0 for delete, and -1 for a focus, forced, or textvariable validation).

%i

The index of the char string that is inserted or deleted, if any. Otherwise, it will be -1.

%P

The value of the entry in case the edit is allowed. If you are configuring the Entry widget to have a new textvariable, this will be the value of that textvariable.

%s

The current value of the entry prior to editing.

%S

The text string being inserted or deleted if any. Otherwise, {}.

%v

The type of validation that has been currently set.

%V

The type of validation that triggers the callback method (key, focusinfocusout, and forced).

%W

The name of the Entry widget.

 

These substitution values provide us with the necessary data to validate the input.

Let's pass all of these values and just print them through a dummy validate method just to see what kind of data that we can expect to get on carrying out the validations (see the 10.04_percent_substitutions_demo.py code):

class PercentSubstitutionsDemo():

def __init__(self):
self.root = tk.Tk()
tk.Label(text='Type Something Below').pack()
vcmd = (self.root.register(self.validate), '%d', '%i', '%P', '%s',
'%S', '%v', '%V', '%W'
)
tk.Entry(self.root, validate="all", validatecommand=vcmd).pack()
self.root.mainloop()

def validate(self, d, i, P, s, S, v, V, W):
print("Following Data is received for running our validation checks:")
print("d:{}".format(d))
print("i:{}".format(i))
print("P:{}".format(P))
print("s:{}".format(s))
print("S:{}".format(S))
print("v:{}".format(v))
print("V:{}".format(V))
print("W:{}".format(W))
# returning true for now
# in actual validation you return true if data is valid
# else return false
return True

Note the line where we register a validate method by passing all the possible percent substitutions to the callback.

Take particular note of the data returned by %P and %s because they pertain to the actual data entered by the user in the Entry widget. In most cases, you will be checking either of these two data sources against the validation rules.

Now that we have a background of rules for data validation, let's have a look at two practical examples that demonstrate input validation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.126.199