Глава 16 · Создаём классные приложения с Tkinter

Валидация ввода и обратная связь

Сырой текст пользователя не становится числом сам — между ними должна быть проверка.

Валидация — прежде чем считать

текст пользователя
entry.get()
пусто? не число? отрицательное?
валидация
валидно?
нет — понятная ошибка
сообщение пользователю
да — конвертация
числовое значение
доменная функция
Ввод не превращается в число сам — между строкой и вычислением есть проверка.
Превью try/except
Это минимальное практическое превью try/except. Пока используем его как готовый шаблон для проверки пользовательского ввода. Подробно исключения будут изучены в главе 21.
parse_number.py
def parse_number(text):
    text = text.strip()
    if not text:
        return False, None, "Поле не должно быть пустым"
    try:
        return True, float(text), ""
    except ValueError:
        return False, None, "Введите число"

print(parse_number(""))      # (False, None, ...)
print(parse_number("abc"))   # (False, None, ...)
print(parse_number("-5"))    # (True, -5.0, '') — отрицательное число ЧИСЛОМ является!
print(parse_number("100"))   # (True, 100.0, '')
Не всякое число обязано быть положительным
parse_number проверяет только «это вообще число?» — и намеренно принимает отрицательные значения и ноль: они тоже числа. Например, температура в градусах Цельсия может быть отрицательной (раздел 16.27) — требование «положительное» специфично для конкретной задачи (суммы денег, количества людей), а не свойство чисел вообще.

Специализированная валидация поверх parse_number

validate_positive.py
def validate_positive_amount(text):
    ok, value, message = parse_number(text)
    if not ok:
        return False, message
    if value <= 0:
        return False, "Число должно быть больше нуля"
    return True, ""

def validate_positive_int(text):
    ok, value, message = parse_number(text)
    if not ok:
        return False, message
    if value != int(value):
        return False, "Введите целое число"
    if int(value) < 1:
        return False, "Число должно быть не меньше 1"
    return True, ""
Разные задачи — разные функции
Сумма счёта должна быть положительным числом — validate_positive_amount. Количество человек должно быть положительным целымvalidate_positive_int дополнительно отвергает 2.5. Обе функции переиспользуют parse_number, а не дублируют разбор текста.

Как показать ошибку пользователю

status_label.py
ok, message = validate_positive_amount(schet_entry.get())
if not ok:
    status_label.config(text=message, foreground="#DB2777")
    return
Ошибка — на экране, а не только в терминале
GUI-пользователь обычно не смотрит в терминал. Показывайте ошибку через виджет-статус или messagebox.showerror(...) (раздел 16.18) — печать print(...) в терминал не считается обратной связью пользователю в оконном приложении.

Чуть глубже: validatecommand

У Tkinter есть встроенный механизм валидации прямо на уровне виджета (validate=, validatecommand=, register(...)) — синтаксис у него не самый интуитивный, поэтому для большинства форм в этом курсе достаточно ручной проверки перед вычислением, как выше.

Практика: parse_number и специализированная валидация
Проверяется без tkinter — на чистых функциях
Открыть практику →