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í.

2. diel - Aplikácie Kalkulačka v PyQt

Zdravím vás u ďalšej lekcie PyQt. V lekcii minulej, Zoznámenie s PyQt, Inštalácia a prvé okenné aplikácie v Python , sme si urobili úvod do tvorby formulárových aplikácií v Pythone a naprogramovali okenné Hello world. V dnešnom tutoriále si, ako bolo sľubované, vytvoríme aplikáciu Kalkulačka, ktorá bude vykonávať nasledujúce matematické operácie:

  • súčet
  • rozdiel
  • súčin
  • podiel

Potrebné widgety

Pre lepšiu orientáciu sa môžete pozrieť na už hotový formulár:

Formulárová kalkulačka v Pythone a PyQt - Okenné aplikácie v Pythone

Aplikácia bude obsahovať nasledujúce widgety:

  • QWidget - Formulár
  • QLabel - Popisok, tu použitý na výpis výsledku
  • QPushButton - Tlačidlo pre výpočet
  • 2x QLineEdit - Jednoriadkové textové pole na zadanie čísla
  • QComboBox - Rozbaľovacia ponuka s výpočtovými operáciami
  • Layouty - Aby sme mohli widgety na formulár rozumne poskladať

Vytvorenie projektu

Vytvorte nový projekt, ja ten svoj uložím opäť ako main.py. Najprv si opäť importujete QWidgets z PyQt5 a sys. Dnes si importujete tiež QtGui, pretože ďalej zmeníme font nášho QLabelu s výsledkom.

from PyQt5 import QtWidgets, QtGui
import sys

Hoci sme minule pracovali čisto procedurálne, bez objektov, ako len jednoducho to išlo, je určite lepšie triedy pre svoje aplikácie používať. Okno aplikácie preto tentoraz vytvoríme ako triedu, dedičov z QtWidgets.QMainWindow. Ukážme si jej kód, ktorý si vzápätí popíšeme:

class Window(QtWidgets.QMainWindow):

    def __init__(self, **kwargs):
        super(Window, self).__init__(**kwargs)

        self.setWindowTitle("Kalkulačka v PyQt5")
        self.init_gui()
        self.show()

    def init_gui(self):
        formular = QtWidgets.QWidget()

V konstruktoru si necháme odovzdať prípadné argumenty z príkazového riadku a nastavíme titulok okna. Ďalšie inicializácii okná prenecháme metóde init_gui(). Nakoniec formulár zobrazíme. V metóde init_gui() vytvoríme formulár ako minule a uložíme si ho do premennej formular.

Layout

Celému formulári nastavíme layout na QVBoxLayout, V v názve označuje vertikálnej. Widgety na formulári sa budú teda skladať pod seba, na rozdiel od minulej lekcie, kde sme použili QHBoxLayout, kde H označovalo horizontálne. Následne pridáme do tohto zvislého layoutu ešte 2 vodorovné layouty. Tie budú teda pod sebou a widgety v nich vložené sa budú skladať vedľa seba.

Kód metódy init_gui() sa rozrastie do nasledujúcej podoby:

def init_gui(self):
    formular = QtWidgets.QWidget()
    formularLayout = QtWidgets.QVBoxLayout()
    formular.setLayout(formularLayout)

    boxLayout1 = QtWidgets.QHBoxLayout()
    boxLayout2 = QtWidgets.QHBoxLayout()

    formularLayout.addStretch()
    formularLayout.addLayout(boxLayout1)
    formularLayout.addLayout(boxLayout2)
    formularLayout.addStretch()

Ak ste sa v Layout stratili, pripravil som pre vás ilustráciu:

Layouty formulárové kalkulačky v Pythone a PyQt - Okenné aplikácie v Pythone

formularLayout radiacej widgety pod seba je zvýraznený červeno a layouty boxLayout1 a boxLayout2 v ňom vložené, vkladajúce widgety vedľa seba, sú vyznačené zelene.

Pomocou addStretch() pridáme voľné miesto, ktoré výsledok vycentruje zvisle. Na obrázku vyššie je toto voľné miesto zvýraznené modro.

Widgety

Máme hotové základné rozvrhnutie našej aplikácie, ktorá je vďaka použitiu layoutov responzívne. To znamená, že keď roztiahnete jej okno, layouty sa rovnomerne roztiahnu s ním a widgety v nich sa novej veľkosti tiež prispôsobí. Teraz vykonáme vloženie ďalších widgetov do layoutov:

def init_gui(self):
    formular = QtWidgets.QWidget()
    formularLayout = QtWidgets.QVBoxLayout()
    formular.setLayout(formularLayout)

    boxLayout1 = QtWidgets.QHBoxLayout()
    boxLayout2 = QtWidgets.QHBoxLayout()

    formularLayout.addStretch()
    formularLayout.addLayout(boxLayout1)
    formularLayout.addLayout(boxLayout2)
    formularLayout.addStretch()

    self.vysledekLabel = QtWidgets.QLabel("0", self)
    self.vysledekLabel.setFont(QtGui.QFont("Arial", 12, QtGui.QFont.Black))
    self.cislo1Edit = QtWidgets.QLineEdit(self)
    self.cislo2Edit = QtWidgets.QLineEdit(self)
    self.vypoctiButton = QtWidgets.QPushButton("Výpočet", self)
    self.operatorComboBox = QtWidgets.QComboBox(self)

    self.operatorComboBox.addItem("+")
    self.operatorComboBox.addItem("-")
    self.operatorComboBox.addItem("/")
    self.operatorComboBox.addItem("*")

    boxLayout1.addWidget(self.cislo1Edit)
    boxLayout1.addWidget(self.operatorComboBox)
    boxLayout1.addWidget(self.cislo2Edit)
    boxLayout1.addWidget(self.vysledekLabel)
    boxLayout2.addWidget(self.vypoctiButton)

    self.setCentralWidget(formular)

Vytvárame widgety, ktorých zoznam sme si uviedli v úvode lekcie. Do boxLayout1 vložíme textová políčka cislo1Edit a cislo2Edit, tiež operatorComboBox s výberom operácie a vysledekLabel. Všimnite si pridávanie položiek do operatorComboBox. Druhý riadok, boxLayout2, obsahuje len vypoctiButton.

Widgety sme pomenovali tak, aby končili názvom PyQt widgetu. To je dobrá praktika, je tak jasné čo je v ktorej premennej uložené. Keby sa vysledekLabel volal len vysledek, mohol by iný programátor predpokladať, že sa jedná len o číslo a nie formulárový prvok.

Možno vás zaujalo, že niektoré widgety sme uložili len ako lokálne premenné a niektoré sme uložili ako atribúty triedy pomocou kľúčového slova self. Je to preto, aby sme s nimi mohli v aplikácii ešte ďalej pracovať.

Posledný metóda setCentralWidget() nastavuje náš formulár ako hlavné okno a tým sa zobrazí po spustení aplikácie.

Na úplný koniec súboru dodáme niekoľko riadkov s tvorbou a spustenie aplikácie:

aplikace = QtWidgets.QApplication(sys.argv)
okno = Window()
sys.exit(aplikace.exec_())

Projekt si môžete teraz skúsiť spustiť, náš formulár vyzerá takto:

Formulárová kalkulačka v Pythone a PyQt - Okenné aplikácie v Pythone

Skúste si ho zmenšiť a zväčšiť, nech vidíte, že je naozaj responzívne.

Udalosti

Teraz je potrebné nastaviť tlačidlu vypoctiButton funkciu, ktorá sa zavolá pri udalosti kliknutí na toto tlačidlo. Týmto funkciám sa v programovaní často hovorí callback. Danú funkciu si zatiaľ len pripravíme a na konci metódy init_gui() ju nadviažeme na tlačidlo.

def init_gui(self):
    # Předešlý kód metody init_gui() ...
    # ...

    self.vypoctiButton.clicked.connect(self.vypocti)

def vypocti(self):
    pass

# Zbytek souboru
# ...

Pridáme logiku našej metódy vypocti():

def vypocti(self):
    vysledek = "";
    chyba = ""
    try:
        # do proměnných načteme hodnoty z ovládacích prvků
        cislo1 = float(self.cislo1Edit.text())
        cislo2 = float(self.cislo2Edit.text())
        operator = self.operatorComboBox.currentText()
        if (operator == "+"):
            vysledek = cislo1 + cislo2
        elif (operator == "-"):
            vysledek = cislo1 - cislo2
        elif (operator == "*"):
            vysledek = cislo1 * cislo2
        elif (operator == "/"):
            if (cislo2 == 0):
                chyba = "Chyba dělení 0"
            else:
                vysledek = cislo1 / cislo2
            else:
            chyba = "Chybná operace"
    except:
        # spustí se, pokud selže parsování na float()
        chyba = "Nebylo zadáno číslo!"
        if (chyba):
            self.vysledekLabel.setText(chyba) # zobrazení chyby
        else:
            self.vysledekLabel.setText(str(round(vysledek, 3))) # zobrazení výsledku zaokrouhleného na 3 desetinná místa

Najprv si vytvoríme pomocné premenné pre hodnoty, ktoré načítame z ovládacích prvkov. To aby sme ďalej neopisoval dlhé názvy a volanie ďalších metód. Z QLineEdit získame text pomocou metódy text(). Vybranú položku QComboBox získame metódou currentText(). Takmer celý kód je v bloku try, pretože funkcia float(), prevádzajúcej text z textových polí na číslo, môže spôsobiť chybu. V takom prípade program prejde ihneď do bloku except, chybu vypíše a výpočet sa vôbec neuskutoční. Na samotnom výpočte nie je nič moc zaujímavého, za zmienku stojí asi len ošetrenie proti delenie nulou.

máme hotovo :) Môžete si vyskúšať, že kalkulačka naozaj počíta a hlási prípadné chyby.

Hotová formulárové kalkulačka v PyQt pre Python - Okenné aplikácie v Pythone

V budúcej lekcii, GridLayout v PyQt - Formulár s využitím tabuľky , na nás čaká ďalší projekt, tentoraz oveľa väčšieho rozsahu. Nechajte sa prekvapiť :)

V budúcej lekcii, GridLayout v PyQt - Formulár s využitím tabuľky , využijeme QGridLayout pre jednoduchú tvorbu prehľadných formulárov.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 755x (3.66 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python

 

Predchádzajúci článok
Zoznámenie s PyQt, Inštalácia a prvé okenné aplikácie v Python
Všetky články v sekcii
Okenné aplikácie v Pythone
Preskočiť článok
(neodporúčame)
GridLayout v PyQt - Formulár s využitím tabuľky
Článok pre vás napísal MQ .
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Používám hlavně Python a zajímám se o Deep Learning a vše kolem.
Aktivity