Lekce 5 - Upomínač narozenin v PyQt - Dokončení návrhu formulářů
V minulé lekci, Upomínač narozenin v PyQt - Návrh formulářů, jsme rozpracovali návrh prvního z formulářů aplikace v PyQt pro upomínání narozenin osob.
Dnes naprogramujeme zobrazování druhého formuláře přes tlačítko.
Tlačítka a ikonky
Do formuláře PrehledForm přidáme 2 tlačítka. Jedno bude
přidávat osoby a to druhé je odstraňovat. Obě tlačítka budou mít ikonky,
které si můžete opět buď stáhnout na https://www.iconfinder.com/ nebo v
archivu se zdrojovým kódem na konci článku.
Asi vás nepřekvapí, že tlačítka vložíme do QHBoxLayout,
aby se poskládala vedle sebe. Struktura aktuálně přidávané části
formuláře vypadá následovně:
QHBoxLayoutQPushButtonQPushButton
Je to ta část znázorněná na obrázku níže červeně:

Do metody __init__() třídy PrehledForm přidáme
následující kód nad volání self.show():
# Původní kód metody # ... # Přidávání tlačítek self.tlacitkaLayout = QtWidgets.QHBoxLayout() self.pridatButton = QtWidgets.QPushButton("Přidat") self.pridatButton.setMinimumHeight(50) self.pridatButton.setIcon(QtGui.QIcon("pridej.png")) self.pridatButton.setIconSize(QtCore.QSize(32,32)) self.odebratButton = QtWidgets.QPushButton("Odebrat") self.odebratButton.setMinimumHeight(50) self.odebratButton.setIcon(QtGui.QIcon("odeber.png")) self.odebratButton.setIconSize(QtCore.QSize(32,32)) self.tlacitkaLayout.addWidget(self.pridatButton) self.tlacitkaLayout.addWidget(self.odebratButton) layoutFormulare.addLayout(self.tlacitkaLayout) self.show()
Na kódu tlačítek není nic složitého, všimněte si jen nastavení
výšky tlačítek a velikosti ikonek. Nyní je náš formulář
PrehledForm hotov. Vrhněme se na formulář
OsobaForm, který má jen několik řádků.
Přidávací formulář
Druhý formulář bude sloužit k přidávání nových osob a má následující podobu:

Do formuláře postupně vložíme tyto ovládací prvky:
- 2x
QLabel- Popisky - 1x
QLabel(Obrázek) - Tentokrát Label využijeme i na obrázek - 1x
QLineEdit- Zadání jména osoby - 3x
QComboBox(Datum) - Zadání data narození osoby realizujeme přes ComboBoxy na den, měsíc a rok - 1x
QPushButton- Tlačítko pro potvrzení
Struktura layoutů
Struktura formuláře včetně layoutů bude následující:
QVBoxLayoutQHBoxLayoutLabel(Obrázek)
QFormLayout- Row
QLabelQLineEdit
- Row
QLabelQComboBoxQComboBoxQComboBox
- Row
QPushButton
- Row
Že do labelu můžeme vložit obrázek vás možná překvapilo, ale není
to nic složitého. Co by ale určitě stálo za zmínku je nový typ layoutu -
QFormLayout. Ten nám ulehčí psaní v případě, kdy chceme
někam vložit formulář, který se skládá ze 2 sloupců. První sloupec
obsahuje popisky (QLabely) a druhý sloupec příslušné
editační prvky. Jistě si dokážete představit, že vkládat popisek a
editační prvek vždy spolu s novým QHBoxLayoutem by bylo
zbytečně pracné 
Vytvoření widgetů
Jelikož již tušíme jak layouty a widgety fungují, ukažme si rovnou kompletní kód pro vytvoření formuláře:
# Formulář pro vytvoření nové osoby class OsobaForm(QtWidgets.QWidget): def __init__(self, **kwargs): super(OsobaForm, self).__init__(**kwargs) # Titulek a ikonka self.setWindowTitle("Přidat osobu") self.setWindowIcon(QtGui.QIcon("person_bg.png")) layoutFormulare = QtWidgets.QVBoxLayout() self.setLayout(layoutFormulare) # Layout s obrázkem self.obrazekLabel = QtWidgets.QLabel() self.obrazekLabel.setPixmap(QtGui.QPixmap("person_bg.png").scaledToWidth(150)) obrazekLayout = QtWidgets.QHBoxLayout() obrazekLayout.addStretch() obrazekLayout.addWidget(self.obrazekLabel) obrazekLayout.addStretch() layoutFormulare.addLayout(obrazekLayout) # Layout se jménem self.udajeLayout = QtWidgets.QFormLayout() self.jmenoTextBox = QtWidgets.QLineEdit() # Přidáme řádek self.udajeLayout.addRow(QtWidgets.QLabel("Jméno"), self.jmenoTextBox) # Layout pro výběr data datumLayout = QtWidgets.QHBoxLayout() self.den = QtWidgets.QComboBox() self.den.addItem("Den") datumLayout.addWidget(self.den) self.mesic = QtWidgets.QComboBox() self.mesic.addItem("Měsíc") datumLayout.addWidget(self.mesic) self.rok = QtWidgets.QComboBox() self.rok.addItem("Rok") datumLayout.addWidget(self.rok) # Přidáme řádek self.udajeLayout.addRow(QtWidgets.QLabel("Datum narození"), datumLayout) self.okButton = QtWidgets.QPushButton("Ok") self.udajeLayout.addRow(None,self.okButton) layoutFormulare.addLayout(self.udajeLayout) def setup(self): pass
Třída OsobaForm již nedědí z
QtWidgets.QMainWindow, ale pouze z QtWidgets.QWidget.
To proto, že se jedná o pomocný formulář, který není hlavním oknem
aplikace. Na začátku konstruktoru nastavujeme opět titulek, ikonku a layout.
Ten je stejně jako u prvního formuláře svislý, aby se další layouty
vkládaly pod sebe.
Následuje přidání obrázku, který nemá žádný praktický význam, ale
aplikace s ním vypadá pro uživatele přívětivěji. Labelu obrázek
nastavíme pomocí metody setPixmap(), a následně mu nastavíme
šířku pomocí scaledToWidth(). Aby se ikonka vycentrovala,
vložíme ji do QHBoxLayout a okolo ní přidáme volné místo
pomocí addStretch().
Dále tvoříme QFormLayout, který metodou
addRow() umožňuje jednoduše vložit popisek a editační prvek
vedle sebe, aniž bychom je museli vkládat do dalších layoutů. Výběr data
narození provedeme pomocí 3 QComboBoxů, prvního na dny,
druhého na měsíce a třetího na roky. Asi vás nepřekvapí, že je
vkládáme vedle sebe do QHBoxLayout a celý layout následně
vložíme jako další řádek našeho QFormLayout pomocí metody
addRow().
Nakonec vytvoříme tlačítko a rovněž jej vložíme do
QFormLayout, tentokrát bez popisku. Layout s údaji o osobě
přidáme do layoutu formuláře a formuláři ještě nastavíme rozměry podle
jeho obsahu. K rozměrům jednotlivých widgetů se dostaneme pomocí metody
sizeHint(), na jejíž návratové hodnotě můžeme následně
volat metody width() a height().
Vygenerování dnů, měsíců a let
Do připravených QComboBoxů si vygenerujme 31 dní, 12
měsíců a posledních 190 let. Díky funkci range(), kterou
jistě v Pythonu znáte, to bude hračka. Na vygenerování hodnot si
vytvoříme ve třídě OsobaForm novou metodu
napln_datum_boxy():
def napln_datum_boxy(self): rok = int(datetime.datetime.now().year) for i in range(1, 32): self.den.addItem(str(i)) for i in range(1, 13): self.mesic.addItem(str(i)) for i in range(rok, rok - 190, -1): self.rok.addItem(str(i))
Metodu zavoláme v __init__() po vytvoření ComboBoxů:
# Kód výše # ... datumLayout.addWidget(self.rok) self.napln_datum_boxy() # další kód metody # ...
Událost tlačítka
Určitě byste si nyní rádi nový formulář vyzkoušeli. Přesuneme se
tedy do třídy PrehledForm, kde tlačítku pro přidávání osob
nastavíme událost clicked. Napojíme ji na metodu, ve které
zobrazíme formulář OsobaForm. Připomenu, že k instanci
osoba_form můžeme přistupovat díky tomu, že jsme si formulář
dříve uložili v metodě setup():
class PrehledForm(QtWidgets.QMainWindow): def __init__(self, **kwargs): super(PrehledForm, self).__init__(**kwargs) # Předchozí kód # ... self.pridatButton.clicked.connect(self.show_osoba_form) self.show() def show_osoba_form(self): self.osoba_form.show()
Výsledek:

Formuláře máme tedy kompletně připravené. Kompletní modul a ikonky naleznete ke stažení níže.
V příští lekci, Upomínač narozenin v PyQt - Logická vrstva, přidáme logiku 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 187x (37.85 kB)
Aplikace je včetně zdrojových kódů v jazyce Python
