ÚVOD
PROG. JAZYKY
PYTHON
PASCAL
JAVASCRIPT
KE STAŽENÍ
OSTATNÍ
FÓRUM
ODKAZY

MODUL TKINTER V PYTHONU - 1

Úvod

Tento text neberte v žádném případě jako nějakou ucelenou učebnici nebo příručku pro modul Tkinter. Není totiž ani zdaleka dokončen. Určitě obsahuje velké množství chyb, omylů a nepřesností (zejména co se týká české terminologie). Je to proto, že se sám pracovat s Tkinterem teprve učím. Co se naučím, to sem dopíšu. Vycházím z většího množství různých, vesměs anglických textů.

Přesto se tato příručka může někomu hodit. Obsahuje spoustu užitečných informací a dá se chápat jako úvod do knihovny Tkinter. Hlavní důvod, že jsem tuto přítučku začal psát, byl, že jsem na internetu nenašel žádný uspokojivý text s touto tematikou. Nevím, jak dlouho mi to psaní vydrží, tak mi držte palce :-).

U čtenáře tohoto textu předpokládám, že umí alespoň základy Pythonu. Pokud tomu tak není, doporučuji nejprve prostudovat Učebnici jazyka Python (aneb Létající cirkus) ze serveru PyCZ.

Co je to Tkinter

Tkinter (slovo znamená Tk interface - rozhraní k Tk) je modul pro přístup ke knihovně Tk v Pythonu. Knihovna Tk (určená pro jazyk Tcl) je trochu starší nástroj k vytváření uživatelského grafického rozhraní. Jeho největší výhoda je jeho platformní rozšíření - verze tohoto modulu existují v podstatě pro všechny dnes používané operační systémy (Unix, Linux, Macintosh, Windows).

Poznámka: Programy s grafickým rozhraním (včetně programů s modulem Tkinter) se obvykle píší objektově orientovaným stylem. Tento (jinak moderní a velmi dobrý) způsob programování však zde vkůli přehlednosti používat nebudu.

Začátek

Inicializace modulu Tkinter

Začátek je jednoduchý: prostě inicializujete knihovnu Tkinter. To jde několika způsoby:

   # import Tkinter          # primitivní způsob, který nemám rád
   import Tkinter as tki     # místo Tkinter.funkce budeme zde psát jen tki.funkce
   # from Tkinter import *   # nejlepší způsob, já jej však tady radši používat nebudu

Zde používám pro názornost radějí druhý způsob (proto jsou taky oba zbývající v komenářích). Pokud byste použili způsob první, psali byste při volani libovolné funkce z knihovny Tkinter vždy Tkinter.funkce(). To je velmi nepohodlné. V praxi je nejšikovnější ten třetí - místo Tkinter.funkce() se píše jen funkce(). U druhého - zde používaného - zůsobu se v daném případě píše tki.funkce().

Vytvoření hlavního okna

  import Tkinter as tki

  hl_okno=tki.Tk()          # toto vytvoří hlavní okno
  
  hl_okno.mainloop()    # toto převede řízení činnosti na hlavní okno

Proměnná hl_okno (reprezentující hlávní okno) je nejduležítější součástí programu. Všechny prvky zobrazené v okně jsou děti (nebo vnuci či vzdálenější potomci) této proměnné.

Funkce mainloop v podstatě spustí vytvořené okno. Pokud byste ji nezadali, okno se ani nezobrazí a program ihned skončí

Proměnné třídy Tk() (hlavní okno) mají několik užitečných funkcí. Například funkce quit(). Ta při volání vypne hlavní okno. Takže pokud zavoláte kdekoli v našem programu hl_okno.quit(), zachová se program stejně, jako byste klikli na křížek v pravém horním rohu.

Ovládací prvky

Práce s ovládacími prvky

Hlavní okno obyčejně obsahuje množství ovládacích prvků.

  import Tkinter as tki

  hl_okno=tki.Tk()
  napis=tki.Label(hl_okno, text="Nazdar!!!")  # toto vytvoří popisku napis
  napis.pack()                                # tohle umožní, aby se popiska zobrazila
  
  hlavni_okno.mainloop()

Zde jsme vytvořili ovládací prvek popisku (label). Stejným způsobem se vytvářejí i ostatní ovládací prvky.

Všechny ovládací prvky mají miniálně jeden povinný atribut a větší množství atributů nepovinných. Ten povinný atribut obsahuje název jeho rodiče (v tomto případě hl_okno), nepovinné atributy obsahují základní vlastnosti daného prvku. Seznam všech nepovinných atributů získáte pomocí metody keys() - například v předchozím případě seznam=napis.keys().

Samotné vytvoření ovládacího prvku nestačí. Musí se ještě zobrazit. U všech ovládacích prvků existují metody, které daný prvek zobrazí a určí mu jeho polohu. Tyto metody jsou u všech obvyklých ovládacích prvků stejné! Zde jsem použil metodu pack(). Existují však i další. Budu o nich psát později. Zatím používejte všude pack().

Některé jednoduché prvky

Zde je popis několika jednoduchých ovládacích prvků, které můžete zatím potřebovat. Ke složitějším ovládacím prvkům se vrátím později.

Label (rodič, text="Nějaký text", fg="blue", bg="white")

Prostě jednoduchá popiska. Její obsah je v nepovinné proměnné text. Proměnná fg (opět nepovinná) obsahuje anglicky psanou barvu textu. Oproti tomu proměnná bg obsahuje anglicky psanou barvu pozadí.

Button (rodič, text="Napis", width=30, height=3, command=akce)

Tlačítko, které po kliknutí provede akci command. Proměnně text, fg a bg (zde nepoužité) jsou stejné jako u popisky.

Nepovinné proměnné width a height určují šířku a výšku daného tlačítka.

Tady je menší příklad na tlačítko, které zavře hlavní okno:

  import Tkinter as tki

  hl_okno=tki.Tk()
  tlacitko=tki.Button(hl_okno, text="Vypnout", command=hl_okno.quit)
  tlacitko.pack()
  
  hlavni_okno.mainloop()

Funkce hl_okno.quit() zavře okno a vypne program. Všimněte si, že pokud dáváme funkci do proměnné command, nepíšeme za ni závorky.

Frame (rodič, width=50, height=20, relief="sunken", bd=2)

Vytvoří rámeček. Ten může obsahovat i další ovládací prvky. To znamená, že může být rodičem dalších ovládacích prvků.

Proměnná relief udává vybočení rámečku oproti okolí. Možně hodnoty: "flat" (žádné vybočení, neviditelný rám), "sunken" (snížení), "raised" (vyvýšení), "groove" (žádné vybočení, viditelný rám snížený) a "ridge" (žádné vybočení, viditelný rám zvýšený).

Proměnná bd (border - rámeček, okraj, lem) značí šířku okraje. Pokud se nezadá, automaticky se nastaví nula. Při nulovém okraji nebude mít nastavení proměnné relief žádné účinky (bude se chovat jako "flat").

Tady je příklad na rámeček obsahující popisku.

  import Tkinter as tki

  hl_okno=tki.Tk()

  ram=tki.Frame(hl_okno, bd=2, width=50, height=20, relief="sunken")
  ram.pack()
  
  napis=tki.Label(ram, text="Zdar!")
  napis.pack()

  hl_okno.mainloop()

Některé nepovinné proměnné můžete použít téměř u všech ovládacích prvků (např. width, height, fg, bg, relief).

Změny vlastností ovládacích prvků

Potřebujete-li změnit vlastnost daného prvku za běhu programu, můžete použít metodu configure() (nebo jen config() ):

  import Tkinter as tki

  hl_okno=tki.Tk()

  napis=tki.Label(hl_okno, text="Nejaky napis")
  napis.pack()

  def zmen_napis():
    napis.configure(text="Jiny napis", fg="blue")

  tlacitko=tki.Button(hl_okno, text="ZMENIT NAPIS", bg="#F5F5DC", command=zmen_napis)
  tlacitko.pack()

  hl_okno.mainloop()

Po kliknutí na tlačítko se provede funkce zmen_napis(), která změní text popisky napis na "Jiny napis" a její barvu na modrou.

Myslím, že syntaxe je jasná. Do závorek příkazu configure se vepíší nepovinné proměnné s novými hodnotami.

Totéž však lze napsat i jinak, jednodušeji:

  import Tkinter as tki

  hl_okno=tki.Tk()

  napis=tki.Label(hl_okno, text="Nejaky napis")
  napis.pack()

  def zmen_napis():
    napis["text"]="Jiný nápis"
    napis["fg"]="blue"

  tlacitko=tki.Button(hl_okno, text="ZMENIT NAPIS", bg="#F5F5DC", command=zmen_napis)
  tlacitko.pack()
  
  hl_okno.mainloop()

Oba způsoby vyvolají v tomto případě stejný účiněk. Avšak ten druhý má oproti metodě configure jednu výhodu. Dá se pomocí něho číst daná vlastnost ovládacího prvku.

  import Tkinter as tki

  hl_okno=tki.Tk()

  def funkce1():
    tlacitko["text"]=tlacitko["text"]+"!"

  tlacitko=tki.Button(hl_okno, text="Klikni sem", command=funkce1)
  tlacitko.pack()

  hl_okno.mainloop()

Tak obdobu tohoto programu se mi pomocí configure napsat nepodařilo (šlo by tlacitko.config(text=tlacitko["text"]+"!")). Práce programu je myslím jasná. Po každém kliknutí na tlačítko přibyde na jeho nápise jeden vykřičník.

Metody k umístění a zobrazení ovládacích prvků

Jak jsem psal v minulém díle, všechny ovládací prvky mají určité metody, které určí jejich polohu a zobrazí je. Zatím jsem všude používal metodu pack() bez parametrů. To je ten nejprimitivnější spůsob. Jak zde uvidíte, modul Tkinter umožňuje rozmisťovat ovládací prvky i mnohem inteligentněji.

Metoda pack()

Tato metoda vyskládává prvky do řádků nebo sloupců. Použitelné proměnné:

side
Z které strany se prvek vloží. Možné hodnoty: "left" (z leva), "right" (z prava), "top" (z hora), "bottom" (z dola).
padx, pady
Okolní mezera. Je-li nastaven padx, bude kolem prvku zleva i zprava zadaná mezera. Totéž platí pro pady zhora a zdola.
fill
Jestli se má prvek roztáhnout na celou mu vymezenou plochu. Hodnoty "none" (nemá se roztahovat), "x" (má se roztáhnout jen vodorovně), "y" (jen podle svisle), "both" (vodorovně i svisle, tj. nejvíc, jak to jde).

Menší příklad:

  import Tkinter as tki

  hl_okno=tki.Tk()

  napis=tki.Label(hl_okno, text="Nejaky napis v okne")
  napis.pack(side="bottom", padx=40, pady=70)

  tlacitko=tki.Button(hl_okno, text="TEXT")
  tlacitko.pack(side="bottom", fill="x")

  hl_okno.mainloop()

V dolní části okna bude popiska napis, kolem ní bude spousta místa. Nahoře bude těsně pod lištou přilepené tlačítko, široké skoro stejně jako okno.

Metoda place()

Umožňuje přesné umístění prvku v okně. Některé nepovinné proměnné:

x, y
Souřadnicová vzdálenost daného ovládacího prvku od levého horního rohu okna.
anchor
Pro který bod ovládacího prvku se počítají hodnoty x a y. Možné hodnoty: "n" (počítá se bod nahoře uprostřed -sever), "ne" (nahoře vpravo - severovýchod), "e" (vpravo uprostřed - východ), "se" (jihovýchod, atd.), "s", "sw", "w", "nw", "center" (uprostřed prvku).
width, height
Šířka a výška daného prvku

Opět příklad:

  import Tkinter as tki

  hl_okno=tki.Tk()

  tlacitko=tki.Button(hl_okno, text="TEXT")
  tlacitko.place(x=25, y=25, width=40, height=40, anchor="center")

  hl_okno.mainloop()

Metoda grid()

Vyskládává prvky do dvojrozměrné tabulky. Proměnné:

row
Říká, do kterého řádku tabulky se má daný prvek umístit. Počítá se od nuly.
column
Říká, do kterého sloupce v daném řádku se má prvek umístit. Počítá se opět od nuly.
padx, pady
Mezera kolem daného prvku. Stejné jako u metody pack()
rowspan, columnspan
Říká, jestli daný prvek zabírá více než jeden řádek (row) nebo sloupec (colunm) a kolik jich zabírá. Požaduje integerové (celočíselné) hodnoty, pokud není zadán, automaticky předpokládá jedničku.
  import Tkinter as tki

  hl_okno=tki.Tk()

  napis1=tki.Label(hl_okno, text="Prvni napis")
  napis1.grid(row=0, column=0)

  male_tlacitko=tki.Button(hl_okno, text="xxx")
  male_tlacitko.grid(row=0, column=0, padx=10, pady=10)

  tlacitko1=tki.Button(hl_okno, text="TEXT 1")
  tlacitko1.grid(row=0, column=1, padx=10, pady=10)

  napis2=tki.Label(hl_okno, text="Druhy napis")
  napis2.grid(row=1, column=0)

  tlacitko2=tki.Button(hl_okno, text="TEXT 2")
  tlacitko2.grid(row=1, column=1)

  tlacitko3=tki.Button(hl_okno, text="TEXT 3")
  tlacitko3.grid(row=2, colunm=0, columnspan=2)

  hl_okno.mainloop()

Vyskládá prvky do tabulky. V prvním řádku budou v levé buňce napis1 a male_tlacitko s mezerou kolem sebe (budou se možná i překrývat), ve druhé buňce bude samotné tlacitko1. Ve druhém řádku budou napis2 a tlacitko2, každý ve své buňce. Ve třetím řádku bude uprostřed (přes dvě buňky) tlacitko3.

Upozornění!

V žádném případě se nedoporučuje používat metody grid() a pack() u ovládacích prvků v jednom okně! Modul Tkinter totiž není schopen zpracovávat v jednom okně zároveň obě metody. Program by nešel ani spustit.