Dwie lekcje i jeden cel: zrozumieć, z czego składa się okno i dlaczego kliknięcie przycisku cokolwiek robi.
01-okno i 09-tekst-i-przyciskiRozmowa po kolei: program pyta, użytkownik odpowiada, program idzie dalej. Kolejność ustala programista.
Wszystko widać naraz. Użytkownik klika, co chce i kiedy chce. Kolejność ustala użytkownik.
modalne i niemodalne
Button
wpisywanie danych
Label — tekst do czytania
wybór z gotowych opcji
nawigacja po programie
wciśnięcie klawisza, puszczenie klawisza
kliknięcie, dwuklik, najechanie, przeciągnięcie
pip --version # NAJPIERW to — do którego Pythona odwołuje się pip? pip install tk # instalacja (terminal, wiersz poleceń albo terminal IDE)
pip --version przed instalacją.
Na jednym komputerze bywa kilka Pythonów. Jeśli pip należy do Pythona 2,
biblioteka trafi nie tam, gdzie piszesz program — i import się nie powiedzie.
Wtedy używamy pip3.import tkinter as tk # wczytaj bibliotekę, nazywaj ją krótko: tk okno = tk.Tk() # stwórz obiekt okna — to jeszcze nie jest widoczne okno.mainloop() # pokaż okno i czekaj na użytkownika
mainloop() to pętla zdarzeń. Program wchodzi do niej
i zostaje tam aż do zamknięcia okna: nasłuchuje kliknięć, odświeża widok, reaguje.
okno = tk.Tk() okno.mainloop() # ← program zatrzymuje się TUTAJ okno.title("Za późno") # ta linia wykona się dopiero po zamknięciu okna
mainloop().
Kod po tej linii wykona się dopiero wtedy, gdy okno zostanie zamknięte.okno.title("Moja pierwsza aplikacja") okno.geometry("300x400")
napis na belce okna
300 to szerokość, 400 to wysokość
geometry to
tekst w cudzysłowie, nie dwie liczby. A między liczbami stoi mała litera x,
nie znak mnożenia. geometry(300, 400) i geometry("300*400") to błędy.okno.resizable(False, False) # nie da się zmienić ani szerokości, ani wysokości okno.resizable(True, False) # szerokość tak, wysokość nie
geometry.(True, False), złap okno za bok i pociągnij. Potem złap za dolną krawędź.
Opisanie, co się faktycznie stało, to jedno z zadań na karcie pracy.# Autor: Jan Kowalski # Program otwiera okno o stałym rozmiarze import tkinter as tk
# to komentarz. Python jej
nie wykonuje — służy wyłącznie człowiekowi, który będzie czytał kod. W tym tobie za miesiąc.import tkinter # pełna nazwa przy każdym użyciu: tkinter.Tk() import tkinter as tk # skrót: tk.Tk() ← tak robimy from tkinter import * # bez przedrostka: Tk() ← odradzane
as tk. Tak pisze większość
poradników w internecie. Widząc tk.Button(...) od razu wiesz, skąd to pochodzi.To są dokładnie zadania z karty pracy 01-okno.
ZADANIE 1 okno z tytułem: twoje imię i nazwisko rozmiar 420x280 skalowanie zablokowane w OBU osiach import z aliasem tk każda linia opisana własnym komentarzem ZADANIE 2 — eksperyment skopiuj program z zadania 1 zmień TYLKO resizable na (True, False) uruchom, spróbuj rozciągnąć okno myszą w obie strony opisz, co faktycznie się stało
tekst = tk.StringVar() # pudełko na tekst, który może się zmieniać tekst.set("Witaj") # wkładamy do pudełka wartość początkową label1 = tk.Label(okno, textvariable=tekst) label1.grid(row=0, column=0)
przechowuje tekst. Sam niczego nie wyświetla.
wyświetla. Sam niczego nie przechowuje.
StringVar() tworzy puste
pudełko — bez set() etykieta pokaże pustkę. To częste pytanie na karcie pracy.Parametr textvariable podpina etykietę do pudełka,
a nie do konkretnego napisu. Zmieniasz zawartość pudełka — napis w oknie zmienia się sam.
tekst.set("Nowa treść") # etykieta odświeża się natychmiast
tk.Label(okno, text="Witaj") —
napis wpisany na sztywno. Działa, ale nie da się go później zmienić w trakcie działania programu.
Dlatego przy przyciskach używamy StringVar.label1.grid(row=0, column=0) # lewy górny róg label2.grid(row=1, column=0) # wiersz niżej label3.grid(row=2, column=0) # jeszcze niżej
row=0 to pierwszy wiersz, row=2 to trzeci.
Element bez grid() nie pojawi się w oknie wcale, nawet jeśli go utworzyłeś.tk.Label(okno, text="Uwaga", bg="black", fg="white") tk.Label(okno, text="Alarm", bg="#ff0000", fg="#00ff00")
kolor tła
kolor napisu
#RRGGBB — po dwa znaki na czerwony,
zielony i niebieski. #ff0000 to czysta czerwień, #00ff00 to czysta zieleń.
Czyli w przykładzie wyżej: czerwone tło, zielony napis.font="none 16 bold" # zapis tekstowy font=("Arial", 16, "bold") # zapis krotką
krój pisma — none oznacza domyślny
rozmiar w punktach
styl: pogrubienie, kursywa, podkreślenie
przycisk = tk.Button(okno, text="Kliknij", command=aplikacja.zmien_tekst) przycisk.grid(row=3, column=0)
command to sedno całej lekcji.
Podajesz w nim nazwę metody bez nawiasów. Mówisz tym: „gdy ktoś kliknie — wywołaj to”.
Samo kliknięcie obsługuje tkinter.command=zmien_tekst() z nawiasami.
Wtedy Python wywoła metodę od razu, przy tworzeniu przycisku, i podstawi jej wynik.
Przycisk po kliknięciu nie zrobi nic.class Aplikacja: def __init__(self, okno): # konstruktor dostaje okno z zewnątrz self.tekst = tk.StringVar() self.tekst.set("Witaj") self.label = tk.Label(okno, textvariable=self.tekst) self.label.grid(row=0, column=0) def zmien_tekst(self): # metoda = zachowanie aplikacji self.tekst.set("Kliknięto!") okno = tk.Tk() aplikacja = Aplikacja(okno) # obiekt dostaje nasze okno okno.mainloop()
self metoda
zmien_tekst wie, którą etykietę ma zmienić, bez zmiennych globalnych.command=self.zmien_tekst # metoda bez parametrów command=lambda: self.zmien_tekst_w(label2) # metoda z parametrem
lambda.
command oczekuje funkcji do wywołania później. Gdyby wpisać
self.zmien_tekst_w(label2) wprost, Python wywołałby ją natychmiast.
lambda opakowuje wywołanie i odkłada je na moment kliknięcia.zmienia zawartość pudełka StringVar. Odświeży się każda etykieta podpięta
pod to pudełko przez textvariable.
zmienia napis w jednej konkretnej etykiecie, bez pośrednika.
StringVar, a drugi napis
zostaje bez zmian — bo nie był z tym pudełkiem połączony.Zadania z karty pracy 09-tekst-i-przyciski.
ZADANIE 1 okno z tytułem: twoje imię, rozmiar 360x240 trzy etykiety w trzech wierszach siatki druga etykieta: biały napis na czarnym tle ZADANIE 2 rozbuduj program o klasę Aplikacja konstruktor + metoda przycisk, który po kliknięciu zmienia tekst pierwszej etykiety na „Kliknięto!” wklej CAŁY plik