Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
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í.

3. diel - GridLayout v PyQt - Formulár s využitím tabuľky

V dnešnom PyQt tutoriále si ukážeme ako jednoducho pracovať s umiestnením widgetov do našich formulárov pomocou QGridLayout. Ten nám umožní vkladať prvky do pomyselnej tabuľky alebo ak chcete mriežky.

Návrh formulára

QGridLayout sa často používa napr. Pre formuláre, kde sú v jednom stĺpci popisky a v druhom príslušná formulárové polia. Tabuľka zaistí, že je všetko pekne zarovnané. Podobne bude vyzerať aj náš dnešný formulár:

Okenné aplikácie v Pythone

Tentokrát nám ide o to skúsiť si len nový layout, takže nebudeme vytvárať funkčnú aplikáciu. Budeme potrebovať:

  • QWidget - Formulár
  • QGridLayout - Náš tabuľkový (grid) layout
  • QLabel - Popisky
  • QLineEdit - Jednoriadkové textové pole
  • QPlainTextEdit - Viacriadkové pole
  • QHBoxLayout - Ukážeme ako do gridu vložiť inej layouty
  • QPushButton - Tlačidlá

Vytvorenie formulára

Vytvoríme si nový Python projekt.

Importy

Pre prácu s PyQt si najprv musíme naimportovať samotnú knižnicu PyQt5 a knižnicu sys:

from PyQt5 import QtWidgets, QtGui, QtCore
import sys

Z PyQt5 nám QtWidgets umožní pracovať s widgety, vďaka QtGui môžeme meniť fonty, ktoré sa vo formulári budú zobrazovať, as QtCore môžeme určiť, kam sa budú widgety a texty v aplikácii zarovnávať.

Trieda s formulárom

Ďalej si vytvoríme triedu Formular. Objekty nám uľahčí tak prácu, tak prehľadnosť, preto sa hodí ich využívať. Naša trieda bude dediť z triedy QtWidgets.QMainWindow:

class Formular(QtWidgets.QMainWindow):
    def __init__(self, **kwargs):
        super(Formular,self).__init__(**kwargs)

        self.setWindowTitle("Formulář")
        self.setFixedSize(500,300)

        self.init_gui()
        self.show()

   def init_gui(self):
    """ Rozmístění formuláře """
        formular = QtWidgets.QWidget()

Rovno pri vytváraní si môžeme definovať aký titulok a aké rozmery bude naša aplikácia mať.

Použitie setFixedSize() naozaj "fixuje" veľkosť nášho okna. Teda týmto aj zamedzíme užívateľovi okno zväčšovať alebo zmenšovať.

Zavolaním metódy init_gui() sa presunieme do našej ďalšej funkcie, kde si už nadefinujeme, ako bude formulár vyzerať.

Práca s QGridLayout

Formulári nastavíme layout na QGridLayout. To nám zatiaľ vo formulári nič nezmení, ale ďalšie widgety už budeme schopní vkladať do gridu:

def init_gui(self):
    """ Rozmístění formuláře """
    formular = QtWidgets.QWidget()
    grid = QtWidgets.QGridLayout()
    formular.setLayout(grid)
    self.setCentralWidget(formular)

    grid.setSpacing(10)

Tu si v premennej grid budeme udržiavať odkaz na náš layout, ktorý následne nastavíme formulári ako hlavný.

Funkcia setSpacing(int) nám umožní definovať, ako ďaleko od seba budú jednotlivé bunky v gride. Nastavenie hodnoty na 0 by teda znamenalo, že dve bunky vedľa seba budú mať 0 pixelov medzeru (čo je často nečitateľné).

Ako sa v gridu vyznať?

Grid je vlastne jednoduchá tabuľka s m riadkami a n stĺpci. Ak teda chceme niečo vložiť na pozíciu v 1. riadku a 1. stĺpci, budeme vkladať na index (0 ; 0). Počítame od 0 podobne ako indexovanie listov v Pythone.

Ukážme si tabuľku s pár stĺpci a riadky a indexy jednotlivých buniek v nej:

0 1 2 ... n
0 (0,0) (0,1) (0,2) ... (0, n)
1 (1,0) (1,1) (1,2) ... (1, n)
2 (2,0) (2,1) (2,2) ... (2, n)
... ... ... ... ... ...
m (M, 0) (M, 1) (M, 2) ... (M, n)
Pri vytváraní formulárov nemusíme nikde dopredu špecifikovať, aká veľká má táto tabuľka byť. Grid sa vytvorí až podľa toho, na aké indexy mu priradíme naše widgety.

Vkladanie widgetov

Teraz už k samotným widgetom, ktoré budeme používať. Z obrázku môžeme vidieť, že náš formulár bude mať 7 riadkov a 3 stĺpce:

Okenné aplikácie v Pythone

V prvých šiestich riadkoch budú informácie o osobe, ktorú pridávame. V siedmom potom tlačidla. Kód si preto rozdelíme do niekoľkých častí.

2 stĺpce

Najprv pridáme widgety do prvých dvoch stĺpcov, teda QLabel a QLineEdit:

def init_gui(self):
""" Rozmístění formuláře """
    formular = QtWidgets.QWidget()
    grid = QtWidgets.QGridLayout()
    formular.setLayout(grid)
    self.setCentralWidget(formular)

    grid.setSpacing(10)

    self.jmeno_text = QtWidgets.QLabel("Jméno:")
    self.jmeno_text.setFont(QtGui.QFont("Arial", 14))
    grid.addWidget(self.jmeno_text, 0,0, QtCore.Qt.AlignRight)

    self.jmeno_input = QtWidgets.QLineEdit()
    self.jmeno_input.setFont(QtGui.QFont("Arial", 14))
    self.jmeno_input.setAlignment(QtCore.Qt.AlignLeft)
    grid.addWidget(self.jmeno_input, 0,1, QtCore.Qt.AlignCenter)

Takto môžeme vytvoriť prvý riadok formulára. Vždy si najskôr pomocou QLabel vytvoríme popisok riadku. Určíme font textu a pridáme popisok do nášho grid pomocou addWidget(). Tu určíme, aký widget pridávame, na akú pozíciu, a navyše, ak chceme, určíme aj zarovnanie widgetu v bunke.

Môžeme si všimnúť, že popisok prvého riadku sa vkladá na pozíciu (0,0). Textové pole, ktoré k popisku patrí, sa potom vloží na pozíciu (0,1).

Toto by sme mohli kód opakovať pre všetky riadky, ktoré chceme nadefinovať. Taký zápis je ale zdĺhavý, nie tak prehľadný a rozhodne sa nám nepáči kopírovať 7 riadkov kódu všade po našom programe.

Generovanie riadkov cyklom

Krajšie spôsob je využiť cyklu:

def init_gui(self):
    """ Rozmístění formuláře """
    formular = QtWidgets.QWidget()
    grid = QtWidgets.QGridLayout()
    formular.setLayout(grid)
    self.setCentralWidget(formular)

    grid.setSpacing(10)

    texty = ["Jméno:", "Příjmení:", "Ulice:", "Město:", "Zip:", "Národnost:"]
    vstupy = []

    for i in range(len(texty)):
        text = QtWidgets.QLabel(texty[i])
        text.setFont(QtGui.QFont("Arial", 14))
        grid.addWidget(text, i,0, QtCore.Qt.AlignRight)

        vstup = QtWidgets.QLineEdit()
        vstup.setFont(QtGui.QFont("Arial", 14))
        vstup.setAlignment(QtCore.Qt.AlignLeft)
        grid.addWidget(vstup, i,1, QtCore.Qt.AlignCenter)

        vstupy.append(vstup)

Najprv si vytvoríme list texty všetkých popiskov, ktoré v jednotlivých riadkoch chceme. Potom si pripravím nový prázdny hárok vstupy, do ktorého uložíme odkazy na jednotlivé vytvorená textové polia (to aby sme s nimi mohli neskôr pracovať, teda čítať z nich text, atď.).

Potom už len vytvárame cyklus, ktorý sa opakuje cez všetky prvky v liste texty. Vybraný text sa použije ako popisok. Posledná zmena je určiť, na akú pozíciu budeme widgety vkladať, ale aj to je ľahké. Riadok je index nášho cyklu.

Tretí stĺpec

Teraz pridáme aj tretí stĺpec. Tu chceme popisok a viacriadkové textové pole, pre to využijeme QPlainTextEdit:

def init_gui(self):
    # předchozí kód ...

    info_text = QtWidgets.QLabel("Info:")
    info_text.setFont(QtGui.QFont("Arial", 14))
    grid.addWidget(info_text, 0,2, QtCore.Qt.AlignLeft)

    self.info_input = QtWidgets.QPlainTextEdit()
    self.info_input.setFont(QtGui.QFont("Arial", 14))
    self.info_input.setFixedHeight(100)
    grid.addWidget(self.info_input, 0,2,4,1, QtCore.Qt.AlignCenter)

Pridanie popisu je rovnaké, až na pozíciu. Jedná sa o 1. riadok a 3. stĺpec, pozícia bude teda (0,2). Pre QPlainTextEdit chceme, aby bol trochu vyšší, než ostatné textové polia. Pomocou setFixedHeight() mu môžeme nastaviť výšku.

Pri pridávaní do gridu si všimneme, že vedľa súradníc pozície, kam widget pridať, máme ešte ďalšie dve súradnice. Metóda addWidget() nám dovoľuje špecifikovať, na koľko riadkov / stĺpcov sa má widget v tabuľke roztiahnuť. Keby sme toto roztiahnutie nepoužili, mohlo by sa nám stať, že textové pole pokojne prekryje vlastný label. Takto sa ale roztiahne pod ním.

Riadok s tlačidlami

Teraz ešte posledný riadok s tlačidlami. Tu chceme tri tlačidlá vedľa seba, ktorá sa vymykajú nášmu gridu. Využijeme preto už layout, ktorý bol použitý v minulých lekciách a to QHBoxLayout. Layouty samozrejme môžeme takto vhodne kombinovať:

def init_gui(self):
    # předchozí kód ...

    box = QtWidgets.QHBoxLayout()
    self.tlacitko_zpet = QtWidgets.QPushButton("Zpět")
    self.tlacitko_zpet.setFixedSize(80,40)
    box.addWidget(self.tlacitko_zpet)

    self.tlacitko_zrusit = QtWidgets.QPushButton("Zrušit")
    self.tlacitko_zrusit.setFixedSize(80,40)
    box.addWidget(self.tlacitko_zrusit)

    self.tlacitko_dalsi = QtWidgets.QPushButton("Další")
    self.tlacitko_dalsi.setFixedSize(80,40)
    box.addWidget(self.tlacitko_dalsi)

    grid.addLayout(box,6,0,1,3, QtCore.Qt.AlignRight)

Najprv si vytvoríme QHBoxLayout do premennej box. Potom jednotlivé tlačidlá postupne pridávame do layoutu box. Keď máme všetky tlačidlá, môžeme si celý box pridať späť do gridu pomocou addLayout(). Opäť udávame, že sa box môže vo svojom riadku roztiahnuť cez všetky 3 stĺpce.

Takto sme vytvorili celé GUI pre náš formulár!

Spustení aplikácie

Na úplný koniec programu už len pridáme pár riadkov pre spustenie aplikácie:

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

A výsledok:

Okenné aplikácie v Pythone

 

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é 162x (2.85 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 Marek Bečvář
Avatar
Užívateľské hodnotenie:
2 hlasov
Marek Bečvář
Aktivity