Rozdział 16 · Tworzenie fajnych aplikacji z Tkinter

Podsumowanie rozdziału: Zestaw narzędzi Tkinter

Od „program czeka na zdarzenia, nie w kolejności”

Wizualna lista kontaktowa widżetów

Zanim wybierzesz imię, pamiętaj, jak ono wygląda:

Rozdział 16 — lista kontaktów
Label / Entry / Button
tekst, pole wprowadzania, przycisk
witryna widgetów
Checkbutton
niezależne pole wyboru
usunięty/zainstalowany
Radiobutton
grupa wzajemnie wykluczających się wariantów
wybrano jeden z trzech
Combobox
wybór z listy rozwijanej
otwarty lista
Listbox
lista z doborem pierwiastków
wybrany przedmiot
Spinbox / Scale
liczba ze strzałkami / suwakiem
Spinbox
Scale
Progressbar
pasek postępu
0–100%
Notebook
przełączalne zakładki
trzy zakładki
Toplevel
osobnym drugim oknem
główne + ustawienia
🔶 Schematyczny obraz (nie prawdziwy zrzut ekranu)
Plik
Edycja
Nowe
Otwórz...
Wyjście

Zestaw narzędzi Tkinter

Co wybrać dla konkretnych zadań
Potrzebne jest główne okno aplikacji
tk.Tk() — jeden na każdy proces
Potrzebujemy kolejnego okna
tk.Toplevel(root)
Potrzebny widżet formularza z motywem
ttk.Label/Button/Entry/Combobox/...
Potrzebny edytor wielolinijowy
tk.Text / ScrolledText
Łatwe ustawienie pionowe
pack()
Formularz/tabela/adaptacyjne kolumny
grid() + weight/sticky
Precyzyjne pozycjonowanie
place() — świadomie
Ogólny status wielu widgetów
StringVar/IntVar/BooleanVar/DoubleVar
Powiadomienie użytkownika
messagebox
Wybór plików
filedialog + pathlib
Odłożone/powtarzające się wywołanie bez blokady
root.after(...)
Ustawienia trwałe
JSON + pathlib (Rozdział 15)
Duża struktura aplikacji
klasa App + małe callback + czysta logika
Bezpośrednio obsługa klawiatury/myszy
rozdział 17 — .bind(...)
Rozdział w całości 16
Model wydarzenia
mainloop() jest cyklem, a nie zamrożeniem
callback ≠ command ≠ event
function bez nawiasów
Drzewo widżetów
rodzic określa kontekst
create → configure → umiejscowienie → interaktywność
tk i ttk
ttk — motyw + nowoczesne widgety
styl ttk.Style(), nie fg/bg
Układ
pack — proste regiony
grid + weight — formy adaptacyjne
nie mieszać jednego rodzica
Input i status
Entry/Text, end-1c
Tk- zmienne ≠ zastąpić Python- zmienne
Dialogi i okna
messagebox/filedialog – sprawdź wynik
Toplevel, nie drugi Tk()
Responsywność
after() zamiast sleep()
długa praca nie jest w jednym callback
Architektura
czysta logika oddzielna od widgetów
App HAS-A root
świat – przez rozdział 15 JSON
Tkinter-app
Model wydarzenia
mainloop
callback/command
Interfejs
drzewo widżetów
tk/ttk
pack/grid/place
Dane
Zmienne Tk
walidacja
Dialogi
messagebox
filedialog
Toplevel
Responsywność
after()
nie sleep()
Architektura
klasa aplikacyjna
ustawienia trwałe
Pełna mapa rozdziału 16.

Sekwencja w ramach wydarzenia

Precyzyjne sformułowanie jest ważniejsze niż skuteczne sformułowanie: kod inicjalizacyjny nadal działa kolejno łańcuch znaków linia po linii, a każdy pojedynczy callback również jest wykonywany kolejno, gdy zostaje wezwany. To nie to się zmienia, ale ogólny model zarządzania: to właśnie pętla zdarzeń decyduje, która callback zostanie wywołana jako następna, w odpowiedzi na zdarzenie — a nie sam kod, idący w jednej ciągłej linii od góry do dołu.

rozpoczęcie programu
inicjalizacja
wykonywana jest sekwencyjnie
łańcuch znaków Linia po linijce
mainloop()
zdarzenie → wybrało cykl
callback A
również spełnione
kolejno
kolejnym wydarzeniu → ponownie wybrał pętlę
callback B
również spełnione
kolejno
Sekwencja nie posunęła się donikąd — jest po prostu podzielona na kawałki, między którymi decyduje cykl wydarzeń.

co dalej

Teraz możemy budować root i drzewo widżetów, łączyć callback przez command, układać formy przez pack i adaptacyjny grid, przechowuj współdzielony stan w zmiennych Tk-, Pokazuj dialogi, otwieraj/zapisuj pliki, umawiaj opóźnione połączenia przez after() i złóż wszystko w klasę aplikacji z trwałością ustawienia.

W rozdziale 17 („Projekt: gra „Kółko-krzyżyk” z Tkinter”) zbudujemy pełną grę — i poznamy bardziej ogólny mechanizm wiązania zdarzeń, .bind("<Button-1>", ...), który reaguje na kliknięcie w dowolnym miejscu widżetu (na przykład na konkretnej komórce płótna), a nie tylko na zdefiniowaną akcję taką jak command przycisk.

Czego nauczyliśmy się w tym rozdziale

  • Inicjalizacja i każdy callback nadal wykonywane są kolejno — zmienia się ogólny model zarządzania: pętla zdarzeń decyduje, który callback wywołać następny w odpowiedzi na wydarzenia.
  • root.mainloop() uruchamia pętlę zdarzeń zamiast „zawieszania”
  • command=функция kojarzy callback z widżetem — bez nawiasów po nazwie funkcji.
  • Każdy widget jest tworzony, konfigurowany i umieszczany osobno przez menedżera geometrii — pack(), grid() lub place(), ale bez mieszania pack/grid z jednym rodzicem.
  • ttk daje tematyczne widżety i stylizację przez ttk.Style() — ale nie zastępuje tk.Text/Canvas/Menu.
  • zmienne Tk-zmienne (StringVar i inne) wiążą wiele widżetów z jedną wartością — i nie zastępują zwykłych zmiennych Python.
  • messagebox i filedialog zwracają rzeczywiste wartości, które należy sprawdzić (w tym anulowanie), a nie zakładać.
  • after() planuje opóźnione lub powtarzające się połączenie bez blokowania — time.sleep() w callback zawiesza cały interfejs.
  • Logikę domeny warto pisać jako czyste funkcje, sprawdzane bez żadnego widgetu — callback tylko czyta dane wejściowe, wywołuje logikę i aktualizuje ekran.
  • GUI- wykorzystują te same funkcje JSON+pathlib co Rozdział 15 – nic nowego.