Валидация Tkinter в Python: параметры и примеры

Рассмотрим, как использовать валидацию Tkinter для проверки введенных пользователем данных в Python.

Содержание

Что такое валидация Tkinter

Проверка (валидация) Tkinter основана на трех параметрах, которые можно использовать для любого виджета ввода, например виджета Entry:

  • validate: указывает, какой тип события вызовет проверку.
  • validatecommand: проверяет, являются ли данные действительными
  • invalidcommand: выполняется, когда данные недействительны. Другими словами, он будет выполнен, если validatecommand вернет False.

validate

Команда validate может иметь одно из следующих строковых значений:

‘focus’ Проверять каждый раз, когда виджет получает или теряет фокус.
‘focusin’ Проверять каждый раз, когда виджет получает фокус.
‘focusout’ Проверять каждый раз, когда виджет теряет фокус.
‘key’ Проверять, когда нажатие клавиши изменяет содержимое виджета.
‘all’ Проверьте во всех вышеперечисленных ситуациях focusing, focusout и key
‘none’ Отключить проверку. Это значение по умолчанию. Обратите внимание, что строка ‘none’ не является значением None в Python.

validatecommand

Команда validatecommand — это кортеж, содержащий:

  • Ссылка на функцию Tcl/tk.
  • Ноль или более кодов подстановки указывают информацию, которая запускает событие, которое вы хотите передать в функцию.

Чтобы получить ссылку на функцию Tck/tk, вы передаете вызываемый метод widget.register(). Он возвращает строку, которую можно использовать с командой validatecommand.

В следующей таблице показаны коды подстановки, которые можно использовать с кортежем:

%d’ Код действия: 0 для попытки удаления, 1 для попытки вставки или -1, если обратный вызов был вызван для установки фокуса, снятия фокуса или изменения текстовой переменной.
‘%i’ Когда пользователь пытается вставить или удалить текст, этот аргумент будет индексом начала вставки или удаления. Если обратный вызов был вызван focusing, focusout или изменением textvariable, аргумент будет равен -1.
‘%P’ Значение, которое будет иметь текст, если изменение разрешено.
‘%s’ Текст в записи до изменения.
‘%S’ Если вызов был вызван вставкой или удалением, этим аргументом будет текст, который вставляется или удаляется.
‘%v’ Текущее значение параметра проверки виджета.
‘%V’ Причина этого обратного вызова: одна из следующих: «focusin», «focusout», «key» или «forced», если textvariable была изменена.
‘%W’ Название виджета.

В следующем примере создается команда validatecommand, которая использует метод self.validate() и код подстановки %P:

vcmd =(self.register(self.validate), '%P')

invalidcommand

Как и команда validatecommand, команда invalidcommand также требует использования метода widget.register() и кода подстановки.

Следующий пример возвращает кортеж, который можно передать в параметр invalidcommand:

ivcmd =(self.register(self.on_invalid),)

Пример валидации Tkinter

Мы создадим форму, содержащую поле ввода адреса электронной почты. Если вы введете недействительный адрес электронной почты, будет показано сообщение об ошибке и цвет текста поля ввода адреса электронной почты изменится на красный. И мы запустим событие проверки, когда фокус выйдет за пределы поля.

Вот полная программа:

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()

Как это работает.

  • Сначала создайте команду проверки, используя метод self.validate() и код подстановки %P:
vcmd =(self.register(self.validate), '%P')
  • Во-вторых, создайте invalidatecommand, которая использует метод self.on_invalid:
ivcmd =(self.register(self.on_invalid),)
  • В-третьих, настройте виджет ввода, который использует validation, validatecommand и invalidatecommand:
self.email_entry.config(validate='focusout', validatecommand=vcmd, invalidcommand=ivcmd)
  • В-четвертых, определите метод show_message(), который изменяет текст виджета label_error и цвет текста виджета email_entry:
def show_message(self, error='', color='black'):
    self.label_error['text'] = error
    self.email_entry['foreground'] = color
  • В-пятых, определите метод validate(), который проверяет значение 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

Метод validate() возвращает True, если текст ввода является допустимым, или False в противном случае. Если текст ввода является допустимым адресом электронной почты, вызовите show_message(), чтобы скрыть сообщение об ошибке и установить цвет текста на черный.

Tkinter выполнит метод on_invalid(), если введенный текст не является допустимым адресом электронной почты.

Наконец, определите метод on_invalid(), который отображает сообщение об ошибке, и установите красный цвет текста виджета email_entry.

def on_invalid(self):
    """
    Show the error message if the data is not valid
    :return:
    """
    self.show_message('Please enter a valid email', 'red')
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *