В некоторых приложениях вы захотите проверить содержимое виджета Entry, чтобы убедиться, что оно действительно соответствует какому-то правилу, которое должно соблюдаться в вашем приложении. Вы определяете, что является правильным, написав функцию обратного вызова, которая проверяет содержимое и сигнализирует, является ли оно правильным или нет.
Вот процедура настройки валидации для виджета.
Напишите функцию обратного вызова, которая проверяет текст в Entry и возвращает True, если текст действителен, или False, если нет. Если обратный вызов возвращает False, попытка пользователя отредактировать текст будет отклонена, и текст останется неизменным.
Зарегистрируйте функцию обратного вызова. На этом шаге вы создадите Tcl-обертку для функции Python.
Предположим, что ваша функция обратного вызова - это функция с именем isOkay. Чтобы зарегистрировать эту функцию, воспользуйтесь методом из универсальных методов для виджетов .register(isOkay). Этот метод возвращает символьную строку, которую Tkinter может использовать для вызова вашей функции.
Когда вы вызываете конструктор Entry, используйте опцию validatecommand в конструкторе Entry, чтобы указать обратный вызов, и опцию validate, чтобы указать, когда будет вызван обратный вызов для проверки текста в обратном вызове. Значения этих опций более подробно рассматриваются ниже.
Вот значения опции validate и то, что они означают.
'focus'
Проверять всякий раз, когда виджет
Entryполучает или теряет фокус (см. Раздел 53, "Фокус: маршрутизация ввода с клавиатуры").
'focusin'
Проверяет, когда виджет получает фокус.
'focusout'
Проверяется всякий раз, когда виджет теряет фокус.
'key'
Проверяет, когда любое нажатие клавиши изменяет содержимое виджета.
'all'
Проверять во всех вышеперечисленных ситуациях.
'none'
Отключить валидацию. Это значение опции по умолчанию. Обратите внимание, что это строка
'none', а не специальное значение PythonNone.
Значение опции validatecommand зависит от того, какие аргументы вы хотите получить от обратного вызова.
Возможно, единственное, что нужно знать обратному вызову, это то, какой текст в данный момент отображается в Entry. В этом случае для получения текста можно использовать метод .get() для textvariable, связанной с виджетом.
В этом случае достаточно указать опцию "validatecommand=f", где f - это имя вашей функции обратного вызова.
Tkinter также может предоставить несколько параметров для обратного вызова. Если вы хотите использовать некоторые из этих параметров, при вызове конструктора Entry используйте опцию validatecommand=(f, s1, s2, ...), где f - это имя вашей функции обратного вызова, а каждое дополнительное si - это код подстановки. Для каждого кода подстановки, который вы укажете, обратный вызов получит позиционный аргумент, содержащий соответствующее значение.
Вот коды подстановки.
Таблица 18. Коды подстановки обратного вызова
'%d' |
Код действия: 0 для попытки удаления, 1 для попытки вставки или -1, если обратный вызов был вызван для фокусировки, выхода из фокуса или изменения textvariable. |
'%i' |
Когда пользователь пытается вставить или удалить текст, этот аргумент будет индексом начала вставки или удаления. Если обратный вызов был вызван входом в фокус, выходом из фокуса или изменением textvariable, аргумент будет -1. |
'%P' |
Значение, которое будет иметь текст, если изменение разрешено. |
'%s' |
Текст в Entry перед изменением. |
'%S' |
Если вызов был вызван вставкой или удалением, этот аргумент будет текстом, который был вставлен или удален. |
'%v' |
Текущее значение опции виджета validate. |
'%V' |
Причина этого обратного вызова: одна из 'focusin', 'focusout', 'key' или 'forced', если textvariable' была изменена. |
'%W' |
Имя виджета. |
Вот небольшой пример. Предположим, вы хотите, чтобы ваш обратный вызов получал '%d', чтобы узнать, почему он был вызван; '%i', чтобы узнать, где будет происходить вставка или удаление; и '%S', чтобы узнать, что должно быть вставлено или удалено. Ваш метод может выглядеть следующим образом:
def isOkay(self, why, where, what):
...
Далее вы используете универсальный метод .register(), чтобы обернуть эту функцию. Мы предполагаем, что self - это некоторый виджет.
okayCommand = self.register(isOkay)
Чтобы установить этот обратный вызов, вы должны использовать эти две опции в конструкторе Entry:
self.w = Entry(self, validate='all', validatecommand=(okayCommand, '%d', '%i', '%S'), ...)
Предположим, что в данный момент Entry содержит строку 'abcdefg', и пользователь выделяет 'cde', а затем нажимает Backspace. Это приведет к вызову isOkay(0, 2, 'cde'): 0 для удаления, 2 для позиции перед 'c', и 'cde' для удаляемой строки. Если isOkay() возвращает True, то новым текстом будет 'abfg'; если возвращает False, то текст не изменится.
Виджет Entry также поддерживает опцию invalidcommand, определяющую функцию обратного вызова, которая вызывается всякий раз, когда validatecommand возвращает False. Эта команда может изменять текст в виджете с помощью метода .set() для связанной с виджетом textvariable. Настройка этой опции работает так же, как и настройка validatecommand. Вы должны использовать метод .register() для обертывания вашей функции Python; этот метод возвращает имя обернутой функции в виде строки. Затем вы передадите в качестве значения опции invalidcommand либо эту строку, либо первый элемент кортежа, содержащего коды подстановки.