Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 1 - Úvod do tvorby GUI pomocí knihovny tkinter v Pythonu

Vítejte u prvního tutoriálu kurzu tvorby GUI aplikací v Pythonu. Naučíme se v něm tvořit uživatelské rozhraní pro aplikace. Využijeme k tomu knihovnu Pythonu tkinter.

Požadavky pro úspěšné absolvování kurzu

K úspěšnému zvládnutí tohoto kurzu potřebujeme znalosti v rozsahu kurzů Základní konstrukce jazyka Python a Objektově orientované programování v Pythonu. Na škodu není ani znalost grafického designu, včetně barev, typografie, uspořádání prvků a podobně. To nám umožní vytvářet esteticky působivé a funkční aplikace.

Balíčky pro tvorbu GUI

Naše programy si zatím vystačily s obyčejnými vestavěnými funkcemi print() a input() pro vstup a výstup programu. Je načase si ukázat také tvorbu grafického rozhraní. Pro Python existují tři nejznámější balíčky na tvorbu formulářových okenních aplikací - tkinter, wxPython a PyQt. Poslední dva jmenované jsou přeportované z C++. Každý z nich má své výhody a nevýhody. V tomto kurzu budeme používat knihovnu tkinter. Ze všech tří jmenovaných je nejjednodušší, ale na druhou stranu také nejvíce zastaralá. Tato knihovna je většinou instalovaná společně s Pythonem.

Všechny tři výše zmíněné balíčky jsou multiplatformní, takže si samy zajistí požadovaný vzhled podle operačního systému.

Co znamená zkratka GUI?

GUI (zkratka pro Grafical User Interface) je typ uživatelského rozhraní, které umožňuje interakci s počítačem pomocí grafických prvků.

Uživatelé mohou k ovládání aplikace a provádění funkcí používat myš, klávesnici a dotykové obrazovky. GUI se používá pro většinu moderních aplikací a umožňuje snadnou a intuitivní interakci s počítačem, díky čemuž mohou s programem pracovat i lidé, kteří nerozumí psaní a manipulaci s kódem.

Knihovna tkinter

Hlavní výhodou použití knihovny tkinter při tvorbě GUI aplikací v Pythonu je její nenáročnost. Výhod je ale více:

  • jednoduchost a snadnost použití: knihovna poskytuje mnoho předdefinovaných widgetů a funkcí, což zjednodušuje proces tvorby aplikací,
  • platformní nezávislost: knihovna je součástí standardní distribuce Pythonu a funguje na všech platformách,
  • flexibilita: knihovna umožňuje vytvářet aplikace s různým rozložením a funkcionalitou,
  • snadná integrace s jinými knihovnami a moduly: knihovnu můžeme snadno integrovat s jinými knihovnami a moduly v jazyce Python, díky čemuž jsme schopni vytvářet komplexní aplikace s různými funkcemi.

Mezi nevýhody knihovny tkinter pak patří:

  • omezené možnosti vzhledu,
  • nízká úroveň abstrakce,
  • nedostatečná dokumentace,
  • omezená podpora pro komplexní aplikace.

Jak jsme si již řekli, tkinter je součástí standardní instalace Pythonu. Otevřeme si tedy v našem IDE nový projekt a dostupnost knihovny si ověříme importem:

import tkinter

Pokud by IDE vypsalo chybu, doinstalujeme tkinter v něm nebo pomocí pip v terminálu:

Instalace tkinter:
pip install tkinter

Tvorba okna

Syntaxe pro psaní GUI programů pomocí tkinter se podobá WPF v C# nebo Java Swing v Javě a všechen kód budeme psát ručně :) Tvorba prázdného okna ale i tak zabere jen pár řádek.

Nejdříve si ukážeme kompletní kód a ten si poté rozebereme:

import tkinter

class MainWindow(tkinter.Frame):

    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent
        self.parent.title("První GUI aplikace")

root = tkinter.Tk()
app = MainWindow(root)
app.mainloop()

Nejprve tedy importujeme knihovna tkinter. Na dalších řádcích si definujeme třídu, která se bude jmenovat MainWindow. Tato třída obvykle obsahuje různé formulářové prvky jako své atributy. Jelikož chceme, aby třída MainWindow byla okno, musíme ji zdědit ze třídy Frame (rám). Potom definujeme konstruktor __init__(), který se zavolá při inicializaci okna. V něm musíme zavolat inicializaci rodiče okna, kterého dostaneme jako parametr při vytváření okna. Navíc si rodiče uložíme, abychom mohli provádět další akce, jako například nastavení titulku okna.

Poté vytvoříme kořen aplikace (root, instance třídy Tk), který nám obstarává mj. zobrazení okna, minimalizaci a ukončení aplikace. Pak vytvoříme instanci aplikace (app) a spustíme hlavní cyklus programu, metodu mainloop().

GUI programy fungují tak, že se nacházejí v následujícím cyklu:

  • zpracuj vstup,
  • aktualizuk,
  • vykresli.

Díky tomu, že nás root od tohoto cyklu odstiňuje, nemusíme ho definovat ručně (na rozdíl např. od her napsaných pomocí modulu Pygame).

Náš program nyní vypadá takto:

Jednoduché okno v tkinteru - Tkinter - Okenní aplikace v Pythonu

Nyní do našeho okna přidáme komponentu label, což je textový popisek. Vytvoříme další metodu a nazveme ji create_widgets(). V této metodě bude probíhat vytváření komponent. Metodu zavoláme na konci konstruktoru __init__(). Náš kód bude vypadat takto:

import tkinter

class MainWindow(tkinter.Frame):

    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent
        self.parent.title("První GUI aplikace")
        self.create_widgets()

    def create_widgets(self):
        self.label = tkinter.Label(text="Hello world!")

root = tkinter.Tk()
app = MainWindow(root)
app.mainloop()

Všechny komponenty, které vytvoříme, budou atributy třídy, která danou komponentu obsahuje. V našem případě bude label atribut třídy MainWindow.

Geometrické manažery

Náš label se zatím nezobrazuje, protože ho napřed musíme do okna umístit. K dispozici máme tři způsoby.

Metoda pack()

První způsob je za pomoci zabalení metodou pack(). Komponentu label tedy umístíme tak, že na ní zavoláme metodu pack():

def create_widgets(self):
    self.label = tkinter.Label(text="Hello world!")
    self.label.pack()

Výsledek vypadá takto:

tkinter – použití pack - Tkinter - Okenní aplikace v Pythonu

Metoda pack() má různé dostupné parametry. Zde jsou hlavní z nich:

  • expand nastaví, zda-li komponenta zabere místo v rodiči, pokud tam nějaké bude (True nebo False),
  • fill nastaví vyplnění rodičovského okna jako: tkinter.NONE (nevyplňovat), tkinter.X (vodorovně), tkinter.Y (svisle) nebo tkinter.BOTH (oba směry),
  • side určí, ke které straně bude komponenta ukotvená: tkinter.TOP (horní hrana), tkinter.BOTTOM (spodní hrana), tkinter.LEFT (levá hrana) nebo tkinter.RIGHT (pravá hrana).

Nyní do okna přidáme další label, abychom viděli, co jednotlivé parametry dělají. Navíc přidáme popiskům barvu pozadí, takže přesně uvidíme, jaké místo zabírají.

Zde je pozměněný kód v metodě create_widgets():

def create_widgets(self):
    self.label_1 = tkinter.Label(text="Hello world!", bg="white") # bílý label
    self.label_2 = tkinter.Label(text="Hello world!", bg="yellow") # žlutý label
    # nastavení geometrie
    self.label_1.pack(side=tkinter.TOP, fill=tkinter.X, expand=True)
    self.label_2.pack(side=tkinter.BOTTOM, fill=tkinter.Y, expand=True)
    print(help(self.label_1.pack)) # zde je kód pro nápovědu

Po roztáhnutí bude okno vypadat takto:

tkinter v Pythonu – Pack a další metody - Tkinter - Okenní aplikace v Pythonu

Metoda place()

Druhý způsob umístění komponent je za pomoci metody place(). Komponenta se do okna umístí pomocí zadání souřadnic. Tento způsob se hodí maximálně pro dialogy s pevným umístěním komponent.

Parametry metody jsou:

  • souřadnice x,
  • souřadnice y,
  • anchor - neboli místo v komponentě, kde bude bod se souřadnicemi. Možnosti jsou stejné, jako světové strany: tkinter.N (sever), tkinter.S (jih), tkinter.W (západ), tkinter.E (východ), tkinter.NW (severozápad), tkinter.NE (severovýchod), tkinter.SW (jihozápad), tkinter.SE (jihovýchod) a tkinter.CENTER (střed).

Nyní vytvoříme dva textové popisky, jeden bude mít ukotvení nahoře a druhý dole. Kód v metodě create_widgets() bude vypadat takto:

def create_widgets(self):
    self.label_1 = tkinter.Label(text="Hello world!", bg="white")
    self.label_2 = tkinter.Label(text="Hello world!", bg="yellow")
    self.label_1.place(x=40, y=60, anchor=tkinter.N)
    self.label_2.place(x=40, y=60, anchor=tkinter.S)

Vidíme, že bílý label je pod žlutým, jelikož bílý má kotevní bod nahoře, zatímco žlutý dole:

tkinter v Pythonu – Ukázka place - Tkinter - Okenní aplikace v Pythonu

Metoda grid()

Třetím a nejlepším způsobem umístění komponent je použití mřížky/tabulky pomocí metody grid(). Metoda rozdělí okno (nebo jakýkoli jiný widget) na mřížku řádků a sloupců. Komponenty pak umístíme na specifické pozice v této mřížce použitím parametrů řádků a sloupců (row a column). Jedna komponenta může zabírat i více buněk a každý řádek nebo sloupec může mít jinou váhu při přidělování místa.

Váhu řádků a sloupců nastavíme při inicializaci okna v konstruktoru __init__(). Váha určuje, jak se přidělí dodatečné místo v okně nebo rámu mezi jednotlivé řádky nebo sloupce, když uživatel zvětší velikost okna. V naší aplikaci budeme chtít mít dvakrát label pod sebou, takže použijeme tabulku 2x1 (dva řádky a jeden sloupec):

def __init__(self, parent):
    super().__init__(parent)
    self.parent = parent
    self.parent.title("První GUI aplikace")
    self.parent.rowconfigure(0, weight=500)
    self.parent.rowconfigure(1, weight=500)
    self.parent.columnconfigure(0, weight=1000)
    self.create_widgets()

Váhy řádků a sloupců se nastavují přes metody rowconfigure() a columnconfigure(). Jako první poziční parametr je číslo řádku/sloupce a poté jako klíčový parametr je jeho váha (weight). Tu jsme pro řádky rozdělili rovnoměrně na polovinu a sloupci jsme dali celou hodnotu.

Metody pack() a grid() nelze použít dohromady!

Metoda grid() má tyto parametry:

  • row: číslo sloupce,
  • column: číslo řádky,
  • rowspan: zabrání více řádků (jejich počet),
  • columnspan: zabrání více sloupců (jejich počet),
  • sticky: zarovnání v buňce; tkinter.N (sever), tkinter.S (jih), tkinter.W (západ), tkinter.E (východ), tkinter.NW (severozápad), tkinter.NE (severovýchod), tkinter.SW (jihozápad), tkinter.SE (jihovýchod) a tkinter.NSEW (zabere celou buňku)
  • odsazení: padx, pady (vnější odsazení) a ipadx, ipady (vnitřní odsazení).

Nyní si ukážeme kompletní kód pro grid:

import tkinter

class MainWindow(tkinter.Frame):

    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent
        self.parent.title("První GUI aplikace")
        self.parent.rowconfigure(0, weight=500)
        self.parent.rowconfigure(1, weight=500)
        self.parent.columnconfigure(0, weight=1000)
        self.create_widgets()

    def create_widgets(self):
        self.label_1 = tkinter.Label(text="Hello world!", bg="white")
        self.label_2 = tkinter.Label(text="Hello world!", bg="yellow")
        self.label_1.grid(row = 0, column = 0, sticky=tkinter.NSEW)
        self.label_2.grid(row = 1, column = 0, sticky=tkinter.NSEW)

root = tkinter.Tk()
app = MainWindow(root)
app.mainloop()

Výsledek vypadá takto:

tkinter v Pythonu – Ukázka grid - Tkinter - Okenní aplikace v Pythonu

Další možnosti okna

Oknu je také vhodné nastavit minimální, případně maximální velikost. Stejně tak můžeme nastavit i zda půjde okno roztahovat:

self.parent.minsize(500, 200) # minimální velisost
self.parent.maxsize(1000, 600) # maximální velikost
self.parent.resizable(True, True) # je okno měnitelné

Pokud chceme, aby se nám při spuštění skriptu nezobrazovala konzole, musíme změnit příponu souboru z .py na .pyw.

V další lekci, Aplikace Kalkulačka v tkinter - MVC model,si rozplánujeme kalkulačku na základě knihovny tkinter pomocí MVC a sestavíme si třídy pro jednotlivé komponenty.


 

Všechny články v sekci
Tkinter - Okenní aplikace v Pythonu
Přeskočit článek
(nedoporučujeme)
Aplikace Kalkulačka v tkinter - MVC model
Článek pro vás napsal gcx11
Avatar
Uživatelské hodnocení:
48 hlasů
(^_^)
Aktivity