IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
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í.

11. diel - Úvod do tkinteru v Pythone

Vitajte u pokračovaní seriálu o Pythone. Teraz budeme pokračovať tvorbou používateľského rozhrania. V dnešnom diele si vytvoríme jednoduchú okenné aplikáciu s užívateľským rozhraním (GUI - Graphic User Interface). Až do teraz sme používali pre naše programy CLI (Command Line Interface). Pre tvorbu GUI aplikácií by ste mali poznať aspoň základy OOP v Pythone.

Balíčky pre tvorbu GUI

Naše programy si zatiaľ vystačili s obyčajnými vstavanými funkciami print () a input () pre vstup a výstup programu. Pre Python existujú asi tri najznámejšie multiplatformový balíky na tvorbu formulárových okenných aplikácií - tkinter (postavený na Tcl / Tk), wxPython (wxWidgets pre Python) a PyQt (Qt pre Python). Posledné dva menované sú přeportované z C ++. Každý z nich má svoje výhody a nevýhody. V tejto sekcii budeme používať tkinter. Z týchto troch menovaných je najjednoduchšie, ale na druhú stranu asi najviac zastaraný. Tkinter je väčšinou inštalovaný spoločne s Python. Ovládacie prvky v tkinteru nevyzerajú príliš pekne, ale môžeme si pomôcť použitím rozšírenie tkinteru - TTK a TIX. Na konci dielu použijeme TTK.

Tri hlavné vyššie spomínané balíčky (tkinter, wxPython a PyQt) sú multiplatformový, takže si samy zabezpečí požadovaný vzhľad podľa operačného systému.

Tvorba okná

Otvoríme si nový súbor. Syntax pre písanie GUI programov v tkinteru sa podobá WF v C# alebo Java Swing v Jave a všetok kód budeme písať ručne. :) Ale nebojte, tvorba prázdneho okna zaberie len pár riadkov.

Najskôr si ukážeme kompletné kód a ten si potom rozoberieme.

#!/usr/bin/env python3
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()

Rozbor

Prvé dva riadky sú celkom jasné. Prvá je shell bang a na druhom sa importuje knižnica tkinter.

#!/usr/bin/env python3
import tkinter

Na ďalších riadkoch si definujeme triedu, ktorá sa bude volať MainWindow. Táto trieda zvyčajne obsahuje rôzne formulárové prvky ako svoje atribúty. Keďže chceme, aby trieda MainWindow bola okno, tak ju musíme zdediť z triedy Frame (rám). Potom definujeme metódu __init __ (), ktorá sa zavolá pri inicializácii okna. V nej musíme zavolať inicializácii rodičia okná, ktorého dostaneme ako parameter pri vytváraní okna. Navyše si rodičia uložíme, aby sme mohli vykonávať ďalšie akcie, ako napríklad nastavenie titulku okna.

class MainWindow(tkinter.Frame):

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

Na konci súboru vytvoríme koreň aplikácie (root), ktorý nám obstaráva napr. Zobrazenia okna, minimalizáciu, ukončenie aplikácie ... Potom vytvoríme objekt aplikácie (app) a spustíme hlavné cyklus programu, metódu mainloop ().

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

GUI programy fungujú tak, že sa nachádzajú v nasledujúcom cykle: spracuj vstup, Army a vykresli. Vďaka tomu, že nás root od tohto cyklu odtieňuje, tak si ho nemusíme definovať ručne, na rozdiel napr. Od hier napísaných pomocou modulu pygame.

Náš program teraz vyzerá zhruba takto:

Jednoduché okno v tkinteru - Okenné aplikácie v Pythone

Teraz skúsime do nášho okna pridať jeden komponent. Tou komponentom bude label, čo je textový popis. Vytvoríme ďalšiu metódu a to create_widgets (). V tejto metóde bude prebiehať vytváranie komponentov. Túto metódu zavoláme na konci špeciálne metódy __init __ (). Takže náš kód bude vyzerať 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šetky komponenty, ktoré vytvoríme, budú atribúty triedy, ktorá danú komponent obsahuje. V tomto prípade bude label atribút triedy MainWindow.

Geometrické manažérov

Label sa nám zatiaľ nezobrazuje, pretože ho napred musíme do okna umiestniť. Môžeme použiť tri spôsoby:

Pack

Prvý spôsob je za pomoci použitia zabalenie (pack). Hodí sa pre vyplnenie nejaké iné komponenty (napr. Frame) alebo na skladanie komponentov vertikálne (zvislo) alebo horizontálne (vodorovne).

Label umiestnime tak, že na komponente zavoláme metódu pack.

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

výsledok:

tkinter – použitie pack - Okenné aplikácie v Pythone

Ďalej môžeme nastaviť rôzne parametre pre metódu pack. Tu sú niektoré z nich:

  • expand: Nastavuje, či ak komponent zaberie miesto v rodičmi, ak tam nejaké bude (True alebo False)
  • fill: Nastaví vyplnenie rodičovského okna. Možnosti sú: tkinter.NONE (nevyplnenie), tkinter.X (vodorovne), tkinter.Y (zvisle) alebo tkinter.BOTH (oba smery)
  • side: Určí, ku ktorej strane bude komponenta ukotvená. Možnosti sú: tkinter.TOP (horná hrana), tkinter.BOTTOM (spodná hrana), tkinter.LEFT (ľavá hrana) alebo tkinter.RIGHT (pravá hrana).

Ak chcete preskúmať ďalšie, stačí použiť funkciu help ().

Teraz do okna pridáme ďalšie label, aby sme videli, čo jednotlivé parametre robia. Navyše pridáme labelům farbu pozadia, tak presne uvidíme, aké miesto zaberajú.

Tu je pozmenený kód v metóde 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 roztiahnutiu bude okno vyzerať nejako takto:

tkinter v Pythone – Pack a ďalšie metódy - Okenné aplikácie v Pythone

Place

Druhý spôsob je za pomoci umiestnenie (place). Komponenta sa do okna umiestni pomocou zadania súradníc. Pre umiestnenie komponenty sa používa metóda place (). Tento spôsob sa hodí maximálne pre dialógy s pevným umiestnením komponentov.

Jej parametre sú:

  • x: Súradnice x
  • y: Súradnice y
  • anchor: Miesto v komponente, kde bude bod so súradnicami. Možnosti sú rovnaké, ako svetové strany: tkinter.N (sever), tkinter.S (juh), tkinter.W (západ), tkinter.E (východ), tkinter.NW (severozápad), tkinter.NE (severovýchod), tkinter.SW (juhozápad), tkinter.SE (juhovýchod) a tkinter.CENTER (stred).

Teraz vytvoríme 2 textové popisky, jeden bude mať ukotvenie hore a druhý dole. Kód v metóde 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.place(x=40, y=60, anchor=tkinter.N)
    self.label_2.place(x=40, y=60, anchor=tkinter.S)

Vidíte, že biely label je pod žltým, pretože biely má ten bod hore, zatiaľ čo žltý dole.

tkinter v Pythone – Ukážka place - Okenné aplikácie v Pythone

Grid

Tretí a najlepší spôsob je použitie mriežky / tabuľky (grid). Určíme jej veľkosť a do buniek tabuľky potom vkladáme jednotlivé komponenty. Jedna komponenta môže zaberať aj viac buniek a každý riadok alebo stĺpec môže mať inú váhu pri prideľovaní miesta.

Ale aby nám to fungovalo, musíme napred rodičmi nastaviť váhu riadkov a stĺpcov. Tú nastavíme pri inicializácii okna v metóde __init __ (). V našej aplikácii budeme chcieť mať dva labely danej pod seba, takže použijeme tabuľku 2x1 (2 riadky a 1 stĺpec).

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 riadkov a stĺpcov sa nastavujú cez metódy rowconfigure () (pre riadok) a columnconfigure () (pre stĺpec). Ako prvý pozičné parameter je číslo riadka / stĺpca a potom ako kľúčový parameter je jeho váha (weight). Tú sme pre riadky rozdelili rovnomerne na polovicu a stĺpci sme dali celú hodnotu.

V metóde create_widgets () potom použijeme metódu grid (). Nikdy nepoužívajte metódy pack () a grid () dohromady! Metóda grid () má tieto parametre:

  • row: číslo stĺpca
  • column: číslo riadky
  • rowspan: zabráni viac riadkov (ich počet)
  • columnspan: zabráni viac stĺpcov (ich počet)
  • sticky: zarovnanie v bunke; tkinter.N (sever), tkinter.S (juh), tkinter.W (západ), tkinter.E (východ), tkinter.NW (severozápad), tkinter.NE (severovýchod), tkinter.SW (juhozápad), tkinter .SE (juhovýchod) a tkinter.NSEW (zaberie celú bunku)
  • ďalej sú možné parametre: padx, pady (vonkajšie odsadenie) a ipadx, iPad (vnútorná odsadenie)

Teraz si ukážeme kompletný kód pre grid:

#!/usr/bin/env python3
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ýsledok vyzerá takto:

tkinter v Pythone – Ukážka grid - Okenné aplikácie v Pythone

Ďalšie možnosti okna

Oknu je vhodné nastaviť minimálnu veľkosť. Rovnako tak môžeme nastaviť aj maximálnu veľkosť a či pôjde okno rozťahovať.

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é

Ak chcete, aby sa vám nezobrazovala konzoly, musíte zmeniť príponu súboru z .py na .pyw

Nabudúce, v lekcii Tvorba kalkučky v tkinteru , sa pozrieme podrobnejšie na labely a tlačidlá a skúsime si napísať GUI kalkulačku.


 

Predchádzajúci článok
PyQt - Tabuľky v Pythone
Všetky články v sekcii
Okenné aplikácie v Pythone
Preskočiť článok
(neodporúčame)
Tvorba kalkučky v tkinteru
Článok pre vás napísal gcx11
Avatar
Užívateľské hodnotenie:
1 hlasov
(^_^)
Aktivity