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ě:
QHBoxLayout
QPushButton
QPushButton
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í:
QVBoxLayout
QHBoxLayout
Label
(Obrázek)
QFormLayout
- Row
QLabel
QLineEdit
- Row
QLabel
QComboBox
QComboBox
QComboBox
- 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 (QLabel
y) 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 QHBoxLayout
em 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 182x (37.85 kB)
Aplikace je včetně zdrojových kódů v jazyce Python