Глава 18 · Финальные штрихи
Архитектура PaintApp
app.root, состояние инструмента, документ фигур и Canvas — три разных слоя одного приложения.
app HAS-A root — тот же паттерн, что и в главах 16–17
Композиция против наследования
Возможно, но не нужно
class PaintApp(tk.Tk):
def __init__(self):
super().__init__()
...
Как в главах 16–17
class PaintApp:
def __init__(self, root):
self.root = root
...
Что использовать сегодня: Наследование от
tk.Tk технически работает, но не согласуется с тем, как строились приложения в этой книге начиная с главы 16. app.root — тот же паттерн, что у калькулятора чаевых и крестиков-ноликов.Три обязанности, три группы методов
| Группа методов | За что отвечает |
|---|---|
build_ui / build_toolbar | построение виджетов — один раз, при запуске |
on_press / on_drag / on_release | события мыши → изменения state и document |
render_document | документ → Canvas (единственное место, которое рисует по-настоящему) |
undo / redo / clear_canvas | управление историей документа |
save_document / load_document | документ ↔ файл на диске |
событие мыши
↓
DrawingState
текущий инструмент, цвет, точка начала
↓
document: list[Shape]
источник истины
↓
render_document()
↓
Canvas
UI-состояние, документ и отображение — три разных слоя
DrawingState — что выбрано ПРЯМО СЕЙЧАС (инструмент, цвет). document — что уже НАРИСОВАНО и что переживает смену инструмента. Canvas — то, что видно на экране, производное от документа. Смешать первое со вторым — частая причина путаницы: например, хранить историю Undo внутри DrawingState вместо отдельного списка не позволило бы отменять действия, сделанные ДО того, как пользователь сменил инструмент.Практика: собираем объектный граф PaintApp
Модуль tkinter открывает нативное окно Python — выполните локально в VS Code, PyCharm или Jupyter
Практика выполняется локально