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í.

7. diel - PyQt - Kreslenie na QWidget

V minulej lekcii, PRIPOMIENKOVÉ narodenín v PyQt - Dokončenie aplikácie , sme dokončili formulárové aplikácii k upomínania narodenín. V našich aplikáciách sa nám občas stane, že okrem štandardných tlačidiel, listov a labelov, budeme potrebovať niečo vykresliť. Kreslenie sa budeme venovať práve v dnešnom Python tutoriálu. Vykreslíme si kinosála na QWidget za pomoci QPainter.

Kreslenie na widgety

Pre kreslenie na PyQt widget využívame metódu paintEvent(self, event), ktorá sa automaticky volá vo chvíľach, keď sa formulár prekresľuje. To je nielen keď sa formulár vykreslí prvýkrát, ale aj keď bol napr. Prekrytý iným oknom, ktoré bolo náhle presunuté, a mal by sa teda opäť prekresliť. Udalosť má dva parametre, ako je v Pythone zvykom. Prvým z nich je inštancie (self / parent) a druhým je samotná udalosť, z ktorej sa dajú v prípade potreby získať ďalšie dáta.

Základná štruktúra aplikácie

Vytvoríme QWidget, ktorému nastavíme QVBoxLayout layout. Pridáme tiež tlačidlo, ktoré bude slúžiť na ukladanie informácií o tom, aké sedadlá sú obsadené.

Pre lepšiu predstavu si ukážme výslednú aplikáciu:

Aplikácia pre evidenciu kinosály v PyQt a Pythone - Okenné aplikácie v Pythone

Vytvorte si nový projekt, ja som súbor pomenoval kinosal.py.

Importy

Na začiatok súboru si nezabudnite pridať nasledujúce importy:

from PyQt5 import QtWidgets, QtGui, QtCore
import sys

Ďalej pridáme nasledujúci kód pre založenie formuláre a aplikácie:

class Window(QtWidgets.QMainWindow):

    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)

        widget = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout()
        widget.setLayout(layout)

        self.setCentralWidget(widget)
        button = QtWidgets.QPushButton("Uložit")

        layout.addStretch()
        layout.addWidget(button)

        self.show()

class App(QtWidgets.QApplication):

    def build(self):
        self.window = Window()
        sys.exit(self.exec_())

app = App(sys.argv)
app.build()

Jedná sa len o základnú kostru, ktorú sme tu už niekoľkokrát vytvárali a nemalo by vás v nej už nič prekvapiť. Aplikáciu si môžete skúsiť spustiť, zatiaľ získate takýto jednoduchý formulár:

Layout Python aplikácie pre správu kinosály - Okenné aplikácie v Pythone

Logická vrstva

Asi vás neprekvapí, že budeme pokračovať vytvorením triedy Kinosal. V tej bude list sedadla s hodnotami True / False. Ďalej bude obsahovať velikost sedadla na obrazovke a veľkosť medzery mezera v pixeloch. Tieto atribúty budeme využívať pri kreslení. Nasledujúci kód triedy si vložte nad triedu App:

class Kinosal:
    # vytvoříme list 30 je šířka a 15 jeho výška
    sedadla = [[False for i in range(15)] for i in range(30)]
    velikost = 16
    mezera = 2

Určite ste si všimli, že list je dvojrozmerný. Ako pracovať dvojrozmerných poli sme si vysvetľovali v lekcii Viacrozmerná poľa v Pythone. V pamäti sme vytvorili 2d pole 30 x 15 sedadiel.

Aby sme sa do kinosály dostali zo všetkých miest našej aplikácii, vytvoríme jeho inštanciu v triede App a uložíme ju rovnako, ako sme to robili s formulármi a manažérmi v predošlej aplikácii k upomínania narodenín:

class App(QtWidgets.QApplication):

    def build(self):
        self.kinosal = Kinosal()
        self.window = Window()
        sys.exit(self.exec_())

Vykreslenie

Ako som spomenul v úvode, budeme potrebovať metódu paintEvent(), keďže kreslíme na widget. Tú do triedy Window dodáme. Rovno aktualizujeme aj konštruktor, ktorý nastaví takú veľkosť formuláre, aby sa do neho jednotlivé sedadlá a medzery medzi nimi vošli. Celý kód triedy Window teraz vyzerá nasledovne:

class Window(QtWidgets.QMainWindow):

    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)

        self.resize((app.kinosal.velikost + app.kinosal.mezera) * len(app.kinosal.sedadla), (app.kinosal.velikost + app.kinosal.mezera) * len(app.kinosal.sedadla[0]) + 80)

        widget = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout()
        widget.setLayout(layout)

        self.setCentralWidget(widget)
        button = QtWidgets.QPushButton("Uložit")

        layout.addStretch()
        layout.addWidget(button)

        self.show()

    def paintEvent(self, event):
        p = QtGui.QPainter(self)
        for j in range(len(app.kinosal.sedadla[0])):
            for i in range(len(app.kinosal.sedadla)):

                if app.kinosal.sedadla[i][j]:
                    #Nastavíme červenou barvu
                    barva = QtCore.Qt.red
                else:
                    #Nastavíme zelenou barvu
                    barva = QtCore.Qt.green
                velikostSMezerou = app.kinosal.velikost + app.kinosal.mezera
                p.fillRect(i * velikostSMezerou, j * velikostSMezerou, app.kinosal.velikost, app.kinosal.velikost, QtGui.QBrush(barva))
        p.end()

V metóde paintEvent() používame inštanciu QPainter. Tá obsahuje metódu pre vykreslenie základných geometrických tvarov a textu. Jednotlivé sedadlá kinosály kreslíme za pomoci fillRect(x, y, w, h, QBrush). Ako asi tušíte, metóda fillRect() vykreslí vyplnený obdĺžnik. Jednotlivé farby nájdeme ako vlastnosti na triede QtCore.Qt. Všimnite si, že obsadeným sedadlám s hodnotou True nastavujeme červenú farbu, inak nastavujeme farbu zelenú. Vykreslenie jednotlivých obdĺžnikov (sedadiel) samozrejme prebieha v 2 vnorených cykloch, keď prvý prechádza stĺpce a druhý riadky.

Náš výsledok vyzerá zatiaľ takto:

Kinosála v Pythone - Okenné aplikácie v Pythone

V budúcej lekcii, Riešené úlohy k 3.-6. lekciu PyQt , naprogramujeme klikanie na sedadlá pomocou myši a ukladanie obsadenosti sedadiel do súboru.

V nasledujúcom cvičení, Riešené úlohy k 3.-6. lekciu PyQt, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 538x (2.53 kB)

 

Predchádzajúci článok
PRIPOMIENKOVÉ narodenín v PyQt - Dokončenie aplikácie
Všetky články v sekcii
Okenné aplikácie v Pythone
Preskočiť článok
(neodporúčame)
Riešené úlohy k 3.-6. lekciu PyQt
Č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