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 3 - Aplikace Kalkulačka v tkinter - Tvoříme GUI

V předchozí lekci, Aplikace Kalkulačka v tkinter - MVC model, jsme si rozplánovali kalkulačku na základě knihovny tkinter pomocí MVC a sestavili jsme si třídy pro jednotlivé komponenty.

V následujícím tutoriálu GUI aplikací v Pythonu si pomocí knihovny tkinter začneme tvořit grafické uživatelské rozhraní aplikace Kalkulačka. Vytvoříme k ní odpovídající View (podle architektury MVC), ve kterém se začne odehrávat modelování aplikace.

Aplikace Kalkulačka - View

Nyní, když máme mozek kalkulačky hotový, je na čase se pustit do vizualizace aplikace a tvorby GUI. Seznámíme se s widgety jako je Button a Entry. Taktéž si povíme, jak je následně umístit a zobrazit v aplikaci. Vysvětlíme si, jak vázat námi nadefinovanou funkci s Button objektem.

Vytvoření třídy CalculatorView

Pojďme si vytvořit poslední třídu, kterou k našemu projektu potřebujeme! Postup již známe, ve složce Kalkulacka/ vytvoříme soubor calculatorview.py. V něm si založíme třídu CalculatorView. Třída bude sloužit k zobrazení uživatelského rozhraní kalkulačky. V konstruktoru třídy vytvoříme potřebné widgety (Entry pro zobrazení výrazu a tlačítka pro zadávání čísel a operací) a propojíme je s odpovídajícími metodami v Controlleru.

Ve třídě nadefinujeme konstruktor __init__, která přijímá hlavní okno aplikace (root) a instanci CalculatorController (controller) jako parametry:

class CalculatorView:
    def __init__(self, root, controller):
        self.controller = controller

Základy máme položené, pojďme se tedy vrhnout na vytváření jednotlivých tkinter widgetů.

Vstupní widget Entry

V konstruktoru třídy CalculatorView vytváříme vstupní widget Entry pomocí tk.Entry(root). Tento widget slouží k zobrazení aktuálního výrazu. Do widgetu Entry vložíme parametry width a font. Pomocí parametru width nakonfigurujeme šířku. Přiřadíme jí hodnotu 20.

Knihovna tkinter nemá metodu height(), která by změnila výšku vstupního pole.

Abychom nastavili výšku, použijeme parametr font. Jedná se o tuple vyžadující dva povinné argumenty:

  • název fontu,
  • velikost písma,
  • volitelně lze přidat styl psaní a navolit tučný text, či kurzívu.

My si vybereme font Arial o velikosti 14. Náš kód vypadá takto:

self.entry = tk.Entry(root, width=20, font=("Arial", 14))

Pozicování widgetů

Abychom mohli naše widgety vyobrazit na obrazovce, je nutné jim definovat layout. K tomu nám dopomůže už známá metoda grid(). Za použití této metody rozložíme widgety v mřížce (řádcích a sloupcích). Pomocí parametrů row a column určíme pozici widgetu. Jsme schopni taktéž nastavit další parametry, jako je sticky (určuje, jak se widget přizpůsobuje v buňce) a padx a pady (mezeru mezi widgety):

self.entry.grid(row=0, column=0, columnspan=5, padx=10, pady=10)

Columnspan vyjadřuje, přes kolik sloupců se widget může roztáhnout. Padx a pady zase vzdálenost od jiných widgetů.

Tlačítka

Vytvoříme seznam buttons, který bude obsahovat konfigurace jednotlivých tlačítek kalkulačky. Každá konfigurace je dictionary (slovník) obsahující text tlačítka a jeho umístění na mřížce (řádek a sloupec). Vybraná tlačítka mají také definovanou barvu pozadí (bg):

buttons = [
            {"text": "7", "row": 1, "col": 0},
            {"text": "8", "row": 1, "col": 1},
            {"text": "9", "row": 1, "col": 2},
            {"text": "/", "row": 1, "col": 3},
            {"text": "4", "row": 2, "col": 0},
            {"text": "5", "row": 2, "col": 1},
            {"text": "6", "row": 2, "col": 2},
            {"text": "*", "row": 2, "col": 3},
            {"text": "1", "row": 3, "col": 0},
            {"text": "2", "row": 3, "col": 1},
            {"text": "3", "row": 3, "col": 2},
            {"text": "-", "row": 3, "col": 3},
            {"text": "0", "row": 4, "col": 0},
            {"text": ".", "row": 4, "col": 1},
            {"text": "=", "row": 4, "col": 2},
            {"text": "+", "row": 4, "col": 3},
            {"text": "C", "row": 1, "col": 4, "bg": "#FF9500"},
            {"text": "AC", "row": 2, "col": 4, "bg": "#FF3B30"}
        ]

Usazení tlačítek na obrazovku

Vkládat na obrazovku tlačítka postupně by bylo zdlouhavé, že? Usnadněme si práci cyklem for. V tom procházíme všechna tlačítka v seznamu buttons. Pro každé tlačítko vytváříme widget Button pomocí tk.Button(). Tlačítku nadefinujeme šířku 5, výšku 2 a písmo Arial s velikostí 12. Widget je umístěn na daném řádku a sloupci. Nastavíme také vnitřní odsazení pomocí padx a pady:

for button in buttons:
    btn = tk.Button(root, text=button["text"], width=5, height=2, font=("Arial", 12))
    btn.grid(row=button["row"], column=button["col"], padx=5, pady=5)

Co když budeme chtít změnit barvu nějakých tlačítek? Změňme tlačítka s popisky C a AC. Těm nastavme hodnotu #FF9500 pro C a #FF3B30 pro AC pomocí parametru bg.

Hodnoty objektu lze měnit pomocí metod config() nebo configure(). Nastavme tedy zároveň hodnotu fg na "white" (Změní barvu popředí - textu). Text tak na barvě lépe vynikne. K zakomponování do kódu využijeme blok if, který provede operaci jen, když zaznamená patřičný vstup:

if "bg" in button:
    btn.configure(bg=button["bg"], fg="white")
Binding

Založíme událost Button-1 pomocí btn.bind(). Tím zajišťujeme, že při kliknutí na tlačítko se spustí metoda handle_button_click() (nastavuje se pro každé tlačítko):

btn.bind("<Button-1>", self.handle_button_click)

Metoda handle_button_click()

Nakonec si pojďme sestavit metodu, která bude zavolána při kliknutí na libovolné tlačítko:

def handle_button_click(self, event):
    value = event.widget.cget("text")
    if value == "C":
        self.controller.clear_input()
    elif value == "AC":
        self.controller.clear_all()
    else:
        self.controller.process_input(value)

Metoda funguje následovně:

  • event.widget.cget("text") vkládá do proměnné value hodnotu textu tlačítka,
  • if blok rozdělí vstup na hodnotu C, hodnotu AC a ostatní. V prvním scénáři zavoláme metodu clear_input(). V druhém pak clear_all(). V případě, že uživatel zmáčkne jakékoliv jiné tlačítko, zavoláme metodu process_input() v Controlleru s předanou hodnotou tlačítka. Tímto zajišťujeme správnou interakci mezi Controllerem a View.

Třída CalculatorView tedy slouží k vytvoření grafického uživatelského rozhraní kalkulačky pomocí Tkinter. Tlačítkům přiřazuje metody, které předávají uživatelský vstup příslušnému Controlleru pro zpracování. Tím je zajištěna oddělenost logiky aplikace od jejího grafického rozhraní.

Zbývá nám již jen vše poskládat dohromady. To si ale necháme na příště. Pro dnešek jsme odvedli krásný kus práce!

V další lekci, Aplikace Kalkulačka v tkinter - Sestavení projektu, si vytvoříme hlavní okno aplikace a instance modelu, pohledu a kontroleru, jež představují různé části kalkulačky. Propojíme je a využijeme metodu mainloop() pro udržování otevřeného okna aplikace.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 36x (2.6 kB)
Aplikace je včetně zdrojových kódů v jazyce Python

 

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