Rozdział 18 · Ostatnie poprawki

PaintApp architektura

app.root, stan narzędzia, dokument kształtu i Canvas to trzy różne warstwy tej samej aplikacji.

app HAS-A root — ten sam wzorzec co w rozdziałach 16–17

Składanie a dziedziczenie
Możliwe, ale niekonieczne
class PaintApp(tk.Tk):
    def __init__(self):
        super().__init__()
        ...
Jak w rozdziałach 16–17
class PaintApp:
    def __init__(self, root):
        self.root = root
        ...
Co używać dzisiaj: Dziedzictwo od tk.Tk technicznie działa, ale nie zgadza się z strukturą załączników w tej książce od rozdziału 16. app.root jest tym samym wzorem co kalkulator końcówek i kółko i krzyżyk.

Trzy obowiązki, trzy grupy metod

app : PaintApproot = Tkstate = DrawingStatedocument = list[Shape]undo_stack = list[list[Shape]]redo_stack = list[list[Shape]]canvas = Canvas
app przechowuje widżety, parametry narzędzi i dokument — ale nie myli ich ze sobą.
Grupa metodZa co odpowiada
build_ui / build_toolbarbudowania widgetów — raz, przy starcie
on_press / on_drag / on_releasezdarzenia myszy → zmiany state i document
render_documentdokument → Canvas (jedyne miejsce, które naprawdę rysuje)
undo / redo / clear_canvasZarządzanie historią dokumentów
save_document / load_documentplik dokumentu ↔ na dysku
zdarzenie myszy
DrawingState
bieżące narzędzie, kolor, punkt początkowy
document: list[Shape]
źródło prawdy
render_document()
Canvas
Zdarzenie najpierw zmienia stan i dokument, a dopiero potem Canvas jest przerysowane z dokumentu.
UI-status, dokument i display to trzy różne warstwy
DrawingState – co jest wybrane TERAZ (narzędzie, kolor). document — co jest już NARYSOWANE i co przeżywa zmianę narzędzia. Canvas — to, co widać na ekranie, jest pochodną dokumentu. Mieszanie pierwszego z drugim jest częstą przyczyną zamieszania: na przykład przechowywanie historii Undo wewnątrz DrawingState zamiast osobnej listy nie pozwoliłoby odwoływać się do działań wykonanych PRZED zmianą narzędzia przez użytkownika.
Praktyka: budujemy graf obiektowy PaintApp
Moduł tkinter otwiera natywne okno Python — wykonaj lokalnie w VS Code, PyCharm lub Jupyter
Praktyka kursuje lokalnie
Otwórz praktykę →