Hlavní navigace

Konfigurace standardních dialogů nabízených knihovnou PySide

6. 3. 2018
Doba čtení: 34 minut

Sdílet

Dnes si ukážeme další možnosti konfigurace standardních dialogů, které tato knihovna programátorům nabízí. I když se totiž jedná o standardní dialogy, je u nich možné některé jejich vlastnosti měnit podle potřeb aplikací.

Obsah

1. Další možnosti konfigurace tlačítek u dialogu QMessageBox

2. První demonstrační příklad – použití metody QMessageBox.addButton pro konfigurace tlačítek

3. Druhý demonstrační příklad – použití metody QMessageBox.setStandardButtons pro konfigurace tlačítek

4. Použití nestandardní ikony v dialogu QMessageBox

5. Třetí demonstrační příklad – vlastní ikona zobrazená v dialogu QMessageBox

6. Změna popisků tlačítek u standardního vstupního dialogu

7. Čtvrtý demonstrační příklad – české popisky tlačítek standardního vstupního dialogu

8. Vstupní dialog zobrazený bez tlačítek (pouze s polem pro zadání údajů uživatelem)

9. Pátý demonstrační příklad – vstupní dialog bez tlačítek

10. Navázání handlerů na událost generovanou při změně údajů ve vstupním dialogu

11. Šestý demonstrační příklad – reakce na průběžnou změnu údajů ve vstupním dialogu

12. Barvová paleta vybraná uživatelem přes QColorDialog

13. Sedmý demonstrační příklad – zobrazení barvové palety vybrané uživatelem a zapamatované v QColorDialogu

14. Standardní dialog pro výběr souboru či adresáře

15. Osmý demonstrační příklad – výběr souboru pro otevření souboru

16. Repositář s demonstračními příklady

17. Odkazy na Internetu

1. Další možnosti konfigurace tlačítek u dialogu QMessageBox

V předchozím článku o tvorbě aplikací s grafickým uživatelským rozhraním s využitím knihovny PySide jsme si mj. popsali i jednoduchý standardní dialog určený pro zobrazení zprávy uživateli. Připomeňme si, že tento dialog je představován třídou QMessageBox popř. potomky této třídy. Víme již, že u tohoto typu dialogu je (pochopitelně) možné specifikovat zprávu, která se má uživateli zobrazit a taktéž lze vybrat jednu ze čtyř standardních ikon nebo naopak zvolit, že se žádná ikona nemá zobrazit:

Ikona
QMessageBox.NoIcon
QMessageBox.Question
QMessageBox.Information
QMessageBox.Warning
QMessageBox.Critical

Obrázek 1: Standardní dialog s ikonou QMessageBox.Warning.

Dnes si ukážeme další možnosti konfigurace tohoto jednoduchého standardního dialogu. Dialog QMessageBox totiž ve skutečnosti neslouží pouze k zobrazení zprávy uživateli, ale může být použit pro dotazy s odpověďmi typu Ano/Ne, Ok/Storno, Ano/Ano pro všechny možnosti/Ne/Ne pro všechny možnosti apod. Pro určení tlačítek, které se mají v dialogu zobrazit, slouží v první řadě metoda addButton, které se předá jak popisek tlačítka, tak i jeho role (ve skutečnosti není zapotřebí roli specifikovat, jedná se o nepovinný parametr). Popis tlačítka může být prakticky libovolný, ovšem roli je nutné vybrat z konstant nabízených samotnou třídou QMessageBox. Role určuje chování tlačítek:

Role tlačítka Poznámka hodnota
QMessageBox.AcceptRole zavře dialog s hodnotou odpovídající tlačítku Ok
QMessageBox.RejectRole zavře dialog s hodnotou odpovídající tlačítku Cancel/Storno
QMessageBox.HelpRole uživatel vyžaduje zobrazení nápovědy
QMessageBox.YesRole odpovídá roli tlačítka „Yes“
QMessageBox.NoRole odpovídá roli tlačítka „No“
QMessageBox.ApplyRole odpovídá roli tlačítka „Apply“
QMessageBox.ResetRole odpovídá roli tlačítka „Reset“ (v jiném dialogu obnovení původních hodnot)
QMessageBox.InvalidRole nevalidní tlačítko

Obrázek 2: Standardní dialog s ikonou QMessageBox.Critical.

Podívejme se na příklad použití u dialogu, v němž potřebujeme zobrazit trojici tlačítek:

def showMessageBox(self):
    # vytvoření dialogu
    msgBox = QtGui.QMessageBox()
 
    # nastavení zprávy a ikony, která se má zobrazit vedle zprávy
    msgBox.setText(u'Zpráva')
    msgBox.setIcon(QtGui.QMessageBox.Information)
    # nastavení tlačítek, které mají být součástí dialogu
    msgBox.addButton("Help", QtGui.QMessageBox.HelpRole)
    msgBox.addButton("Accept", QtGui.QMessageBox.AcceptRole)
    msgBox.addButton("Reject", QtGui.QMessageBox.RejectRole)

Pokud dialog zobrazíme metodou exec_, bude návratová hodnota obsahovat index zvoleného tlačítka v tom pořadí, jak byla tlačítka předána do dialogu. To je trošku problematické, protože pozice zobrazených tlačítek (a tedy i jejich index) je platformově závislá. Například na Linuxu sice požadujeme zobrazení tlačítek v pořadí Help-Accept-Reject, ovšem ve skutečnosti se tlačítka zobrazí v pořadí Help-Reject-Accept (pořadí je určeno rolí, nikoli textem).

Obrázek 3: Standardní dialog se třemi nakonfigurovanými tlačítky Help, Accept a Reject.

Třída QMessageBox poskytuje programátorům i několik standardních tlačítek, které je do dialogu možné přidat metodou setStandardButton popř. v případě většího množství tlačítek setStandardButtons. Každé standardní tlačítko obsahuje (standardní) popisek a taktéž přiřazenou roli (viz tabulka zobrazená výše):

Tlačítko Text Role
QMessageBox.Ok „OK“ AcceptRole
QMessageBox.Open „Open“ AcceptRole
QMessageBox.Save „Save“ AcceptRole
QMessageBox.Cancel „Cancel“ RejectRole
QMessageBox.Close „Close“ RejectRole
QMessageBox.Discard „Discard“ nebo „Don’t Save“ DestructiveRole
QMessageBox.Apply „Apply“ ApplyRole
QMessageBox.Reset „Reset“ ResetRole
QMessageBox.RestoreDefaults „Restore Defaults“ ResetRole
QMessageBox.Help „Help“ HelpRole
QMessageBox.SaveAll „Save All“ AcceptRole
QMessageBox.Yes „Yes“ YesRole
QMessageBox.YesToAll „Yes to All“ YesRole
QMessageBox.No „No“ NoRole
QMessageBox.NoToAll „No to All“ NoRole
QMessageBox.Abort „Abort“ RejectRole
QMessageBox.Retry „Retry“ AcceptRole
QMessageBox.Ignore „Ignore“ AcceptRole
QMessageBox.NoButton nevalidní tlačítko ×

Následuje ukázka kódu, z něhož se dozvíme, jakým způsobem je možné deklarovat větší množství tlačítek, které se mají na dialogu objevit. Povšimněte si použití operátoru | (or):

def showMessageBox(self):
    # tlačítka, která mají být součástí dialogu
    buttons = QtGui.QMessageBox.Yes | \
              QtGui.QMessageBox.YesToAll | \
              QtGui.QMessageBox.No | \
              QtGui.QMessageBox.NoToAll | \
              QtGui.QMessageBox.Help
    # vytvoření dialogu
    msgBox = QtGui.QMessageBox()
 
    # nastavení zprávy a ikony, která se má zobrazit vedle zprávy
    msgBox.setStandardButtons(buttons)
    msgBox.setText(u'Zpráva')
    msgBox.setIcon(QtGui.QMessageBox.Question)

Pro výběr výchozího tlačítka se použije metoda setDefaultButton. Taktéž je možné zvolit, které tlačítko se pomyslně vybere ve chvíli stlačení klávesy Esc. Pro tento účel se používá metoda setEscapeButton.

Obrázek 4: Standardní dialog s pěti nakonfigurovanými tlačítky.

Opět platí, že pokud dialog zobrazíme zavoláním metody exec_, vrátí se celočíselná hodnota odpovídající zvolenému tlačítku. Samotná tlačítka QMessageBox.* jsou konstanty výčtového typu, takže je možné psát například:

ret = msgBox.exec_()
if ret == QtGui.QMessageBox.Yes:
    print("Yes!!!")
elif ret == QtGui.QMessageBox.No:
    print("No!!!")
else:
    print("something else")

Obrázek 5: Standardní dialog se čtyřmi nakonfigurovanými tlačítky.

2. První demonstrační příklad – použití metody QMessageBox.addButton pro konfigurace tlačítek

V dnešním prvním demonstračním příkladu je ukázáno, jakým způsobem je možné použít metodu nazvanou QMessageBox.addButton pro vytvoření dialogu, v němž bude zobrazena trojice tlačítek Help, Accept a Reject. Podívejme se na úplný zdrojový kód tohoto příkladu, v němž je důležitá především metoda nazvaná jednoduše showMessageBox:

#!/usr/bin/env python
# vim: set fileencoding=utf-8
 
import sys
 
# import "jádra" frameworku Qt i modulu pro GUI
from PySide import QtCore
from PySide import QtGui
 
 
# nový widget bude odvozen od obecného widgetu
class MainWindowContent(QtGui.QWidget):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindowContent, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        quitButton = self.prepareQuitButton()
        messageBoxButton = self.prepareMessageBoxButton()
 
        # vytvoření správce geometrie
        topLayout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        topLayout.addWidget(messageBoxButton)
        topLayout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(topLayout)
 
    def prepareMessageBoxButton(self):
        # tlačítko
        messageBoxButton = QtGui.QPushButton('Message Box', self)
        messageBoxButton.resize(messageBoxButton.sizeHint())
 
        # navázání akce na signál
        messageBoxButton.clicked.connect(self.showMessageBox)
        return messageBoxButton
 
    def prepareQuitButton(self):
        # tlačítko
        quitButton = QtGui.QPushButton('Quit', self)
        quitButton.resize(quitButton.sizeHint())
 
        # navázání akce na signál
        quitButton.clicked.connect(QtCore.QCoreApplication.instance().quit)
        return quitButton
 
    def showMessageBox(self):
        # vytvoření dialogu
        msgBox = QtGui.QMessageBox()
 
        # nastavení zprávy a ikony, která se má zobrazit vedle zprávy
        msgBox.setText(u'Zpráva')
        msgBox.setIcon(QtGui.QMessageBox.Information)
        # msgBox.setIcon(QtGui.QMessageBox.Question)
        # msgBox.setIcon(QtGui.QMessageBox.Warning)
        # msgBox.setIcon(QtGui.QMessageBox.Critical)
 
        # nastavení tlačítek, které mají být součástí dialogu
        msgBox.addButton("Help", QtGui.QMessageBox.HelpRole)
        msgBox.addButton("Accept", QtGui.QMessageBox.AcceptRole)
        msgBox.addButton("Reject", QtGui.QMessageBox.RejectRole)
 
        # zobrazení dialogu
        print(msgBox.exec_())
 
 
# nový widget bude odvozen od obecného hlavního okna
class MainWindow(QtGui.QMainWindow):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindow, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        # velikost není potřeba specifikovat
        # self.resize(320, 240)
        self.setWindowTitle("QMessageBox")
 
        # vložení komponenty do okna
        self.setCentralWidget(MainWindowContent())
 
    def run(self, app):
        # zobrazení okna na obrazovce
        self.show()
        # vstup do smyčky událostí (event loop)
        app.exec_()
 
 
def main():
    app = QtGui.QApplication(sys.argv)
    MainWindow().run(app)
 
 
if __name__ == '__main__':
    main()

3. Druhý demonstrační příklad – použití metody QMessageBox.setStandardButtons pro konfigurace tlačítek

Ve druhém příkladu můžeme vidět použití metody QMessageBox.setStandardButtons, které se předá objekt představující všechna tlačítka, která se mají v dialogu zobrazit. Povšimněte si, jakým způsobem je možné tento objekt vytvořit s využitím operátoru | (opět viz metodu showMessageBox obsahující nejdůležitější část tohoto příkladu):

#!/usr/bin/env python
# vim: set fileencoding=utf-8
 
import sys
 
# import "jádra" frameworku Qt i modulu pro GUI
from PySide import QtCore
from PySide import QtGui
 
 
# nový widget bude odvozen od obecného widgetu
class MainWindowContent(QtGui.QWidget):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindowContent, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        quitButton = self.prepareQuitButton()
        messageBoxButton = self.prepareMessageBoxButton()
 
        # vytvoření správce geometrie
        topLayout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        topLayout.addWidget(messageBoxButton)
        topLayout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(topLayout)
 
    def prepareMessageBoxButton(self):
        # tlačítko
        messageBoxButton = QtGui.QPushButton('Message Box', self)
        messageBoxButton.resize(messageBoxButton.sizeHint())
 
        # navázání akce na signál
        messageBoxButton.clicked.connect(self.showMessageBox)
        return messageBoxButton
 
    def prepareQuitButton(self):
        # tlačítko
        quitButton = QtGui.QPushButton('Quit', self)
        quitButton.resize(quitButton.sizeHint())
 
        # navázání akce na signál
        quitButton.clicked.connect(QtCore.QCoreApplication.instance().quit)
        return quitButton
 
    def showMessageBox(self):
        # tlačítka, která mají být součástí dialogu
        buttons = QtGui.QMessageBox.Yes | \
                  QtGui.QMessageBox.YesToAll | \
                  QtGui.QMessageBox.No | \
                  QtGui.QMessageBox.NoToAll | \
                  QtGui.QMessageBox.Help
        # vytvoření dialogu
        msgBox = QtGui.QMessageBox()
 
        # nastavení zprávy a ikony, která se má zobrazit vedle zprávy
        msgBox.setStandardButtons(buttons)
        msgBox.setText(u'Zpráva')
        msgBox.setIcon(QtGui.QMessageBox.Question)
        # msgBox.setIcon(QtGui.QMessageBox.Question)
        # msgBox.setIcon(QtGui.QMessageBox.Warning)
        # msgBox.setIcon(QtGui.QMessageBox.Critical)
 
        # zobrazení dialogu
        print(msgBox.exec_())
 
 
# nový widget bude odvozen od obecného hlavního okna
class MainWindow(QtGui.QMainWindow):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindow, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        # velikost není potřeba specifikovat
        # self.resize(320, 240)
        self.setWindowTitle("QMessageBox")
 
        # vložení komponenty do okna
        self.setCentralWidget(MainWindowContent())
 
    def run(self, app):
        # zobrazení okna na obrazovce
        self.show()
        # vstup do smyčky událostí (event loop)
        app.exec_()
 
 
def main():
    app = QtGui.QApplication(sys.argv)
    MainWindow().run(app)
 
 
if __name__ == '__main__':
    main()

4. Použití nestandardní ikony v dialogu QMessageBox

I další úpravy standardního dialogu představovaného třídou QMessageBox jsou z programátorského hlediska velmi jednoduché. Již minule jsme se zmínili o možnosti výběru standardní ikony metodou QMessageBox.setIcon. V některých případech nám však nemusí nabídka standardních ikon vyhovovat a proto namísto této metody použijeme metodu QMessageBox.setIconPixmap, které lze předat libovolný rastrový obrázek reprezentovaný instancí třídy QPixmap. Základní možnosti této třídy již dobře známe, takže si jen ve stručnosti ukažme, jakým postupem lze zařídit načtení externího rastrového obrázku a použít ho jako ikonu:

def showMessageBox(self):
    # tlačítko, která mají být součástí dialogu
    buttons = QtGui.QMessageBox.Ok
 
    # vytvoření dialogu
    msgBox = QtGui.QMessageBox()
 
    # nastavení zprávy a ikony, která se má zobrazit vedle zprávy
    msgBox.setStandardButtons(buttons)
    msgBox.setText(u'')
 
    # načtení pixmapy a její nastavení jako ikony pro dialog
    pixmap = QtGui.QPixmap("pixmaps/pysidelogo.png")
    msgBox.setIconPixmap(pixmap)

Obrázek 6: Dialog, v němž je zpráva představována prázdným řetězcem a ve kterém je použita vlastní ikona.

5. Třetí demonstrační příklad – vlastní ikona zobrazená v dialogu QMessageBox

Podívejme se nyní na zdrojový kód dnešního třetího demonstračního příkladu, ve kterém vytváříme dialog typu QMessageBox a přitom v něm použijeme vlastní ikonu, kterou jsme již mimochodem v tomto seriálu použili při zobrazování tzv. splash screenu. Zpráva je nastavena na prázdný řetězec (samotná ikona je totiž poměrně velká a tak je v dialogu dostatečně dominantní) a kromě již zmíněné ikony se zobrazí jen jediné tlačítko Ok:

#!/usr/bin/env python
# vim: set fileencoding=utf-8
 
import sys
 
# import "jádra" frameworku Qt i modulu pro GUI
from PySide import QtCore
from PySide import QtGui
 
 
# nový widget bude odvozen od obecného widgetu
class MainWindowContent(QtGui.QWidget):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindowContent, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        quitButton = self.prepareQuitButton()
        messageBoxButton = self.prepareMessageBoxButton()
 
        # vytvoření správce geometrie
        topLayout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        topLayout.addWidget(messageBoxButton)
        topLayout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(topLayout)
 
    def prepareMessageBoxButton(self):
        # tlačítko
        messageBoxButton = QtGui.QPushButton('Message Box', self)
        messageBoxButton.resize(messageBoxButton.sizeHint())
 
        # navázání akce na signál
        messageBoxButton.clicked.connect(self.showMessageBox)
        return messageBoxButton
 
    def prepareQuitButton(self):
        # tlačítko
        quitButton = QtGui.QPushButton('Quit', self)
        quitButton.resize(quitButton.sizeHint())
 
        # navázání akce na signál
        quitButton.clicked.connect(QtCore.QCoreApplication.instance().quit)
        return quitButton
 
    def showMessageBox(self):
        # tlačítko, která mají být součástí dialogu
        buttons = QtGui.QMessageBox.Ok
 
        # vytvoření dialogu
        msgBox = QtGui.QMessageBox()
 
        # nastavení zprávy a ikony, která se má zobrazit vedle zprávy
        msgBox.setStandardButtons(buttons)
        msgBox.setText(u'')
 
        # načtení pixmapy a její nastavení jako ikony pro dialog
        pixmap = QtGui.QPixmap("pixmaps/pysidelogo.png")
        msgBox.setIconPixmap(pixmap)
 
        # zobrazení dialogu
        print(msgBox.exec_())
 
 
# nový widget bude odvozen od obecného hlavního okna
class MainWindow(QtGui.QMainWindow):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindow, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        # velikost není potřeba specifikovat
        # self.resize(320, 240)
        self.setWindowTitle("QMessageBox")
 
        # vložení komponenty do okna
        self.setCentralWidget(MainWindowContent())
 
    def run(self, app):
        # zobrazení okna na obrazovce
        self.show()
        # vstup do smyčky událostí (event loop)
        app.exec_()
 
 
def main():
    app = QtGui.QApplication(sys.argv)
    MainWindow().run(app)
 
 
if __name__ == '__main__':
    main()

6. Změna popisků tlačítek u standardního vstupního dialogu

Ve standardním vstupním dialogu nalezneme tlačítko Ok a Cancel:

Obrázek 7: Standardní vstupní dialog s tlačítky Ok a Cancel i se vstupním textovým polem.

Shodná tlačítka budou použita i ve chvíli, kdy je vstupní dialog nakonfigurován tak, aby akceptoval jen celá čísla, reálná čísla, výběr prvku ze seznamu či kombo boxu atd.

Obrázek 8: Standardní vstupní dialog s tlačítky Ok a Cancel i se vstupním polem určeným pro zadání celého čísla.

Popisky těchto dvou tlačítek můžeme snadno změnit, a to konkrétně zavoláním metod QInputDialog.setOkButtonText a QInputDialog.setCancelButtonText, kterým se předá nový text tlačítek. To je ukázáno v další funkci. Kvůli kompatibilitě s Pythonem 2.x je u všech řetězců explicitně uvedeno, že se používá kódování Unicode a nikoli ASCII:

def textInputDialogHandler(self):
    # vytvoření a konfigurace vstupního dialogu
    dialog = QtGui.QInputDialog(self)
    dialog.setInputMode(QtGui.QInputDialog.TextInput)
 
    # nastavení výchozího stavu dialogu
    dialog.setLabelText("Text input:")
    dialog.setTextValue("default text")
 
    # nastavení textů tlačítek
    dialog.setCancelButtonText(u"Zrušit")
    dialog.setOkButtonText(u"Potvrdit")

Obrázek 9: Standardní vstupní dialog s modifikovanými tlačítky Ok a Cancel.

7. Čtvrtý demonstrační příklad – české popisky tlačítek standardního vstupního dialogu

V dnešním čtvrtém demonstračním příkladu je ukázána změna textu u tlačítek standardního vstupního dialogu. Zdrojový text tohoto příkladu se od příkladu uvedeného minule odlišuje pouze ve volání metod QInputDialog.setOkButtonText a QInputDialog.setCancelButtonText:

#!/usr/bin/env python
# vim: set fileencoding=utf-8
 
import sys
 
# import "jádra" frameworku Qt i modulu pro GUI
from PySide import QtCore
from PySide import QtGui
 
 
# nový widget bude odvozen od obecného widgetu
class MainWindowContent(QtGui.QWidget):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindowContent, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        quitButton = self.prepareQuitButton()
 
        textInputDialogButton = self.prepareButton(
            "Text Input", self.textInputDialogHandler)
 
        # vytvoření správce geometrie
        topLayout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        topLayout.addWidget(textInputDialogButton)
        topLayout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(topLayout)
 
    def textInputDialogHandler(self):
        # vytvoření a konfigurace vstupního dialogu
        dialog = QtGui.QInputDialog(self)
        dialog.setInputMode(QtGui.QInputDialog.TextInput)
 
        # nastavení výchozího stavu dialogu
        dialog.setLabelText("Text input:")
        dialog.setTextValue("default text")
 
        # nastavení textů tlačítek
        dialog.setCancelButtonText(u"Zrušit")
        dialog.setOkButtonText(u"Potvrdit")
 
        # zobrazení dialogu a čekání na uživatelský vstup
        result = dialog.exec_()
 
        # zpracování a zobrazení výsledků
        text = dialog.textValue()
        message = "Entered text: '{t}'\nClicked on: {c}".format(
            t=text, c="Ok" if result == 1 else "Cancel")
 
        # zobrazení dialogu s informací o vstupu od uživatele
        self.showMessageBox(message)
 
    def prepareButton(self, label, handler):
        # tlačítko
        button = QtGui.QPushButton(label, self)
        button.resize(button.sizeHint())
 
        # navázání akce na signál
        button.clicked.connect(handler)
        return button
 
    def prepareQuitButton(self):
        # tlačítko
        quitButton = QtGui.QPushButton('Quit', self)
        quitButton.resize(quitButton.sizeHint())
 
        # navázání akce na signál
        quitButton.clicked.connect(QtCore.QCoreApplication.instance().quit)
        return quitButton
 
    def showMessageBox(self, text):
        # vytvoření dialogu
        msgBox = QtGui.QMessageBox()
 
        # nastavení textu a ikony, které se mají zobrazit
        msgBox.setText(text)
        msgBox.setIcon(QtGui.QMessageBox.Information)
 
        # zobrazení dialogu
        msgBox.exec_()
 
 
# nový widget bude odvozen od obecného hlavního okna
class MainWindow(QtGui.QMainWindow):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindow, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        # velikost není potřeba specifikovat
        # self.resize(320, 240)
        self.setWindowTitle("QInputDialog")
 
        # vložení komponenty do okna
        self.setCentralWidget(MainWindowContent())
 
    def run(self, app):
        # zobrazení okna na obrazovce
        self.show()
        # vstup do smyčky událostí (event loop)
        app.exec_()
 
 
def main():
    app = QtGui.QApplication(sys.argv)
    MainWindow().run(app)
 
 
if __name__ == '__main__':
    main()

8. Vstupní dialog zobrazený bez tlačítek (pouze s polem pro zadání údajů uživatelem)

Standardní vstupní dialog QInputDialog je dokonce možné nakonfigurovat i takovým způsobem, aby se v něm nezobrazily žádné další ovládací prvky kromě vstupního textového políčka, kombo boxu nebo seznamu prvků. Pokud skutečně nevyžadujete použití dalších ovládacích prvků, tedy především tlačítek, je možné dialog nakonfigurovat následujícím způsobem:

QInputDialog.setInputMode(QtGui.QInputDialog.TextInput)
QInputDialog.setOption(QtGui.QInputDialog.NoButtons, True)

Obrázek 10: Vstupní dialog zobrazený bez tlačítek.

Metoda, která zajistí konfiguraci dialogu pro vstup textu (bez tlačítek), bude vypadat takto:

def textInputDialogHandler(self):
    # vytvoření a konfigurace vstupního dialogu
    dialog = QtGui.QInputDialog(self)
    dialog.setInputMode(QtGui.QInputDialog.TextInput)
 
    # nastavení výchozího stavu dialogu
    dialog.setLabelText("Text input:")
    dialog.setTextValue("default text")
 
    # dialog bude zobrazen bez tlačítek
    dialog.setOption(QtGui.QInputDialog.NoButtons, True)

Obrázek 11: Další varianta vstupního dialogu zobrazeného bez tlačítek.

Podobně je možné nakonfigurovat dialog pro vstup celého čísla:

def integerInputDialogHandler(self):
    # vytvoření a konfigurace vstupního dialogu
    dialog = QtGui.QInputDialog(self)
    dialog.setInputMode(QtGui.QInputDialog.IntInput)
 
    # nastavení výchozího stavu dialogu
    dialog.setLabelText("Integer input:")
    dialog.setIntMinimum(10)
    dialog.setIntMaximum(20)
 
    # dialog bude zobrazen bez tlačítek
    dialog.setOption(QtGui.QInputDialog.NoButtons, True)

Takto nakonfigurovaný dialog lze zavřít klávesou Esc nebo pomocí myši.

9. Pátý demonstrační příklad – vstupní dialog bez tlačítek

V pátém demonstračním příkladu je ukázán způsob zobrazení vstupního dialogu bez tlačítek. Dialog tedy obsahuje pouze vstupní textové pole a je ho možné zavřít buď klávesou Esc nebo myší. Ovšem ve standardním nastavení nebude fungovat klávesa Enter/Return, takže vlastně dialog vždy vrátí hodnotu „Cancel“ (zadaný text samozřejmě není ztracen, protože ho lze přečíst metodou QInputDialog.textValue, nezávisle na tom, jakým způsobem byl dialog zavřen:

#!/usr/bin/env python
# vim: set fileencoding=utf-8
 
import sys
 
# import "jádra" frameworku Qt i modulu pro GUI
from PySide import QtCore
from PySide import QtGui
 
 
# nový widget bude odvozen od obecného widgetu
class MainWindowContent(QtGui.QWidget):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindowContent, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        quitButton = self.prepareQuitButton()
 
        textInputDialogButton = self.prepareButton(
            "Text Input", self.textInputDialogHandler)
 
        # vytvoření správce geometrie
        topLayout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        topLayout.addWidget(textInputDialogButton)
        topLayout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(topLayout)
 
    def textInputDialogHandler(self):
        # vytvoření a konfigurace vstupního dialogu
        dialog = QtGui.QInputDialog(self)
        dialog.setInputMode(QtGui.QInputDialog.TextInput)
 
        # nastavení výchozího stavu dialogu
        dialog.setLabelText("Text input:")
        dialog.setTextValue("default text")
 
        # dialog bude zobrazen bez tlačítek
        dialog.setOption(QtGui.QInputDialog.NoButtons, True)
 
        # zobrazení dialogu a čekání na uživatelský vstup
        result = dialog.exec_()
 
        # zpracování a zobrazení výsledků
        text = dialog.textValue()
        message = "Entered text: '{t}'\nClicked on: {c}".format(
            t=text, c="Ok" if result == 1 else "Cancel")
 
        # zobrazení dialogu s informací o vstupu od uživatele
        self.showMessageBox(message)
 
    def prepareButton(self, label, handler):
        # tlačítko
        button = QtGui.QPushButton(label, self)
        button.resize(button.sizeHint())
 
        # navázání akce na signál
        button.clicked.connect(handler)
        return button
 
    def prepareQuitButton(self):
        # tlačítko
        quitButton = QtGui.QPushButton('Quit', self)
        quitButton.resize(quitButton.sizeHint())
 
        # navázání akce na signál
        quitButton.clicked.connect(QtCore.QCoreApplication.instance().quit)
        return quitButton
 
    def showMessageBox(self, text):
        # vytvoření dialogu
        msgBox = QtGui.QMessageBox()
 
        # nastavení textu a ikony, které se mají zobrazit
        msgBox.setText(text)
        msgBox.setIcon(QtGui.QMessageBox.Information)
 
        # zobrazení dialogu
        msgBox.exec_()
 
 
# nový widget bude odvozen od obecného hlavního okna
class MainWindow(QtGui.QMainWindow):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindow, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        # velikost není potřeba specifikovat
        # self.resize(320, 240)
        self.setWindowTitle("QInputDialog")
 
        # vložení komponenty do okna
        self.setCentralWidget(MainWindowContent())
 
    def run(self, app):
        # zobrazení okna na obrazovce
        self.show()
        # vstup do smyčky událostí (event loop)
        app.exec_()
 
 
def main():
    app = QtGui.QApplication(sys.argv)
    MainWindow().run(app)
 
 
if __name__ == '__main__':
    main()

10. Navázání handlerů na událost generovanou při změně údajů ve vstupním dialogu

V případě, že je vstupní dialog zobrazen bez tlačítek Ok a Cancel, je většinou nutné, aby aplikace reagovala přímo na zadávané hodnoty. Představme si například webový prohlížeč, v němž se v reálném čase mohou vyhledávat části textu atd. U dialogů odvozených od třídy QInputDialog lze zaregistrovat handlery pro šest typů událostí, ovšem vždy pouze dvě události mají skutečný smysl. Které dvě události to budou záleží na tom, jaký typ vstupu je nakonfigurován – zda lze zadat libovolný text, celé číslo či číslo reálné:

Událost Předaný parametr
intValueChanged změněná hodnota typu int
intValueSelected vybraná hodnota typu int
   
doubleValueChanged změněná hodnota typu double
doubleValueSelected vybraná hodnota typu double
   
textValueChanged změněný řetězec
textValueSelected vybraný řetězec

Navázání handleru na událost (přes signál) se provede snadno. Příkladem může být nejběžnější dialog určený pro vstup běžného textu, v němž potřebujeme reagovat na každou změnu textu v dialogu (přidání dalšího znaku, vymazání znaku, použití schránky apod.):

# při změně textu se zavolá handler
dialog.textValueChanged.connect(self.onTextValueChanged)

Vytvoření dialogu s navázáním události na handler bude vypadat například následovně:

def registerTextInputDialogHandler(self):
    # vytvoření a konfigurace vstupního dialogu
    dialog = QtGui.QInputDialog(self)
    dialog.setInputMode(QtGui.QInputDialog.TextInput)
 
    # nastavení výchozího stavu dialogu
    dialog.setLabelText("Text input:")
    dialog.setTextValue("")
 
    # dialog bude zobrazen bez tlačítek
    dialog.setOption(QtGui.QInputDialog.NoButtons, True)
 
    # při změně textu se zavolá handler
    dialog.textValueChanged.connect(self.onTextValueChanged)

Samotný handler může například změnit hodnotu zobrazenou v hlavním okně aplikace:

def onTextValueChanged(self, text):
    """Handler zavolaný při změně textu ve vstupním dialogu."""
    self.enteredTextLabel.setText(text)

Obrázek 12: Text labelu na hlavním okně reflektuje změny prováděné uživatelem ve vstupním dialogu.

11. Šestý demonstrační příklad – reakce na průběžnou změnu údajů ve vstupním dialogu

V dnešním šestém demonstračním příkladu je ukázáno, jak lze jednoduše naprogramovat handler reagující na změnu údajů ve vstupním dialogu. Samotný handler je realizován metodou nazvanou onTextValueChanged, jeho registrace a navázání na signál je provedeno v metodě pojmenované textInputDialogHandler. Následuje výpis zdrojového kódu tohoto příkladu:

#!/usr/bin/env python
# vim: set fileencoding=utf-8
 
import sys
 
# import "jádra" frameworku Qt i modulu pro GUI
from PySide import QtCore
from PySide import QtGui
 
 
# nový widget bude odvozen od obecného widgetu
class MainWindowContent(QtGui.QWidget):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindowContent, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        quitButton = self.prepareQuitButton()
 
        textInputDialogButton = self.prepareButton(
            "Text Input", self.textInputDialogHandler)
 
        self.enteredTextLabel = QtGui.QLabel("")
 
        # vytvoření správce geometrie
        topLayout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        topLayout.addWidget(self.enteredTextLabel)
        topLayout.addWidget(textInputDialogButton)
        topLayout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(topLayout)
 
    def onTextValueChanged(self, text):
        """Handler zavolaný při změně textu ve vstupním dialogu."""
        self.enteredTextLabel.setText(text)
 
    def textInputDialogHandler(self):
        # vytvoření a konfigurace vstupního dialogu
        dialog = QtGui.QInputDialog(self)
        dialog.setInputMode(QtGui.QInputDialog.TextInput)
 
        # nastavení výchozího stavu dialogu
        dialog.setLabelText("Text input:")
        dialog.setTextValue("")
 
        # dialog bude zobrazen bez tlačítek
        dialog.setOption(QtGui.QInputDialog.NoButtons, True)
 
        # při změně textu se zavolá handler
        dialog.textValueChanged.connect(self.onTextValueChanged)
 
        # zobrazení dialogu a čekání na uživatelský vstup
        result = dialog.exec_()
 
        # zpracování a zobrazení výsledků
        text = dialog.textValue()
        message = "Entered text: '{t}'\nClicked on: {c}".format(
            t=text, c="Ok" if result == 1 else "Cancel")
 
        # zobrazení dialogu s informací o vstupu od uživatele
        self.showMessageBox(message)
 
    def prepareButton(self, label, handler):
        # tlačítko
        button = QtGui.QPushButton(label, self)
        button.resize(button.sizeHint())
 
        # navázání akce na signál
        button.clicked.connect(handler)
        return button
 
    def prepareQuitButton(self):
        # tlačítko
        quitButton = QtGui.QPushButton('Quit', self)
        quitButton.resize(quitButton.sizeHint())
 
        # navázání akce na signál
        quitButton.clicked.connect(QtCore.QCoreApplication.instance().quit)
        return quitButton
 
    def showMessageBox(self, text):
        # vytvoření dialogu
        msgBox = QtGui.QMessageBox()
 
        # nastavení textu a ikony, které se mají zobrazit
        msgBox.setText(text)
        msgBox.setIcon(QtGui.QMessageBox.Information)
 
        # zobrazení dialogu
        msgBox.exec_()
 
 
# nový widget bude odvozen od obecného hlavního okna
class MainWindow(QtGui.QMainWindow):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindow, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        # velikost není potřeba specifikovat
        # self.resize(320, 240)
        self.setWindowTitle("QInputDialog")
 
        # vložení komponenty do okna
        self.setCentralWidget(MainWindowContent())
 
    def run(self, app):
        # zobrazení okna na obrazovce
        self.show()
        # vstup do smyčky událostí (event loop)
        app.exec_()
 
 
def main():
    app = QtGui.QApplication(sys.argv)
    MainWindow().run(app)
 
 
if __name__ == '__main__':
    main()

12. Barvová paleta vybraná uživatelem přes QColorDialog

Již minule jsme si popsali dialog určený pro výběr barvy. Ovšem tento dialog má ještě jednu důležitou vlastnost – může si totiž „pamatovat“ uživatelem vybrané barvy, které tak tvoří relativně malou barvovou paletu (zapamatovaná paleta je permanentní, přežije i restart systému). Vypadá to následovně:

Obrázek 13: Dialog pro výběr barvy s prázdnou uživatelskou barvovou paletou.

Obrázek 14: Dialog pro výběr barvy s nastavenou uživatelskou barvovou paletou.

Barvová paleta je interně uložena v třídním atributu třídy QColorDialog a je možné se k ní dostat po jednotlivých barvách zadáním indexu od 0 do 15:

for index in range(0, 16):
    color = QtGui.QColorDialog.customColor(index)

Výsledkem je kód barvy, který je možné použít například následujícím způsobem:

def redrawColorBoxes(self):
    # vytvoření objektu typu QPainter s předáním
    # reference na "pokreslovaný" objekt
    qp = QtGui.QPainter(self.image)
 
    # vykreslení čtverců s barvami získanými z dialogu
    index = 0
    for row in range(0, 2):
        for column in range(0, 8):
            color = QtGui.QColorDialog.customColor(index)
            x = 10 + column * (MainWindowContent.SQUARE_SIZE + 10)
            y = 10 + row * (MainWindowContent.SQUARE_SIZE + 10)
            drawRectangleUsingBrush(qp, color, x, y,
                                    MainWindowContent.SQUARE_SIZE,
                                    MainWindowContent.SQUARE_SIZE)
            index += 1
 
    # vytvoření instance třídy QPixmap z objektu QImage
    self.pixmap = QtGui.QPixmap.fromImage(self.image)

Vykreslení obdélníků vybranou barvou je realizováno touto funkcí:

# funkce pro vykreslení obdélníku zadanou barvou
def drawRectangleUsingBrush(qPainter, color, x, y, width, height):
    # změna barvy štětce
    brush = QtGui.QBrush(QtGui.QColor(color))
    brush.setStyle(QtCore.Qt.SolidPattern)
    qPainter.setBrush(brush)
 
    # vykreslení obdélníku
    qPainter.drawRect(x, y, width, height)

13. Sedmý demonstrační příklad – zobrazení barvové palety vybrané uživatelem a zapamatované v QColorDialogu

Výše popsaná statická metoda QColorDialog.customColor je použita v dnešním sedmém demonstračním příkladu. Po jeho spuštění se zobrazí hlavní okno, které mj. obsahuje i šestnáct barevných obdélníků ukazujících uživatelskou paletu. Výchozí barvy vypadají takto:

Obrázek 15: Výchozí stav hlavního okna aplikace s uživatelskou barvovou paletou.

Po zobrazení dialogu pro výběr barvy si můžete nastavit vlastní barvovou paletu, takže se ihned po zavření dialogu hlavní okno změní, například následovně:

Obrázek 16: Barvová paleta poté, co do ní uživatel vložil další barvy.

Následuje výpis zdrojového kódu tohoto demonstračního příkladu:

#!/usr/bin/env python
# vim: set fileencoding=utf-8
 
import sys
 
# import "jádra" frameworku Qt i modulu pro GUI
from PySide import QtCore
from PySide import QtGui
 
 
# funkce pro vykreslení obdélníku zadanou barvou
def drawRectangleUsingBrush(qPainter, color, x, y, width, height):
    # změna barvy štětce
    brush = QtGui.QBrush(QtGui.QColor(color))
    brush.setStyle(QtCore.Qt.SolidPattern)
    qPainter.setBrush(brush)
 
    # vykreslení obdélníku
    qPainter.drawRect(x, y, width, height)
 
 
# nový widget bude odvozen od obecného widgetu
class MainWindowContent(QtGui.QWidget):
 
    # rozměry rastrového obrázku
    IMAGE_WIDTH = 330
    IMAGE_HEIGHT = 90
 
    SQUARE_SIZE = 30
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindowContent, self).__init__()
 
        self.prepareImage()
        self.redrawColorBoxes()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareImage(self):
        # vytvoření instance třídy QImage
        self.image = QtGui.QImage(MainWindowContent.IMAGE_WIDTH,
                                  MainWindowContent.IMAGE_HEIGHT,
                                  QtGui.QImage.Format_RGB32)
        # vymazání obrázku
        self.image.fill(0)
 
    def redrawColorBoxes(self):
        # vytvoření objektu typu QPainter s předáním
        # reference na "pokreslovaný" objekt
        qp = QtGui.QPainter(self.image)
 
        # vykreslení čtverců s barvami získanými z dialogu
        index = 0
        for row in range(0, 2):
            for column in range(0, 8):
                color = QtGui.QColorDialog.customColor(index)
                x = 10 + column * (MainWindowContent.SQUARE_SIZE + 10)
                y = 10 + row * (MainWindowContent.SQUARE_SIZE + 10)
                drawRectangleUsingBrush(qp, color, x, y,
                                        MainWindowContent.SQUARE_SIZE,
                                        MainWindowContent.SQUARE_SIZE)
                index += 1
 
        # vytvoření instance třídy QPixmap z objektu QImage
        self.pixmap = QtGui.QPixmap.fromImage(self.image)
 
    def prepareGUI(self):
        quitButton = self.prepareQuitButton()
        colorDialogButton = self.prepareColorDialogButton()
 
        # vytvoření správce geometrie
        topLayout = QtGui.QVBoxLayout()
 
        # vytvoření návěští
        self.colorPalette = QtGui.QLabel("test")
        # přiřazení rastrového obrázku k návěští
        self.colorPalette.setPixmap(self.pixmap)
 
        # umístění widgetů do okna
        topLayout.addWidget(self.colorPalette)
        topLayout.addWidget(colorDialogButton)
        topLayout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(topLayout)
 
    def prepareColorDialogButton(self):
        # tlačítko
        colorDialogButton = QtGui.QPushButton('Select color', self)
        colorDialogButton.resize(colorDialogButton.sizeHint())
 
        # navázání akce na signál
        colorDialogButton.clicked.connect(self.showColorDialog)
        return colorDialogButton
 
    def prepareQuitButton(self):
        # tlačítko
        quitButton = QtGui.QPushButton('Quit', self)
        quitButton.resize(quitButton.sizeHint())
 
        # navázání akce na signál
        quitButton.clicked.connect(QtCore.QCoreApplication.instance().quit)
        return quitButton
 
    def showColorDialog(self):
        colorDialog = QtGui.QColorDialog()
        colorDialog.setCurrentColor(QtGui.QColor("#aabbcc"))
        result = colorDialog.exec_()
        self.redrawColorBoxes()
        self.colorPalette.setPixmap(self.pixmap)
 
 
# nový widget bude odvozen od obecného hlavního okna
class MainWindow(QtGui.QMainWindow):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindow, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        # velikost není potřeba specifikovat
        # self.resize(320, 240)
        self.setWindowTitle("QColorDialog colors")
 
        # vložení komponenty do okna
        self.setCentralWidget(MainWindowContent())
 
    def run(self, app):
        # zobrazení okna na obrazovce
        self.show()
        # vstup do smyčky událostí (event loop)
        app.exec_()
 
 
def main():
    app = QtGui.QApplication(sys.argv)
    MainWindow().run(app)
 
 
if __name__ == '__main__':
    main()

14. Standardní dialog pro výběr souboru či adresáře

Již minule jsme se zmínili o tom, že knihovna PySide programátorům nabízí i standardní dialogy určené pro výběr souborů či adresářů pro otevření či naopak pro zápis. V nejjednodušším případě je použití těchto dialogů velmi snadné, zejména tehdy, pokud uživateli nabídneme libovolný soubor k otevření (nebudeme ho tedy omezovat jen na určité typy souborů) a pokud nezadáme výchozí cestu.

Příkladem může být dialog pro otevření souboru, přičemž výchozí adresář bude nastaven na pwd. Prvním parametrem je reference na hlavní okno aplikace, druhý parametr je textový popisek dialogu a třetím parametrem pak cesta (může a pro jistotu by měla být v Unicode):

fileName = QtGui.QFileDialog.getOpenFileName(self, "Open file", u".")

Obrázek 17: Standardní dialog pro výběr souboru.

Další možnosti těchto typů dialogů si popíšeme v navazujícím článku.

15. Osmý demonstrační příklad – výběr souboru pro otevření souboru

Osmý a současně i poslední demonstrační příklad, s nímž se dnes setkáme, po svém spuštění zobrazí okno, z něhož je možné spustit dialog určený pro otevření souboru, resp. přesněji řečeno pro výběr souboru z prakticky libovolného adresáře na disku. Po výběru souboru se jeho celá cesta zobrazí v informačním dialogu:

Obrázek 18: Zobrazení cesty k vybranému souboru.

root_podpora

Celý zdrojový kód tohoto příkladu vypadá následovně:

#!/usr/bin/env python
# vim: set fileencoding=utf-8
 
import sys
 
# import "jádra" frameworku Qt i modulu pro GUI
from PySide import QtCore
from PySide import QtGui
 
 
# nový widget bude odvozen od obecného widgetu
class MainWindowContent(QtGui.QWidget):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindowContent, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        quitButton = self.prepareQuitButton()
        openFileButton = self.prepareOpenFileButton()
 
        # vytvoření správce geometrie
        topLayout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        topLayout.addWidget(openFileButton)
        topLayout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(topLayout)
 
    def prepareOpenFileButton(self):
        # tlačítko
        openFileButton = QtGui.QPushButton('Open file...', self)
        openFileButton.resize(openFileButton.sizeHint())
 
        # navázání akce na signál
        openFileButton.clicked.connect(self.showOpenFileDialog)
        return openFileButton
 
    def prepareQuitButton(self):
        # tlačítko
        quitButton = QtGui.QPushButton('Quit', self)
        quitButton.resize(quitButton.sizeHint())
 
        # navázání akce na signál
        quitButton.clicked.connect(QtCore.QCoreApplication.instance().quit)
        return quitButton
 
    def showOpenFileDialog(self):
        fileName = QtGui.QFileDialog.getOpenFileName(self, "Open file", u".")
 
        # vytvoření dialogu
        msgBox = QtGui.QMessageBox()
        msgBox.setText(u'Vybraný soubor\n{f}'.format(f=fileName))
        msgBox.setIcon(QtGui.QMessageBox.Information)
        msgBox.exec_()
 
 
# nový widget bude odvozen od obecného hlavního okna
class MainWindow(QtGui.QMainWindow):
 
    def __init__(self):
        # zavoláme konstruktor předka
        super(MainWindow, self).__init__()
 
        # konfigurace GUI + přidání widgetu do okna
        self.prepareGUI()
 
    def prepareGUI(self):
        # velikost není potřeba specifikovat
        # self.resize(320, 240)
        self.setWindowTitle("QMessageBox")
 
        # vložení komponenty do okna
        self.setCentralWidget(MainWindowContent())
 
    def run(self, app):
        # zobrazení okna na obrazovce
        self.show()
        # vstup do smyčky událostí (event loop)
        app.exec_()
 
 
def main():
    app = QtGui.QApplication(sys.argv)
    MainWindow().run(app)
 
 
if __name__ == '__main__':
    main()

16. Repositář s demonstračními příklady

Zdrojové kódy všech devíti dnes popsaných demonstračních příkladů byly opět, podobně jako tomu bylo i v předchozích článcích, uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/pre­sentations. Pokud nechcete klonovat celý repositář, můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce:

17. Odkazy na Internetu

  1. PySide 1.2.1 documentation
    https://pyside.github.io/doc­s/pyside/index.html
  2. QAbstractSlider
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/Abstrac­tSlider.html
  3. QScrollBar
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/Scro­llBar.html
  4. QSlider
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/Sli­der.html
  5. QDial
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/Dial­.html
  6. QImage
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QIma­ge.html
  7. QPixmap
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QPix­map.html
  8. QBitmap
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QBit­map.html
  9. QPaintDevice
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QPa­intDevice.html
  10. QPicture
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QPic­ture.html
  11. QPainter
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QPa­inter.html
  12. QPainterPath
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QPa­interPath.html
  13. QGradient
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QGra­dient.html
  14. QLinearGradient
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QLi­nearGradient.html
  15. QRadialGradient
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QRa­dialGradient.html
  16. QTableWidget
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QTa­bleWidget.html
  17. QTableWidgetItem
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QTa­bleWidgetItem.html
  18. QTreeWidget
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QTre­eWidget.html
  19. QTreeWidgetItem
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QTre­eWidgetItem.html
  20. Afinní zobrazení
    https://cs.wikipedia.org/wi­ki/Afinn%C3%AD_zobrazen%C3%AD
  21. Differences Between PySide and PyQt
    https://wiki.qt.io/Differen­ces_Between_PySide_and_PyQt
  22. PySide 1.2.1 tutorials
    https://pyside.github.io/doc­s/pyside/tutorials/index.html
  23. PySide tutorial
    http://zetcode.com/gui/py­sidetutorial/
  24. Drawing in PySide
    http://zetcode.com/gui/py­sidetutorial/drawing/
  25. Qt Core
    https://pyside.github.io/doc­s/pyside/PySide/QtCore/Qt­.html
  26. QLayout
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QLa­yout.html
  27. QValidator
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QVa­lidator.html
  28. QStackedLayout
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QStac­kedLayout.html
  29. QFormLayout
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QFor­mLayout.html
  30. QBoxLayout
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QBox­Layout.html
  31. QHBoxLayout
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QHBox­Layout.html
  32. QVBoxLayout
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QVBox­Layout.html
  33. QGridLayout
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QGrid­Layout.html
  34. QAction
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QAc­tion.html
  35. QDialog
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QDi­alog.html
  36. QMessageBox
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QMes­sageBox.html
  37. QErrorMessage
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QError­Message.html
  38. QInputDialog
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QIn­putDialog.html
  39. QColorDialog
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QCo­lorDialog.html
  40. QListWidget
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QLis­tWidget.html
  41. Signals & Slots
    http://doc.qt.io/qt-4.8/signalsandslots.html
  42. Signals and Slots in PySide
    http://wiki.qt.io/Signals_an­d_Slots_in_PySide
  43. Intro to PySide/PyQt: Basic Widgets and Hello, World!
    http://www.pythoncentral.io/intro-to-pysidepyqt-basic-widgets-and-hello-world/
  44. QLineEdit
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QLi­neEdit.html
  45. QTextEdit
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QTex­tEdit.html
  46. QValidator
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QVa­lidator.html
  47. QIntValidator
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QIn­tValidator.html
  48. QRegExpValidator
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QRe­gExpValidator.html
  49. QWidget
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QWid­get.html
  50. QMainWindow
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QMa­inWindow.html
  51. QLabel
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QLa­bel.html
  52. QAbstractButton
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QAb­stractButton.html
  53. QCheckBox
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QChec­kBox.html
  54. QRadioButton
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QRa­dioButton.html
  55. QButtonGroup
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QBut­tonGroup.html
  56. QFrame
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QFra­me.html#PySide.QtGui.PySi­de.QtGui.QFrame
  57. QFrame.frameStyle
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QFra­me.html#PySide.QtGui.PySi­de.QtGui.QFrame.frameStyle
  58. Leo editor
    http://leoeditor.com/
  59. IPython Qt Console aneb vylepšený pseudoterminál
    https://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-ipython-a-ipython-notebook/#k06
  60. Vývojová prostředí ve Fedoře (4. díl)
    https://mojefedora.cz/vyvojova-prostredi-ve-fedore-4-dil/
  61. Seriál Letní škola programovacího jazyka Logo
    http://www.root.cz/serialy/letni-skola-programovaciho-jazyka-logo/
  62. Educational programming language
    http://en.wikipedia.org/wi­ki/Educational_programmin­g_language
  63. Logo Tree Project:
    http://www.elica.net/downlo­ad/papers/LogoTreeProject­.pdf
  64. Hra Breakout napísaná v Tkinteri
    https://www.root.cz/clanky/hra-breakout-napisana-v-tkinteri/
  65. Hra Snake naprogramovaná v Pythone s pomocou Tkinter
    https://www.root.cz/clanky/hra-snake-naprogramovana-v-pythone-s-pomocou-tkinter/
  66. 24.1. turtle — Turtle graphics
    https://docs.python.org/3­.5/library/turtle.html#mo­dule-turtle
  67. TkDND
    http://freecode.com/projects/tkdnd
  68. Python Tkinter Fonts
    https://www.tutorialspoin­t.com/python/tk_fonts.htm
  69. The Tkinter Canvas Widget
    http://effbot.org/tkinter­book/canvas.htm
  70. Ovládací prvek (Wikipedia)
    https://cs.wikipedia.org/wi­ki/Ovl%C3%A1dac%C3%AD_prvek_­%28po%C4%8D%C3%ADta%C4%8D%29
  71. Rezervovaná klíčová slova v Pythonu
    https://docs.python.org/3/re­ference/lexical_analysis.html#ke­ywords
  72. TkDocs: Styles and Themes
    http://www.tkdocs.com/tuto­rial/styles.html
  73. Drawing in Tkinter
    http://zetcode.com/gui/tkin­ter/drawing/
  74. Changing ttk widget text color (StackOverflow)
    https://stackoverflow.com/qu­estions/16240477/changing-ttk-widget-text-color
  75. The Hitchhiker's Guide to Pyhton: GUI Applications
    http://docs.python-guide.org/en/latest/scenarios/gui/
  76. 7 Top Python GUI Frameworks for 2017
    http://insights.dice.com/2014/11/26/5-top-python-guis-for-2015/
  77. GUI Programming in Python
    https://wiki.python.org/mo­in/GuiProgramming
  78. Cameron Laird's personal notes on Python GUIs
    http://phaseit.net/claird/com­p.lang.python/python_GUI.html
  79. Python GUI development
    http://pythoncentral.io/introduction-python-gui-development/
  80. Graphic User Interface FAQ
    https://docs.python.org/2/faq/gu­i.html#graphic-user-interface-faq
  81. TkInter
    https://wiki.python.org/moin/TkInter
  82. Tkinter 8.5 reference: a GUI for Python
    http://infohost.nmt.edu/tcc/hel­p/pubs/tkinter/web/index.html
  83. TkInter (Wikipedia)
    https://en.wikipedia.org/wiki/Tkinter
  84. appJar
    http://appjar.info/
  85. appJar (Wikipedia)
    https://en.wikipedia.org/wiki/AppJar
  86. appJar na Pythonhosted
    http://pythonhosted.org/appJar/
  87. appJar widgets
    http://appjar.info/pythonWidgets/
  88. Stránky projektu PyGTK
    http://www.pygtk.org/
  89. PyGTK (Wikipedia)
    https://cs.wikipedia.org/wiki/PyGTK
  90. Stránky projektu PyGObject
    https://wiki.gnome.org/Pro­jects/PyGObject
  91. Stránky projektu Kivy
    https://kivy.org/#home
  92. Stránky projektu PyQt
    https://riverbankcomputin­g.com/software/pyqt/intro
  93. PyQt (Wikipedia)
    https://cs.wikipedia.org/wiki/PyGTK
  94. Stránky projektu PySide
    https://wiki.qt.io/PySide
  95. PySide (Wikipedia)
    https://en.wikipedia.org/wiki/PySide
  96. Stránky projektu Kivy
    https://kivy.org/#home
  97. Kivy (framework, Wikipedia)
    https://en.wikipedia.org/wi­ki/Kivy_(framework)
  98. QML Applications
    http://doc.qt.io/qt-5/qmlapplications.html
  99. KDE
    https://www.kde.org/
  100. Qt
    https://www.qt.io/
  101. GNOME
    https://en.wikipedia.org/wiki/GNOME
  102. Category:Software that uses PyGTK
    https://en.wikipedia.org/wi­ki/Category:Software_that_u­ses_PyGTK
  103. Category:Software that uses PyGObject
    https://en.wikipedia.org/wi­ki/Category:Software_that_u­ses_PyGObject
  104. Category:Software that uses wxWidgets
    https://en.wikipedia.org/wi­ki/Category:Software_that_u­ses_wxWidgets
  105. GIO
    https://developer.gnome.or­g/gio/stable/
  106. GStreamer
    https://gstreamer.freedesktop.org/
  107. GStreamer (Wikipedia)
    https://en.wikipedia.org/wi­ki/GStreamer
  108. Wax Gui Toolkit
    https://wiki.python.org/moin/Wax
  109. Python Imaging Library (PIL)
    http://infohost.nmt.edu/tcc/hel­p/pubs/pil/
  110. Why Pyjamas Isn’t a Good Framework for Web Apps (blogpost z roku 2012)
    http://blog.pyjeon.com/2012/07/29/why-pyjamas-isnt-a-good-framework-for-web-apps/

Byl pro vás článek přínosný?