Lekce 2 - Aplikace Kalkulačka v tkinter - MVC model
V minulé lekci, Úvod do tvorby GUI pomocí knihovny tkinter v Pythonu, jsme si představili úvod do práce s knihovnou
tkinter
.
V následujícím tutoriálu GUI aplikací v Pythonu si
pomocí knihovny tkinter
začneme tvořit aplikaci Kalkulačka.
Využijeme k tomu architekturu MVC. Jako první krok si
sestavíme třídy pro jednotlivé komponenty.
Aplikace Kalkulačka
pomocí knihovny tkinter
Svou cestu do hlubin GUI aplikací v tkinter
započneme u
užitečného a často využívaného nástroje. Naše první aplikace bude
Kakulačka. Nejprve si naplánujeme, jak budeme při tvorbě tohoto projektu
postupovat. Aplikaci totiž zpracujeme na základě architektury
MVC
(Model-View-Controller).
Více o architektuře se dozvíme v lekci MVC architektura). Aplikaci
rozdělíme do tří nezávislých bloků, kterými budou:
- datový model aplikace,
- uživatelské rozhraní,
- řídící logika.
MVC je softwarová architektura, která rozděluje layout projektu do tří komponent. Tento postup nám umožní modifikovat jedné z nich s minimálním vlivem na ostatní.
Naše konečná verze aplikace bude zanedlouho vypadat takto:
Model - správa dat kalkulačky
Začněme tím, že si v rámci nového projektu ve složce
Kalkulacka/
založíme soubor calculatormodel.py
.V
něm vytvoříme novou třídu CalculatorModel
s konstruktorem
__init__
, který inicializuje atribut expression
(budoucí výraz pro výpočet) jako prázdný řetězec:
import tkinter as tk class CalculatorModel: def __init__(self): self.expression = ""
Metoda add_to_expression()
Dále ve třídě CalculatorModel
vytvoříme metodu
add_to_expression()
, která nám poslouží k přidání
uživatelova vstupu do výrazu. Metoda přijímá parametr value
,
který reprezentuje uživatelův vstup, a připojuje ho k existujícímu
výrazu:
def add_to_expression(self, value): self.expression += str(value)
Metoda
evaluate_expression()
Následující kód bude zodpovědný za vyhodnocení výrazu a aktualizaci
výsledku. Metoda evaluate_expression()
používá funkci
eval()
k vyhodnocení výrazu jako výrazu v jazyce Python.
Výsledek je uložen jako string
v atributu
expression
. Pomocí bloku except
zajistíme, aby
kalkulačka správně zareagovala při všech možných scénářích. Do
atributu expression
vložíme text, jenž nám objasní příčinu
chyby:
- ZeroDivisionError upozorní uživatele na chybu, pokud se snaží dělit nulou,
- SyntaxError se vyvolá, pokud vložený znak bude neplatný, např. písmeno,
- Exception as e využijeme v případě, že se naskytne jiná chyba.
Kód metody bude vypadat takto:
def evaluate_expression(self): try: result = eval(self.expression) self.expression = str(result) except ZeroDivisionError: self.expression = "Error: Division by zero" except SyntaxError: self.expression = "Error: Invalid syntax" except Exception: self.expression = "Error:" + str(e)
Shrnutí datového modelu
Díky modelu zabalujeme stav kalkulačky a chování souvisejících s manipulací s výrazem. Model nám umožňuje přidávat vstupy do výrazu. Ty se následně vyhodnotí pro získání výsledku. Model neinteraguje s uživatelským rozhraním ani neprovádí žádné operace specifické pro grafické rozhraní. Hlavní úkol jsme stanovili tak, aby model spravoval výraz a prováděl výpočty.
Oddělením Modelu od View (uživatelského rozhraní) a Controlleru (řídící logiky) dodržujeme principy architektonického vzoru MVC, což umožňuje modulární a organizovanou strukturu kódu.
Controller - řídící logika kalkulačky
Třída CalculatorController
, která tvoří
Controller v MVC nám poslouží jako prostředník mezi
Modelem (CalculatorModel
) a uživatelským
rozhraním - View (CalculatorView
). Třída
CalculatorController
zprostředkovává komunikaci mezi těmito
dvěma částmi aplikace.
Začneme opět tím, že ve složce Kalkulacka/
vytvoříme
nový soubor s názvem calculatorcontroller.py
. V něm si
následně připravíme třídu CalculatorController
. V ní
nadefinujeme konstruktor __init__
, který přijímá instanci
Modelu a View jako parametry a ukládá je jako atributy:
import tkinter as tk class CalculatorController: def __init__(self, model, view): self.model = model self.view = view
Metoda process_input()
Tuto metodu si nastavíme tak, že bude zodpovědná za zpracování výrazu
v Modelu na základě uživatelových vstupů. Jestliže je
náš vstup =
(rovná se), zavoláme metodu
evaluate_expression()
v modelu pro vyhodnocení výrazu. V
opačném případě zavoláme metodu
add_to_expression()
v modelu pro přidání zadané hodnoty k
výrazu. Po zadání vstupu zavoláme metodu update_view()
pro
aktualizaci zobrazení:
def process_input(self, value): if value == "=": self.model.evaluate_expression() else: self.model.add_to_expression(value) self.update_view()
Metoda clear_input()
Uživatelé jistě ocení, když budou schopni vymazat například špatně vložené cifry, případně odstranit starý výpočet a začít kalkulovat nový. Naše další funkce odstraní poslední znak z výrazu v modelu.
Využijeme k tomu sekvenční indexování ([:-1]
), které
odstraní poslední znak z výrazu. Po dokončení operace zavoláme metodu
update_view()
pro aktualizaci zobrazení:
def clear_input(self): self.model.expression = self.model.expression[:-1] self.update_view()
Metoda clear_all()
Dokázali jsme vymazat poslední znak, výborně! Ale co takhle celý vstup?
Nebojme se ničeho, není v tom žádná věda. Potřebujeme jen nastavit
atribut expression
na prázdný string
a následně
aktualizovat zobrazení. Toho docílíme následovně:
def clear_all(self): self.model.expression = "" self.update_view()
Metoda update_view()
Naším posledním úkolem pro tuto třídu zůstalo nadefinovat metodu pro aktualizaci zobrazení výsledků. Nejprve smažeme obsah vstupního widgetu a poté vložíme aktuální výraz z modelu:
def update_view(self): self.view.entry.delete(0, tk.END) self.view.entry.insert(0, self.model.expression)
Krátké shrnutí
Díky tomu, že jsme oddělili logiku aplikace (Model) od uživatelského rozhraní (View), je pro nás nyní jednodušší správa a údržba kódu. Controller pro nás propojuje tyto dvě části. Následně umožňuje vzájemnou komunikaci a spolupráci při vývoji kalkulačky.
Mozek kalkulačky máme připravený. Příště už začneme tvořit uživatelské rozhraní, kvůli kterému jsme tady. Pro dnešek jsme ale udělali práce dost 😎
V další lekci, Aplikace Kalkulačka v tkinter - Tvoříme GUI, si vytvoříme uživatelské rozhraní pro aplikaci Kalkulačka. Naprogramujeme hlavní okno aplikace, vstupní pole a tlačítka. Těm dosadíme patřičné funkce.