Rozdział 18 · Narzędzia do rysowania

Ołówek: ciągła kreska

Oddzielne okręgi tworzą przerwy. Połącz każdy punkt z poprzednim — a kreska staje się jedną linią.

Dlaczego kółka przy każdym ruchu — zły pomysł

Rozdział 18.7 wylosowała wolny styl z kółkami, po jednym dla każdej konkurencji <B1-Motion>Działa, ale to podejście ma trzy problemy:

Prawdziwe płótno: pociągnięcie pojedynczych kółek z wyraźnymi przerwami między nimi
To samo rzeczywiste okno z sekcji 18.7: rozpraszanie okręgów zamiast linii.

Najlepszy model: Pamiętaj o poprzednim punkcie

Zamiast okrągu dla każdego zdarzenia, połącz każdy nowy punkt z poprzednim segmentem prosta. Jest wiele odcinków, ale razem tworzą jedną ciągłą linię:

karandash.py
def on_drag(self, event):
    self.canvas.create_line(
        self.state.last_x, self.state.last_y, event.x, event.y,
        fill=self.state.color, width=self.state.width,
        capstyle=tk.ROUND,
    )
    self.state.last_x, self.state.last_y = event.x, event.y
Stąd kod — to metody klasy PaintApp
Począwszy od tej sekcji, przykłady są opisane jako metody: def on_drag(self, event), self.state, self.canvas. Wszystkie należą do PaintAppw całości omówimy w sekcji 18.29 — do tego czasu wystarczy przeczytać self.state.color jako „aktualny kolor aplikacji”
Prawdziwe płótno: Ciągła, płynna linia bez przerw, która podąża za ruchem myszy
Prawdziwe okno ostatecznej wersji: ta sama ręka, ale linia bez przerw — ponieważ rysowane są segmenty, a nie pojedyncze punkty.
ParametrDlaczego
capstyle=tk.ROUNDzaokrągla końce każdego segmentu – połączenia między nimi nie wyglądają na „poszarpane”
widthgrubości ruchu; Im większy, tym bardziej widoczne byłoby „poszarpanie”
A co z smooth=True? Tutaj nie zadziała
U create_line() jest parametrem smooth=True — Tk wygładza linię łamaną, prowadząc przez jej punkty krzywą. Ale wygładzać potrafi tylko wewnętrzny punkty jednej linii, a każdy z naszych odcinków składa się dokładnie z DWÓCH punktów — nie ma między nimi ani jednego rogu. Dodaj smooth=True w ten kod można, i Tk go milcząco zaakceptuje, ale na ekranie nie zmieni się dokładnie nic. Parametr byłby przydatny, gdyby cały kontur był JEDNĄ długą łamaną — taki wariant opisano poniżej.
Dokąd to można rozwinąć: jeden pociągnięcie — jedna łamana
Teraz każdy ruch myszy tworzy osobny element Canvas. Możesz zamiast tego utworzyć linię raz na <Button-1> i dodawaj nową parę współrzędnych przy każdym ruchu coords() (rozdział 18.18): wtedy długa kreska to jeden element zamiast setki, a smooth=True w końcu otrzymuje wewnętrzne punkty, które faktycznie można wygładzić. W tym rozdziale pozostała prostsza wersja z oddzielnymi odcinkami — jest krótsza i łatwiejsza do debugowania.
Praktyka: Ciągłe pociągnięcie ołówkiem
Moduł tkinter otwiera natywne okno Python — wykonaj lokalnie w VS Code, PyCharm lub Jupyter
Praktyka kursuje lokalnie
Otwórz praktykę →