IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

3. diel - PRIPOMIENKOVÉ narodenín v PyQt - Návrh formulárov

V minulej lekcii, Aplikácie Kalkulačka v PyQt , sme sa naučili obsluhovať udalosti a vytvorili jednoduchú kalkulačku. V dnešnom Python tutoriálu začneme v PyQt pracovať na aplikáciu k upomínania narodenín priateľov. Aplikácia bude vyzerať nasledovne:

Aplikácia na upomínania narodenín v Python a PyQt - Okenné aplikácie v Pythone

Štruktúra aplikácie

Vytvorte si nový projekt, ja súbor opäť pomenujem main.py. Ako vždy začneme formulári. Tentoraz už budeme mať v aplikácii dva, PrehledForm s prehľadom osôb a ich narodenín a OsobaForm k pridávanie nových osôb. Čo sa týka vytvorenia samotnej aplikácie, prejdeme ešte ďalej a aj tu dnes vytvoríme cez triedu App. Všetky tieto triedy si pripravíme a do triedy App pridáme metódu build(), ktorá nám našu aplikáciu spustí. Trieda App bude udržiavať inštancie našich ďalších tried, teraz formulárov.

from PyQt5 import QtWidgets, QtGui, QtCore
import sys

class OsobaForm(QtWidgets.QWidget):

    def __init__(self, **kwargs):
        super(OsobaForm, self).__init__(**kwargs)
        pass

    def setup(self):
        pass

class PrehledForm(QtWidgets.QMainWindow):

    def __init__(self, **kwargs):
        super(PrehledForm, self).__init__(**kwargs)
        pass

    def setup(self):
        self.osoba_form = root.osoba_form

class App(QtWidgets.QApplication):

    def __init__(self):
        super(App, self).__init__(sys.argv)

    def build(self):
        self.prehled_form = PrehledForm()
        self.osoba_form = OsobaForm()

        self.prehled_form.setup()
        self.osoba_form.setup()
        sys.exit(self.exec_())

root = App()
root.build()

Oba formuláre sú opäť vytvorené ako triedy dedičov z QtWidgets.QWidget. Okrem konstruktoru (metódy __init__()) v nich máme aj metódu setup(), ktorú spustíme až po vytvorenie všetkých formulárov. Týmto spôsobom k sebe budú môcť formuláre vzájomne pristupovať. Všimnite si, že v metóde build() triedy App() vytvoríme obaja formuláre a až potom obom zavoláme metódu setup(). Formulár PrehledForm si v nej uloží inštancii OsobaForm, ktorú si z aplikácie vytiahne pomocou kľúčového slova root. Formulár s prehľadom bude takto môcť formulár pre osobu otvárať pri kliknutí na tlačidlo "Pridať".

Kostru formulárov a aplikácie máme vytvorenú, aj keď aplikácia zatiaľ po spustení nič neurobí.

Návrh formulárov

Presuňme sa ku vkladaniu jednotlivých widgetov do formulárov.

Prehľadový formulár

Prehľadový formulár je základná okno aplikácie s prehľadom osôb a ich narodenín. Budeme potrebovať nasledujúce ovládacie prvky:

  • 8x QLabel - Popisky
  • 2x QPushButton - Tlačidlo na pridanie a odobratie osoby
  • 1x QListWidget - Zoznam osôb
  • 1x QCalendarWidget - Kalendár

Layout

Ako prvý musíme samozrejme vytvoriť systém layoutov, aby sa widgety vo formulári správne poskladali. Keďže všetky GUI tu píšeme ako kód a nepoužívame žiaden GUI designer, budeme postupovať jednoducho zhora nadol a zľava doprava. Celému formulári nastavíme QVBoxLayout, čím sa v ňom ďalšie layouty budú radiť pod seba. V tomto formulári budeme box layouty využívať často.

Informačné boxy

Layout labelov v PyQt formulári - Okenné aplikácie v Pythone

Na časť vyznačenú červeno na obrázku budeme potrebovať:

  • QHBoxLayout - umožní vyčíňať labely vedľa seba QLabel - Popis s textom "Dnes je"

    QLabel - Popisok s dnešným dátumom

  • QLabel - Popis s textom "Dnes je"
  • QLabel - Popisok s dnešným dátumom
  • QHBoxLayout - umožní vyčíňať labely vedľa seba QLabel - Popis s textom "Najbližšie narodeniny"

    QLabel - Popisok s najbližšími narodeninami (zatiaľ nebude použitý)

  • QLabel - Popis s textom "Najbližšie narodeniny"
  • QLabel - Popisok s najbližšími narodeninami (zatiaľ nebude použitý)

Najprv si na začiatok súboru pridajte:

import datetime

Tým sme si importovali funkcionalitu pre prácu s dátumom a časom a budeme schopní do QLabelu zobraziť čo je dnes za deň. Ukážme si teraz upravený kód triedy PrehledForm, ktorý si následne podrobne popíšeme.

class PrehledForm(QtWidgets.QMainWindow):

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

        # Titulek, ikonka a minimální šířka okna
        self.setWindowTitle("Výročí")
        self.setWindowIcon(QtGui.QIcon("icon.png"))
        self.setMinimumWidth(650)

        # Vytvoříme hlavní widget a nastavíme BoxLayout
        formular = QtWidgets.QWidget()
        layoutFormulare = QtWidgets.QVBoxLayout()
        formular.setLayout(layoutFormulare)
        self.setCentralWidget(formular)

        # Vytvoříme informační box s BoxLayoutem (Dnešní datum)
        self.dnesLayout = QtWidgets.QHBoxLayout()
        layoutFormulare.addLayout(self.dnesLayout)
        self.dnesLayout.addWidget(QtWidgets.QLabel("Dnes je:"))
        self.dnesLayout.addStretch()
        self.dnesLabel = QtWidgets.QLabel(self.get_current_date())
        self.dnesLayout.addWidget(self.dnesLabel)

        # Vytvoříme informační box s BoxLayoutem (Nejbližší narozeniny)
        self.narozeninyLayout = QtWidgets.QHBoxLayout()
        layoutFormulare.addLayout(self.narozeninyLayout)
        self.narozeninyLayout.addWidget(QtWidgets.QLabel("Nejbližší narozeniny:"))
        self.narozeninyLayout.addStretch()
        self.nejblizsiLabel = QtWidgets.QLabel("")
        self.narozeninyLayout.addWidget(self.nejblizsiLabel)

        self.show()

    def get_current_date(self):
        return (str(datetime.datetime.now().day) + "." + str(datetime.datetime.now().month)
        + "." + str(datetime.datetime.now().year))

    # Získá požadované instance
    def setup(self):
        self.osoba_form = root.osoba_form

Prvá trojica riadkov nastaví názov okna, jeho ikonku a minimálnu šírku, aby sa okno nedalo zmenšiť tak, že by sa do neho obsah nevošiel. Ikonku, ktorá sa vám páči, si môžete nájsť na https://www.iconfinder.com/ alebo si stiahnuť ikony priložené v dnešnom archíve. Súbor potom stačí umiestniť do zložky so súborom main.py. Keď ju nenastavíte alebo dokonca aj keď ju nastavíte a nenahráš, vadiť to nebude.

Ďalšie riadky vytvárajú samotný formulár a nastavujú mu QVBoxLayout pre radenie widgetov (presnejšie ďalších layoutov) pod seba. Formulár sa následne nastaví aplikáciu ako predvolený.

Prvé informačné boxík s dnešným dátumom vytvárame teda ako QHBoxLayout. Na kódu je zaujímavé asi len to, že aby boli QLabel y oproti sebe, je medzi ne vložené prázdne miesto pomocou addStretch().

Nakoniec nasleduje vytvorenie druhého boxíkov s dnešnými narodeninami, situácia je tu úplne rovnaká ako v boxu predchádzajúcom.

Metóda get_current_date() vráti aktuálny dátum v slovenskom formáte (mm.dd.rrrr) a mala by byť z kódu zrozumiteľná.

Ak spustíte aplikáciu, zobrazia sa vám nasledujúce okienko:

Prehľadový formulár PRIPOMIENKOVÉ narodenín v Pythone - Okenné aplikácie v Pythone

ListWidget, kalendár a informácie o osobe

Základné informácie máme hotové a teraz vytvoríme layouty pre QListWidget, kalendár a informácie o aktuálne vybranej osobe.

Prostredná časť formulára PRIPOMIENKOVÉ narodenín v Pythone - Okenné aplikácie v Pythone

Vytvoríme QHBoxLayout, ktorý bude obsahovať jednotlivé BoxLayouty s widgety.

  • QHBoxLayout
    • QHBoxLayout
      • QListWidget
    • QVBoxLayout
      • QHBoxLayout
        • QLabel
        • QLabel
      • QHBoxLayout
        • QLabel
        • QLabel
      • QCalendarWidget
# Předchozí kód metody __init__() třídy PrehledForm
# ...

# Společný layout pro osobyListBox a narozenMonthCalendar
self.prostredniLayout = QtWidgets.QHBoxLayout()
layoutFormulare.addLayout(self.prostredniLayout)

# Vytvoříme layout pro osobyListBox
self.jmenaLayout = QtWidgets.QHBoxLayout()
self.osobyListBox = QtWidgets.QListWidget()
self.jmenaLayout.addWidget(self.osobyListBox)
self.prostredniLayout.addLayout(self.jmenaLayout)

# Vytvoříme layout pro narozenMonthCalendar
self.kalendarLayout = QtWidgets.QVBoxLayout()
self.narozenMonthCalendar = QtWidgets.QCalendarWidget(self)
self.narozenMonthCalendar.setEnabled(False)

# Vytvoříme layout pro informace o osobách
self.osobaLayout = QtWidgets.QHBoxLayout()
self.osobaLayout.addWidget(QtWidgets.QLabel("Narozen:"))
self.osobaLayout.addStretch()
self.narozeninyLabel = QtWidgets.QLabel("")
self.osobaLayout.addWidget(self.narozeninyLabel)
self.kalendarLayout.addLayout(self.osobaLayout)
self.osobaLayout2 = QtWidgets.QHBoxLayout()
self.osobaLayout2.addWidget(QtWidgets.QLabel("Věk:"))
self.osobaLayout2.addStretch()
self.vekLabel = QtWidgets.QLabel("")
self.osobaLayout2.addWidget(self.vekLabel)

self.kalendarLayout.addLayout(self.osobaLayout2)
self.kalendarLayout.addWidget(self.narozenMonthCalendar)
self.prostredniLayout.addLayout(self.kalendarLayout)

self.show()

Naše počínanie je veľmi podobné ako u informačného boxu. Pre celú prostredná časť sme si vytvorili QHBoxLayout, aby sa jej súčasti mohli radiť vedľa seba. Pridanie QListWidget je triviálne. Ďalšie widgety vpravo sú komplikované len kvôli layoutům. Je tu treba vložiť ďalšie QVBoxLayout, ktorý umožní zobraziť dva layouty s labely a tretí s kalendárom pod sebou. U kalendára je zaujímavé zrejme len to, že sme mu nastavili setEnabled(False), aby sa na ňom dátum narodenia vybranej osoby zobrazovalo, ale nedalo sa vybrať iné.

Náš formulár PrehledForm je skoro hotový, stačí len pridať tlačidlá :)

Rozpracovaný prehľadový formulár upomienku narodeniny v PyQt - Okenné aplikácie v Pythone

Formuláre dokončíme v budúcej lekcii, PRIPOMIENKOVÉ narodenín v PyQt - Dokončenie návrhu 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é 168x (6.11 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Python

 

Predchádzajúci článok
Aplikácie Kalkulačka v PyQt
Všetky články v sekcii
Okenné aplikácie v Pythone
Preskočiť článok
(neodporúčame)
PRIPOMIENKOVÉ narodenín v PyQt - Dokončenie návrhu formulárov
Č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