Глава 17 · Интерфейс игры
Hover preview через bind()
Показать возможный ход — не значит его сделать. Именно этот эффект доказывает, зачем нужна модель.
Наведение — сигнатурный визуальный эффект главы
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
Практика выполняется локально