Summary: in this tutorial, you’ll learn how to use the Tkinter validation to validate user inputs.
Introduction to the Tkinter validation
Tkinter validation relies on the three options that you can use for any input widget such as Entry
widget:
validate
: specifies which type of event will trigger the validation.validatecommand
: checks if a data is validinvalidcommand
: executes when the data is invalid. In other words, it’ll execute if thevalidatecommand
returnsFalse
.
validate
The validate
command can be one of the following string values:
‘focus’ | Validate whenever the widget gets or loses focus |
‘focusin’ | Validate whenever the widget gets focus. |
‘focusout’ | Validate whenever the widget loses focus |
‘key’ | Validate whenever any keystroke changes the widget’s contents. |
‘all’ | Validate in all the above situations focusing, focusout, and key |
‘none’ | Turn the validation off. This is the default. Please note that the string 'none' is not the None value in Python. |
validatecommand
The validatecommand
is a tuple that contains:
- A reference to a Tcl/tk function.
- Zero or more substitution codes specify the information that triggers the event you want to pass into the function.
To get a reference to a Tck/tk function, you pass a callable to the widget.register()
method. It returns a string that you can use with the validatecommand
.
The following table shows the substitution codes that you can use with the tuple:
%d' | Action code: 0 for an attempted deletion, 1 for an attempted insertion, or -1 if the callback was called for focus in, focus out, or a change to the textvariable . |
'%i' | When the user attempts to insert or delete text, this argument will be the index of the beginning of the insertion or deletion. If the callback was due to focus in, focus out, or a change to the textvariable , the argument will be -1 . |
'%P' | The value that the text will have if the change is allowed. |
'%s' | The text in the entry before the change. |
'%S' | If the call was due to an insertion or deletion, this argument will be the text being inserted or deleted. |
'%v' | The current value of the widget’s validate option. |
'%V' | The reason for this callback: one of 'focusin' , 'focusout' , 'key' , or 'forced' if the textvariable was changed. |
'%W' | The name of the widget. |
The following example constructs a validatecommand
that use the self.validate()
method and %P
substitution code:
vcmd = (self.register(self.validate), '%P')
Code language: Python (python)
invalidcommand
Like the validatecommand
, the invalidcommand
also requires the use of the widget.register()
method and substitution code.
The following example returns a tuple that you can pass into the invalidcommand
option:
ivcmd = (self.register(self.on_invalid),)
Code language: Python (python)
Tkinter validation example
We’ll create a form that contains an email input. If you enter an invalid email address, it’ll show an error message and change the text color of the email input to red. And we’ll trigger the validation event when the focus is moving out of the entry.
Here’s the complete program:
import tkinter as tk
from tkinter import ttk
import re
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title('Tkinter Validation Demo')
self.create_widgets()
def create_widgets(self):
self.columnconfigure(0, weight=1)
self.columnconfigure(1, weight=3)
self.columnconfigure(2, weight=1)
# label
ttk.Label(text='Email:').grid(row=0, column=0, padx=5, pady=5)
# email entry
vcmd = (self.register(self.validate), '%P')
ivcmd = (self.register(self.on_invalid),)
self.email_entry = ttk.Entry(self, width=50)
self.email_entry.config(validate='focusout', validatecommand=vcmd, invalidcommand=ivcmd)
self.email_entry.grid(row=0, column=1, columnspan=2, padx=5)
self.label_error = ttk.Label(self, foreground='red')
self.label_error.grid(row=1, column=1, sticky=tk.W, padx=5)
# button
self.send_button = ttk.Button(text='Send').grid(row=0, column=4, padx=5)
def show_message(self, error='', color='black'):
self.label_error['text'] = error
self.email_entry['foreground'] = color
def validate(self, value):
"""
Validat the email entry
:param value:
:return:
"""
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
if re.fullmatch(pattern, value) is None:
return False
self.show_message()
return True
def on_invalid(self):
"""
Show the error message if the data is not valid
:return:
"""
self.show_message('Please enter a valid email', 'red')
if __name__ == '__main__':
app = App()
app.mainloop()
Code language: Python (python)
How it works.
First, create a validate command using the self.validate()
method and %P
substitution code:
vcmd = (self.register(self.validate), '%P')
Code language: Python (python)
Second, create the invalidatecommand
that uses the self.on_invalid
method:
ivcmd = (self.register(self.on_invalid),)
Code language: Python (python)
Third, configure the entry widget that uses validation
, validatecommand
, and invalidatecommand
:
self.email_entry.config(validate='focusout', validatecommand=vcmd, invalidcommand=ivcmd)
Code language: Python (python)
Fourth, define the show_message()
method that changes the text of the label_error
widget and the text color of the email_entry
widget:
def show_message(self, error='', color='black'):
self.label_error['text'] = error
self.email_entry['foreground'] = color
Code language: Python (python)
Fifth, define the validate()
method that validates the value of the email_entry
.
def validate(self, value):
"""
Validat the email entry
:param value:
:return:
"""
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
if re.fullmatch(pattern, value) is None:
return False
self.show_message()
return True
Code language: Python (python)
The validate()
method returns True
if the input text is valid or False
otherwise. In case the input text is a valid email address, call the show_message()
to hide the error message and set the text color to black.
Tkinter will execute the on_invalid()
method if the input text is not a valid email address.
Finally, define the on_invalid()
method that shows an error message and set the text color of the email_entry
widget to red.
def on_invalid(self):
"""
Show the error message if the data is not valid
:return:
"""
self.show_message('Please enter a valid email', 'red')
Code language: Python (python)
Summary
- Tkinter uses the
validate
,validatecommand
, andinvalidcommand
options on any input widget to validate data. - Pass a callable to the
widget.register()
method to create a command for thevalidatecommand
andinvalidcommand
options. validationcommand
returnsTrue
if the data is valid orFalse
otherwise.invalidcommand
will execute if the data is not valid, or when thevalidatecommand
returnFalse
.