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:
Š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
Na časť vyznačenú červeno na obrázku budeme potrebovať:
QHBoxLayout
- umožní vyčíňať labely vedľa sebaQLabel
- Popis s textom "Dnes je"QLabel
- Popisok s dnešným dátumomQLabel
- Popis s textom "Dnes je"QLabel
- Popisok s dnešným dátumomQHBoxLayout
- umožní vyčíňať labely vedľa sebaQLabel
- 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:
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.
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á
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