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

Hover preview через bind()

Показать возможный ход — не значит его сделать. Именно этот эффект доказывает, зачем нужна модель.

Наведение — сигнатурный визуальный эффект главы

Наведение на пустую клетку показывает бледный превью X
Реальное окно полной версии: ход X, временный превью не изменяет board. Фрагмент ниже отвечает только за эффект наведения.
После хода X наведение показывает бледный превью O
Реальное окно той же версии на ходе O: визуальный слой меняется вместе с current_player, но пустая клетка в модели остаётся пустой.
hover_preview.py
def on_cell_enter(self, index):
    state = self.state
    if state.game_over or state.board[index]:
        return   # не показываем превью — конец игры или клетка занята
    self.buttons[index].config(text=state.current_player, fg=HOVER_COLOR)

def on_cell_leave(self, index):
    self.render()   # не 'text=""' — а render() из МОДЕЛИ
on_cell_leave НЕ должен просто стирать текст
Наивная реализация on_cell_leave вида self.buttons[index].config(text="") сотрёт уже СДЕЛАННЫЙ ход, если игрок наводит мышь на занятую клетку каким-то другим путём — Debug Lab 13 (раздел 17.29) разбирает это подробно. Правильный код всегда перерисовывает из модели, а не гадает, что стереть.

Доказательство: модель не меняется

hover_ne_menyaet_model.py
assert app.state.board[4] == ""
app.on_cell_enter(4)
assert app.state.board[4] == ""     # ПОСЛЕ наведения — всё ещё пусто
app.on_cell_leave(4)
assert app.state.board[4] == ""     # и после ухода курсора — тоже
Практика: hover preview на реальном поле
Модуль tkinter открывает нативное окно Python — выполните локально в VS Code, PyCharm или Jupyter
Практика выполняется локально
Открыть практику →