pre up next title end end

A. Tkinter

  1. Úvodní informace
  2. Základní pojmy I
  3. Praktická ukázka I
  4. Základní pojmy II
  5. Praktická ukázka II

A.1   Úvodní informace

Účelem této přílohy je poskytnout úvodní a nutně neúplné informace o navrhování grafických aplikací pomocí Tkinteru. Je to vlastně úvodní kapitola k obsáhlejšímu souboru přeložených textů s příklady: Tkinter Pythonu.

Jednoduché příklady budou čtenáře lákat, aby si je během studia Pythonu příležitostně vyzkoušel, proti čemuž nelze nic namítat. Nutno ale poznamenat, že od grafických objektů se očekává něco víc, než jejich pouhé vykreslení na monitoru.

Jsou to GUI - grafická rozhraní mezí počítačem a uživatelem. Mají sloužit k výměně informací pro navazující programy. Pro tuto úroveň použití je nezbytná poměrně ucelená znalost Pythonu - zejména jeho tříd a objektů.

Předložený text není didakticky komponován. Zaujatý student by se měl zaměřit zejména na řízení událostí a používání kontrolních proměnných. Tento čtenář by také měl částečně umět anglicky aby byl schopen si vyhledat chybějící informace.

Programy Tkinteru je ve Windows nejvýhodnějěí psát a editovat v prostředí Thonny, kde zapsaný skript spustíme tlačítkem nebo klávesnicí F5.


A.2   Základní pojmy I

Tkinter (či tkinter pro Python 3) je paket modulů, které obsahují kolekce tříd a metod pro přístup k prvkům Tk.

Tk je knihovna rutin v jazyce C neboli sada nástrojů pro správu oken a událostí, která je součástí Tcl

Tcl (Tool Command Language) je jazyk pro manipulaci s prvky Tk.

Widget je prvek grafického rozhraní jako je text box, combo box nebo okno nejvyšší úrovně. Od této chvíle mu budeme familiárně říkat piškot. Piškoty jsou hierarchicky uspořádatelné objekty, vytvořené jako instance tříd.

Termín widget alias piškot má dvojí "skupenství". Jednak to je instance třídy ve skriptu, jednak to je zobrazený prvek na monitoru.

ttk je novější modul Tkinteru (Tk 8.5 - prosinec 2007), obsahující odlišné verze většiny standardních piškotů.

GUI (Graphical User Interface) je grafická aplikace, umožňující výměnu informací mezi uživatelem a počítačem. Technicky se skládá z jednotlivých widgetů.

Grafická aplikace se skládá ze tří skupin nástrojů:

A.3   Praktická ukázka I

Mnohé náležitosti Tkinteru si nejlépe ukážeme na příkladě (hello_1.py)

1   from tkinter import*
2
3   root = Tk()
4   w = Label(root, text="Nazdar světe!")
5   w.pack()
6
7   root.mainloop()
F:\Codetest\Tkinter> python hello_1.py

Tímto prostinkým skriptem vytvoříme okno, které má tři ovládácí prvky a náš popisek "Nazdar světe" :

Jednotlivé řádky skriptu mají tento význam:

  1. Na prvním řádku importujeme modul tkinter; kdybychom chtěli použít také modul ttk, napíšeme na druhý řádek import ttk.
  2. ---
  3. Jméno root je náš název pro instaci třídy Tk, která představuje nejvýše postavené okno se základními ovládacími prvky. Do tohoto okna se ukládají všechny další piškoty.
  4. Jméno w je náš název pro instanci třídy Label, která je podřízená objektu root a nese námi vložený text.
  5. Nezbytný úkon, který zviditelní předtím deklarovaný objekt. Jde o akt správy geometrie, který si označíme jako expozici neboli výstav.
  6. ---
  7. Poslední instrukce evokuje metodu mainloop() pro objekt root, která generuje nekonečnou smyčku událostí.

A.4   Základní pojmy II

Nekonečná smyčka událostí mainloop je velmi důležitou a sofistikovanou částí programové struktury. Zobrazení okna si můžeme představit jako promítání filmu, při kterém si vůbec neuvědomujeme střídání jednotlivých políček.

Zobrazení není statické ale cyklicky se obnovuje tak dlouho, dokud není dalším příkazem ukončeno.
V našem případě ukončí opakované zobrazování okna klik myší na ovládacím prvku s křížkem.

Smyčka mainloop mezitím koná velice důležitou práci. Hlídá, jestli v souvisejícím prostředí nedošlo k nějaké události

Událostí může být pohyb kurzoru, stisk či uvolnění tlačítka myší nebo klávesnice, změna velikosti okna a také zaměření (focus). Je-li událost programově ošetřena (což v našem případě je implicitně také), procedura mainloop() to zaregistruje a uvědomí příslušný piškot (či proceduru), který (která) zařídí další - v našem případě zavře wokno.

Focus je stav aktivity, který umožňuje spojení widgetu s událostí klávesnice. V jednom okamžiku může mít focus jen jediný widget (vidíme kolem něho tečkovaný rámeček).

Přesun zaměření z jednoho widgetu na druhý lze provést několika způsoby:

Stisk mezerníku je událost, která spustí ten widget, na který ukazuje focus.

Spojení události s připravenou reakcí piškotu lze realizovat buď prostřednictvím parametru command (jen u některých piškotů) nebo metodou .bind().

Správa geometrie

Pozice jednotlivých piškotů a rámečků uvnitř nadřízených kontejnerů se určují pomocí správců geometrie, jež jsou tři:

  1. packer - používá metodu   pack()
  2. grider - používá metodu   grid()
  3. placer - používá metodu   place()

Nejjednodušší je metoda pack, doporučovaná a nejvšestrannější je metoda grid.


A.5   Praktická ukázka II

Při programování grafických prvků se velmi často používají třídy. Ukážeme si trochu rozvinutou variantu předchozí ukázky (hello2.py):

 1 from tkinter import*
 2
 3 class Hello:
 4    def __init__(self, master):
 5       frame = Frame(master)
 6       frame.pack()
 7       self.button = Button(frame, text="QUIT", fg="red",
                                command=frame.quit)
 8       self.button.pack(side=LEFT)
 9       self.hi = Button(frame, text="Nazdar!",
                            command=self.say_hi)
10       self.hi.pack(side=LEFT) 
11    def say_hi(self):
         print("Nazdárek Kašpárek")

12 root = Tk()
13 app = Hello(root)
14 root.mainloop()
C:\CodeTest\tk-py> python33 hello.py
Nazdárek Kašpárek

Vytvořili jsme okno se dvěma tlačítky. Jedním způsobíme tisk oslovení "Nazdárek Kašpárek" v okně konzoly, druhým okno zavřeme:

Jednotlivé řádky skriptu mají tento význam:

  1. Na prvním řádku importujeme všechny objekty modulu tkinter.
  2. ---
  3. Počátek deklarace vlastní třídy.
  4. Konstruktor s povinným atributem self a vlastním atributem master, jímž bude instance root .
  5. V rámci konstruktoru vytváříme instanci třídy Frame, která má jeden atribut, jímž má být název rodičovského objektu; v našem případě to bude "root".
  6. Povinná expozice objektu frame.
  7. Deklarace tlačítka jako instance třídy Button. Zástupné self naznačuje, že tlačítko bude vytvořeno pro instanci třídy "Hello". Parametry v závorce uvádějí jméno nadřízeného piškotu, text na tlačítku, barvu pozadí a jméno nativní funkce, která bude volaná při stisku tlačítka.
  8. Povinná expozice objektu s parametrem side=LEFT, což znamená, že toto tlačítko se v nadřazeném piškotu "frame" umístí vlevo nahoru.
  9. Deklarace dalšího tlačítka s názvem hi. Parametr command tentokrát uvádí jméno vlastní funkce, která bude volaná při stisku tlačítka.
  10. Opět povinná expozice objektu.
  11. Definice funkce say_hi, která při své evokaci vytiskne zadaný text.
  12. Nejvýše postavené okno aplikace jako instance třídy Tk.
  13. Vytvoření instance třídy Hello, která je nositelem deklarovaných piškotů a metod.
  14. Evokace smyčky pro objekt root.

Při deklaraci tlačítek button a hi jsme využili implicitně přiřazenou událost <Button-1>, což je stisk levého tlačítka myši.

Projdeme-li skriptem od shora dolů, uvědomíme si, že kromě importu na prvním řádku začíná výpočet na řádku 12 vytvořením nejvýše postaveného okna root, které hned na řádku 13 použijeme jako argument při tvorbě instance třídy Hello.
Tento argument použije konstruktor třídy Hello jako hodnotu pro parametr master.

Nabízí se otázka, k čemu vlastně potřebujeme deklarovat piškot frame? Když upravíte hello2.py tak aby se v něm piškot frame nevyskytoval, zjistíte, že dostanete téměř shodné okno - pouze s tím rozdílem, že tlačítka QUIT a "Nazdar!" jsou posunutá až k okraji okna.
Piškot frame tedy zajistil jejich centrické umístění.

Více se dozvíte v navazujícím textu:   Tkinter Pythonu.


prev up next title end end