Глава 17 · Интерфейс игры

Управление клавиатурой

1-9 — те же ходы, что и клик мышью, через тот же самый код.

Мышь и клавиатура сходятся в одной точке

Button command(клик)клавиатурнаяпривязка (1-9)attempt_move(index)
Оба пути ведут в ОДНУ И ТУ ЖЕ функцию — правила не дублируются.
keyboard_control.py
def on_key(self, event):
    if event.keysym in ("r", "R"):
        self.new_round()
        return
    if event.char and event.char.isdigit():
        n = int(event.char)
        if 1 <= n <= 9:
            self.attempt_move(n - 1)   # клавиша 1 -> индекс 0, ... 9 -> индекс 8
Клавиатура не получает свою копию правил
Обработчик клавиатуры ТОЛЬКО переводит нажатую клавишу в номер клетки и зовёт attempt_move() — ту же функцию, что вызывает клик мышью. Если бы клавиатурный путь копировал проверку победителя отдельно, два набора правил рано или поздно разошлись бы (Debug Lab 9, раздел 17.29 — похожая ошибка с опечаткой в линии).
КлавишаИндекс клетки
10
21
32
43
54
65
76
87
98
keysym против char — здесь выбран char
Раздел 17.8 показал разницу: event.char — фактический введённый символ. Для цифровых клавиш верхнего ряда он предсказуемо равен самой цифре; с дополнительной цифровой клавиатурой (NumPad) поведение обычно совпадает, если включён NumLock, но может отличаться в зависимости от платформы, раскладки и состояния NumLock — если клавиатура важна для вашего проекта, проверьте оба варианта на целевой системе. Здесь event.char всё равно удобнее, чем сравнение по event.keysym.
Практика: клавиши 1-9 и R
Модуль tkinter открывает нативное окно Python — выполните локально в VS Code, PyCharm или Jupyter
Практика выполняется локально
Открыть практику →