Obsah
1. Standardní dialogy v knihovně PySide
2. Dialog pro zobrazení zprávy uživateli
3. První demonstrační příklad: jednoduchý dialog s ikonou a textovou zprávou
4. Dialog určený pro zobrazení chybové zprávy
5. Druhý demonstrační příklad: zobrazení chybové zprávy
6. Jednoduché dialogy pro vstup údajů
7. Vstupní dialog nakonfigurovaný pro zadání běžného textu
8. Třetí demonstrační příklad: dialog pro zadání jednořádkového textu
9. Vstupní dialog nakonfigurovaný pro zadání celého čísla
10. Čtvrtý demonstrační příklad: dialog pro specifikaci celého čísla
11. Vstupní dialog nakonfigurovaný pro zadání reálného čísla
12. Pátý demonstrační příklad: dialog pro specifikaci reálného čísla
13. Dialog s výběrem prvku ze seznamu nebo kombo boxu
14. Šestý demonstrační příklad: výběr prvku z kombo boxu
15. Sedmý demonstrační příklad: výběr prvku ze seznamu
16. Standardní dialog pro výběr barvy z palety
17. Osmý demonstrační příklad: dialog pro výběr barvy
18. Repositář s demonstračními příklady
1. Standardní dialogy v knihovně PySide
V dnešním článku se seznámíme s dalšími možnostmi nabízenými knihovnou PySide. Podobně, jako je tomu i v dalších frameworcích určených pro tvorbu aplikací s grafickým uživatelským rozhraním, nabízí i knihovna PySide programátorům několik typů standardních dialogů. Tyto dialogy jsou navrženy takovým způsobem, aby svým vzhledem i chováním odpovídaly chování aplikací na dané platformě. Současná verze knihovny PySide nabízí tyto dialogy (jejich třídy jsou odvozeny od obecného dialogu QDialog):
Třída | Stručný popis |
---|---|
QMessageBox | zobrazení zprávy uživateli |
QErrorMessage | zobrazení chybové zprávy popř. průběžně se doplňujících informací |
QInputDialog | vyžádání vstupu od uživatele |
QColorDialog | výběr barvy |
QFontDialog | výběr fontu |
QFileDialog | výběr souboru nebo adresáře |
QAbstractPrintDialog | základní implementace dialogu pro konfiguraci tiskáren |
QPrintDialog | ucelený dialog pro výběr a konfiguraci tiskárny |
QAbstractPageSetupDialog | základní implementace dialogu pro nastavení tisku dokumentu |
QPageSetupDialog | nastavení tisku dokumentu |
QWizard | dialog sestavený ze sekvence „stránek“, které uživatel postupně vyplňuje |
QProgressDialog | zobrazení průběhu déletrvající operace |
QPrintPreviewDialog | dialog pro náhled na dokument, který se má vytisknout + pro nastavení tiskových stran atd. |
Všechny tyto typy dialogů si postupně popíšeme.
2. Dialog pro zobrazení zprávy uživateli
Nejjednodušším dialogem podporovaným knihovnou PySide je dialog určený pro zobrazení zprávy uživateli. V tomto dialogu je možné kromě vlastní jednořádkové či víceřádkové zprávy specifikovat i ikonu zobrazenou uživateli a popř. upravit počet a význam tlačítek. Podívejme se, jak se tento dialog zobrazí. Není to nic složitého:
def showMessageBox(self): msgBox = QtGui.QMessageBox() msgBox.setText(u'Zpráva') msgBox.exec_()
Obrázek 1: Dialog s ikonou QMessageBox.Information.
Ikonu vkládanou do dialogu je možné nakonfigurovat dvěma způsoby. Buď lze použít metodu setIconPixmap(), které se předá libovolná pixmapa, což je sice řešení flexibilní, ovšem bude složité vybrat takovou ikonu, která zapadne do L&F celého desktopového prostředí. Pokud se jedná o nějakou zprávu se standardním významem, je výhodnější namísto setIconPixmap() zavolat metodu nazvanou setIcon(), které se předá jedna z následujících konstant:
Ikona |
---|
QMessageBox.NoIcon |
QMessageBox.Question |
QMessageBox.Information |
QMessageBox.Warning |
QMessageBox.Critical |
Obrázek 2: Dialog s ikonou QMessageBox.Question.
Vytvoření dialogu tedy může vypadat následovně:
def showMessageBox(self): msgBox = QtGui.QMessageBox() msgBox.setText(u'Zpráva') msgBox.setIcon(QtGui.QMessageBox.Information) msgBox.exec_()
Obrázek 3: Dialog s ikonou QMessageBox.Warning.
Dialog lze konfigurovat i dalšími způsoby, například do něj je možné přidávat další tlačítka. S těmito způsoby se seznámíme v závěrečné části tohoto článku.
Obrázek 4: Dialog s ikonou QMessageBox.Critical.
3. První demonstrační příklad: jednoduchý dialog s ikonou a textovou zprávou
V dnešním prvním demonstračním příkladu je ukázán způsob zobrazení jednoduchého dialogu, v němž je umístěna informační ikona a taktéž zpráva. Ta může být jednořádková či víceřádková. Tento dialog zobrazíte po výběru tlačítka „Message Box“, jehož stisk zavolá handler showMessageBox (kód této funkce byl ukázán v předchozí kapitole):
#!/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): msgBox = QtGui.QMessageBox() msgBox.setText(u'Zpráva') 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()
4. Dialog pro zobrazení chybové zprávy
Druhým typem dialogu, s nímž se v dnešním článku setkáme, je dialog sloužící pro zobrazení chybové zprávy popř. pro doplnění dalších informací o chybě. Tento dialog je reprezentován třídou QErrorMessage, popř. potomky této třídy. Jedním z podstatných rozdílů mezi tímto dialogem a výše popsaným dialogem QMessageBox je fakt, že u chybového dialogu je možné s využitím zobrazeného zatrhávacího tlačítka (checkboxu) zajistit, aby se již podobné typy zpráv uživateli nezobrazovaly. Nejprve se však podívejme na tu nejjednodušší variantu dialogu se zobrazením chybové zprávy. Ten se nakonfiguruje následujícím způsobem:
def showErrorMessage(self): msgBox = QtGui.QErrorMessage() msgBox.showMessage(u'Chybová zpráva') msgBox.exec_()
Obrázek 5: Dialog se zobrazením chybové zprávy a taktéž se zatrhávacím tlačítkem, pomocí něhož lze pozastavit výpis podobných typů zpráv.
5. Druhý demonstrační příklad: zobrazení chybové zprávy
Zobrazení jednoduché chybové zprávy v chybovém dialogu, prozatím ovšem bez naprogramování reakce na nastavení checkboxu uživatelem, je ukázán v dnešním druhém demonstračním příkladu, jehož zdrojový kód je zobrazen pod tímto odstavcem:
#!/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() errorMessageButton = self.prepareErrorMessageButton() # vytvoření správce geometrie topLayout = QtGui.QVBoxLayout() # umístění widgetů do okna topLayout.addWidget(errorMessageButton) topLayout.addWidget(quitButton) # nastavení správce geometrie a vložení všech komponent do okna self.setLayout(topLayout) def prepareErrorMessageButton(self): # tlačítko errorMessageButton = QtGui.QPushButton('Error Message', self) errorMessageButton.resize(errorMessageButton.sizeHint()) # navázání akce na signál errorMessageButton.clicked.connect(self.showErrorMessage) return errorMessageButton 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 showErrorMessage(self): msgBox = QtGui.QErrorMessage() msgBox.showMessage(u'Chybová zpráva') 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("QErrorMessage") # 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. Jednoduché dialogy pro vstup údajů
V případě, že budeme od uživatele vyžadovat zadání nějakých údajů popř. výběr prvků z nějakého seznamu, máme k dispozici tři možnosti:
- Použít běžné ovládací prvky (widgety) určené pro vstup údajů a zabudovat tyto widgety přímo do oken aplikace. S většinou těchto widgetů jsme se již setkali, další si popíšeme v navazujících částech tohoto seriálu.
- Naprogramovat si vlastní vstupní dialogy, ať již modální či nemodální.
- Využít standardní typ dialogu představovaný třídouQInputDialog. Možnosti nabízené touto třídou jsou sice na jednu stranu omezené (vždy jen jeden typ vstupu), na stranu druhou je však použití standardních dialogů velmi jednoduché – většinou se jedná o pouhých několik řádků v programu.
V navazujících kapitolách si ukážeme pět různých podob dialogů podporovaných třídou QInputDialog
- Dialog pro vstup textu
- Dialog pro vstup celočíselné hodnoty
- Dialog pro vstup reálné hodnoty
- Dialog pro výběr prvku s využitím kombo boxu
- Dialog pro výběr prvku ze seznamu
7. Vstupní dialog nakonfigurovaný pro zadání běžného textu
První typ dialogu, který očekává vstup od uživatele, je dialog určený pro zápis běžného jednořádkového textu. Pokud budete chtít tento dialog v aplikaci použít, postačuje vytvořit instanci třídy QInputDialog, nastavit typ vstupu na hodnotu QInputDialog.TextInput a po uzavření dialogu zjistit, jaký text byl uživatelem zapsán, pomocí metody QInputDialog.textValue():
def textInputDialogHandler(self): # vytvoření a konfigurace vstupního dialogu dialog = QtGui.QInputDialog(self) dialog.setInputMode(QtGui.QInputDialog.TextInput) # zobrazení dialogu a čekání na uživatelský vstup result = dialog.exec_() # zpracování výsledků return dialog.textValue()
Při práci s tímto typem dialogu můžeme použít několik metod pro jeho další konfiguraci:
Metoda | Význam |
---|---|
setLabelText | výzva, která je zobrazena nad nebo vedle vstupního textového pole |
setTextValue | výchozí text, který je do pole zapsán ve chvíli zobrazení dialogu |
setOkButtonText | text zobrazený na tlačítku [Ok] |
setCancelButtonText | text zobrazený na tlačítku [Storno] |
setEchoMode | nastavení zpětné vazby mezi zapisovaným textem a obsahem textového pole (modifikováno u zápisu hesla atd.) |
Samotné vstupní textové pole se ovládá naprosto stejně jako již popsaný widget QLineEdit.
Většinou je nutné rozlišit, zda bylo stlačeno tlačítko [Ok] nebo [Storno]. Pro tento účel je nutné otestovat návratovou hodnotu metody QInputDialog.exec_(), například takto:
def textInputDialogHandler(self): # vytvoření a konfigurace vstupního dialogu dialog = QtGui.QInputDialog(self) dialog.setInputMode(QtGui.QInputDialog.TextInput) dialog.setLabelText("Text input:") dialog.setTextValue("default text") # 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") self.showMessageBox(message)
Obrázek 6: Dialog pro vstup běžného jednořádkového textu.
8. Třetí demonstrační příklad: dialog pro zadání jednořádkového textu
V dnešním třetím demonstračním příkladu je ukázán jak způsob zobrazení dialogu určeného pro zadání jednořádkového textu, tak i otestování, zda uživatel po zadání textu vybral tlačítko [Ok] nebo [Storno], což je důležité, protože i při stisku tlačítka [Storno] se vrátí vyplněná hodnota textového políčka a nikoli (například) prázdný řetězec či None. Podívejme se nyní na zdrojový kód 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 # 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) dialog.setLabelText("Text input:") dialog.setTextValue("default text") # 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") 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): msgBox = QtGui.QMessageBox() msgBox.setText(text) 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("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()
9. Vstupní dialog nakonfigurovaný pro zadání celého čísla
Vstupní dialog QInputDialog je možné nakonfigurovat takovým způsobem, aby namísto libovolného textu bylo možné zadat pouze celočíselnou hodnotu, navíc v předem známém rozsahu. Vedle vstupního pole se zobrazí pomocná tlačítka „nahoru“ a „dolů“, kterými lze číselné hodnoty přetáčet (stejně bude fungovat i kolečko myši). Aby se skutečně povolil vstup celočíselných údajů, je nutné specifikovat vstupní režim, a to takto:
dialog.setInputMode(QtGui.QInputDialog.IntInput)
Dialog se zobrazí metodou exec_(), s níž jsme se již setkali v předchozích kapitolách. Po uzavření dialogu se přečtení hodnoty ze vstupního pole provádí metodou intValue() a nikoli textValue():
def integerInputDialogHandler(self): # vytvoření a konfigurace vstupního dialogu dialog = QtGui.QInputDialog(self) dialog.setInputMode(QtGui.QInputDialog.IntInput) # zobrazení dialogu a čekání na uživatelský vstup result = dialog.exec_() # zpracování výsledků return dialog.intValue()
Obrázek 7: Dialog pro vstup celočíselné hodnoty ze zadaného rozsahu.
Kromě již zmíněných metod je ještě možné nastavit další parametry pole pro vstup celočíselných údajů a tím do jisté míry omezit další programové kontroly prováděné po uzavření dialogu (implicitně je možné zadávat jen hodnoty do 99):
Metoda | Význam |
---|---|
setIntValue | výchozí číselná hodnota zobrazená společně s dialogem |
setIntMinimum | minimální povolená číselná hodnota |
setIntMaximum | maximální povolená číselná hodnota |
setIntRange | kombinace obou předchozích metod (předávají se dvě hodnoty min a max) |
setIntStep | krok při použití kolečka myši nebo tlačítek „nahoru“ a „dolů“ |
Výše uvedené metody se použijí takto:
def integerInputDialogHandler(self): # vytvoření a konfigurace vstupního dialogu dialog = QtGui.QInputDialog(self) dialog.setInputMode(QtGui.QInputDialog.IntInput) dialog.setLabelText("Integer input:") dialog.setIntValue(15) dialog.setIntMinimum(10) dialog.setIntMaximum(20) # zobrazení dialogu a čekání na uživatelský vstup result = dialog.exec_() # zpracování a zobrazení výsledků value = dialog.intValue() message = "Entered value: '{v}'\nClicked on: {c}".format( v=value, c="Ok" if result == 1 else "Cancel")
10. Čtvrtý demonstrační příklad: dialog pro specifikaci celého čísla
Použití standardního dialogu, který po svém zobrazení očekává zadání celého čísla od uživatele, je ukázáno v dnešním čtvrtém demonstračním příkladu, jehož zdrojový kód je zobrazen pod tímto odstavcem:
#!/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() integerInputDialogButton = self.prepareButton( "Integer value input", self.integerInputDialogHandler) # vytvoření správce geometrie topLayout = QtGui.QVBoxLayout() # umístění widgetů do okna topLayout.addWidget(integerInputDialogButton) topLayout.addWidget(quitButton) # nastavení správce geometrie a vložení všech komponent do okna self.setLayout(topLayout) def integerInputDialogHandler(self): # vytvoření a konfigurace vstupního dialogu dialog = QtGui.QInputDialog(self) dialog.setInputMode(QtGui.QInputDialog.IntInput) dialog.setLabelText("Integer input:") dialog.setIntMinimum(10) dialog.setIntMaximum(20) # zobrazení dialogu a čekání na uživatelský vstup result = dialog.exec_() # zpracování a zobrazení výsledků value = dialog.intValue() message = "Entered value: '{v}'\nClicked on: {c}".format( v=value, c="Ok" if result == 1 else "Cancel") 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): msgBox = QtGui.QMessageBox() msgBox.setText(text) 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("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()
11. Vstupní dialog nakonfigurovaný pro zadání reálného čísla
Jen nepatrnou úpravou je možné zajistit, aby vstupní dialog akceptoval reálná čísla a nikoli jen čísla celá:
dialog.setInputMode(QtGui.QInputDialog.DoubleInput)
U tohoto typu vstupu je opět možné nastavit minimální a maximální akceptovatelné hodnoty, navíc je ovšem možné specifikovat, kolik desetinných míst se implicitně zobrazí:
Metoda | Význam |
---|---|
setDoubleValue | výchozí číselná hodnota zobrazená společně s dialogem |
setDoubleMinimum | minimální povolená číselná hodnota |
setDoubleMaximum | maximální povolená číselná hodnota |
setDoubleRange | kombinace obou předchozích metod (předávají se dvě hodnoty min a max) |
setDoubleStep | krok při použití kolečka myši nebo tlačítek „nahoru“ a „dolů“ |
setDoubleDecimals | počet zobrazených desetinných míst |
Příklad použití dialogu pro zadání reálného čísla:
def doubleInputDialogHandler(self): # vytvoření a konfigurace vstupního dialogu dialog = QtGui.QInputDialog(self) dialog.setInputMode(QtGui.QInputDialog.DoubleInput) dialog.setLabelText("Double value input:") dialog.setDoubleRange(0.0, 7.5) dialog.setDoubleDecimals(2) # zobrazení dialogu a čekání na uživatelský vstup result = dialog.exec_() # zpracování a zobrazení výsledků value = dialog.doubleValue() message = "Entered value: '{v}'\nClicked on: {c}".format( v=value, c="Ok" if result == 1 else "Cancel") self.showMessageBox(message)
Obrázek 8: Dialog pro vstup reálné hodnoty ze zadaného rozsahu.
12. Pátý demonstrační příklad: dialog pro specifikaci reálného čísla
Opět se podívejme na to, jakým způsobem lze nakonfigurovat dialog určený pro specifikaci reálného čísla uživatelem. Používáme přitom metody popsané v předchozí kapitole. Následuje výpis zdrojového kódu 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 # 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() doubleInputDialogButton = self.prepareButton( "Double value input", self.doubleInputDialogHandler) # vytvoření správce geometrie topLayout = QtGui.QVBoxLayout() # umístění widgetů do okna topLayout.addWidget(doubleInputDialogButton) topLayout.addWidget(quitButton) # nastavení správce geometrie a vložení všech komponent do okna self.setLayout(topLayout) def doubleInputDialogHandler(self): # vytvoření a konfigurace vstupního dialogu dialog = QtGui.QInputDialog(self) dialog.setInputMode(QtGui.QInputDialog.DoubleInput) dialog.setLabelText("Double value input:") dialog.setDoubleRange(0.0, 7.5) dialog.setDoubleDecimals(2) # zobrazení dialogu a čekání na uživatelský vstup result = dialog.exec_() # zpracování a zobrazení výsledků value = dialog.doubleValue() message = "Entered value: '{v}'\nClicked on: {c}".format( v=value, c="Ok" if result == 1 else "Cancel") 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): msgBox = QtGui.QMessageBox() msgBox.setText(text) 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("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()
13. Dialog s výběrem prvku ze seznamu nebo kombo boxu
Poslední možností, kterou nám QInputDialog nabízí, je výběr prvku z předem zadaného seznamu. Tento seznam se zobrazí buď pomocí kombo boxu (což šetří místo na úkor přehlednosti) nebo klasickým seznamem. Použití kombo boxu se provede následovně:
def textInputDialogHandler(self): # vytvoření a konfigurace vstupního dialogu dialog = QtGui.QInputDialog(self) dialog.setLabelText("Your choice:") dialog.setComboBoxItems(["Assembler", "Bash", "C", "C++", "Clojure", "Python"]) # zobrazení dialogu a čekání na uživatelský vstup result = dialog.exec_() # zpracování výsledků return dialog.textValue()
Obrázek 9: Výběr prvku s využitím kombo boxu.
Pokud preferujete klasický seznam, je funkci zapotřebí nepatrně upravit:
def textInputDialogHandler(self): # vytvoření a konfigurace vstupního dialogu dialog = QtGui.QInputDialog(self) dialog.setLabelText("Your choice:") dialog.setOption(QtGui.QInputDialog.UseListViewForComboBoxItems, True) dialog.setComboBoxItems(["Assembler", "Bash", "C", "C++", "Clojure", "Python"]) # zobrazení dialogu a čekání na uživatelský vstup result = dialog.exec_() # zpracování výsledků return dialog.textValue()
14. Šestý demonstrační příklad: výběr prvku z kombo boxu
Zobrazení dialogu, který si od uživatele vyžádá výběr prvku z kombo boxu, je implementováno v dnešním šestém demonstračním příkladu, jehož zdrojový kód je zobrazen pod tímto odstavcem:
#!/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.setLabelText("Your choice:") dialog.setComboBoxItems(["Assembler", "Bash", "C", "C++", "Clojure", "Python"]) # 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") 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): msgBox = QtGui.QMessageBox() msgBox.setText(text) 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("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()
15. Sedmý demonstrační příklad: výběr prvku ze seznamu
Sedmý demonstrační příklad se od příkladu předchozího odlišuje pouze v jediném řádku:
dialog.setOption(QtGui.QInputDialog.UseListViewForComboBoxItems, True)
Tímto řádkem se specifikuje použití klasického list boxu namísto kombo boxu. Navíc si povšimněte, že implicitně není vybrán žádný prvek a tudíž dialog zobrazí tlačítko [Ok] šedou barvou a nebude ho možné stisknout do té doby, dokud uživatel nějaký prvek explicitně nevybere:
Obrázek 10: Screenshot dialogu ze sedmého demonstračního příkladu.
Opět 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) # 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.setLabelText("Your choice:") dialog.setOption(QtGui.QInputDialog.UseListViewForComboBoxItems, True) dialog.setComboBoxItems(["Assembler", "Bash", "C", "C++", "Clojure", "Python"]) # 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") 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): msgBox = QtGui.QMessageBox() msgBox.setText(text) 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("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()
16. Standardní dialog pro výběr barvy z palety
Poslední typ standardního dialogu, s nímž se dnes setkáme, slouží pro výběr barvy z barvové palety. Tento dialog je představován třídou QColorDialog a zobrazit je ho snadné:
def showColorDialog(self): colorDialog = QtGui.QColorDialog() result = colorDialog.exec_() selected = colorDialog.selectedColor()
Před zobrazením tohoto dialogu je možné přednastavit barvu, a to s využitím metody setCurrentColor(), které se předá instanci třídy QColor:
def showColorDialog(self): colorDialog = QtGui.QColorDialog() colorDialog.setCurrentColor(QtGui.QColor("#aabbcc")) result = colorDialog.exec_() selected = colorDialog.selectedColor()
Pokud budete chtít zjistit, jakou barvu uživatel vybral, stačí po zobrazení dialogu zavolat metodu selectedColor() a z navrácené hodnoty pak metodami red(), green() a blue() získat jednotlivé barvové složky:
def showColorDialog(self): colorDialog = QtGui.QColorDialog() colorDialog.setCurrentColor(QtGui.QColor("#aabbcc")) result = colorDialog.exec_() selected = colorDialog.selectedColor() message = "Selected color: {r} {g} {b}\nClicked on: {c}".format( r=selected.red(), g=selected.green(), b=selected.blue(), c="Ok" if result == 1 else "Cancel") self.showMessageBox(message)
Obrázek 11: Standardní dialog pro výběr barvy.
17. Osmý demonstrační příklad: dialog pro výběr barvy
V osmém demonstračním příkladu si ukážeme, jakým způsobem je možné použít standardní dialog určený pro výběr barvy. Základní postup pro použití tohoto typu dialogu jsme si již vysvětlili v předchozí kapitole, takže zde jen pro úplnost dialog zabudujeme do naší testovací aplikace:
#!/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() colorDialogButton = self.prepareColorDialogButton() # vytvoření správce geometrie topLayout = QtGui.QVBoxLayout() # umístění widgetů do okna 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_() selected = colorDialog.selectedColor() message = "Selected color: {r} {g} {b}\nClicked on: {c}".format( r=selected.red(), g=selected.green(), b=selected.blue(), c="Ok" if result == 1 else "Cancel") self.showMessageBox(message) def showMessageBox(self, text): msgBox = QtGui.QMessageBox() msgBox.setText(text) 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("QColorDialog") # 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()
18. Repositář s demonstračními příklady
Zdrojové kódy všech osmi 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/presentations. Pokud nechcete klonovat celý repositář, můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce:
19. Odkazy na Internetu
- PySide 1.2.1 documentation
https://pyside.github.io/docs/pyside/index.html - QAbstractSlider
https://pyside.github.io/docs/pyside/PySide/QtGui/AbstractSlider.html - QScrollBar
https://pyside.github.io/docs/pyside/PySide/QtGui/ScrollBar.html - QSlider
https://pyside.github.io/docs/pyside/PySide/QtGui/Slider.html - QDial
https://pyside.github.io/docs/pyside/PySide/QtGui/Dial.html - QImage
https://pyside.github.io/docs/pyside/PySide/QtGui/QImage.html - QPixmap
https://pyside.github.io/docs/pyside/PySide/QtGui/QPixmap.html - QBitmap
https://pyside.github.io/docs/pyside/PySide/QtGui/QBitmap.html - QPaintDevice
https://pyside.github.io/docs/pyside/PySide/QtGui/QPaintDevice.html - QPicture
https://pyside.github.io/docs/pyside/PySide/QtGui/QPicture.html - QPainter
https://pyside.github.io/docs/pyside/PySide/QtGui/QPainter.html - QPainterPath
https://pyside.github.io/docs/pyside/PySide/QtGui/QPainterPath.html - QGradient
https://pyside.github.io/docs/pyside/PySide/QtGui/QGradient.html - QLinearGradient
https://pyside.github.io/docs/pyside/PySide/QtGui/QLinearGradient.html - QRadialGradient
https://pyside.github.io/docs/pyside/PySide/QtGui/QRadialGradient.html - QTableWidget
https://pyside.github.io/docs/pyside/PySide/QtGui/QTableWidget.html - QTableWidgetItem
https://pyside.github.io/docs/pyside/PySide/QtGui/QTableWidgetItem.html - QTreeWidget
https://pyside.github.io/docs/pyside/PySide/QtGui/QTreeWidget.html - QTreeWidgetItem
https://pyside.github.io/docs/pyside/PySide/QtGui/QTreeWidgetItem.html - Afinní zobrazení
https://cs.wikipedia.org/wiki/Afinn%C3%AD_zobrazen%C3%AD - Differences Between PySide and PyQt
https://wiki.qt.io/Differences_Between_PySide_and_PyQt - PySide 1.2.1 tutorials
https://pyside.github.io/docs/pyside/tutorials/index.html - PySide tutorial
http://zetcode.com/gui/pysidetutorial/ - Drawing in PySide
http://zetcode.com/gui/pysidetutorial/drawing/ - Qt Core
https://pyside.github.io/docs/pyside/PySide/QtCore/Qt.html - QLayout
https://pyside.github.io/docs/pyside/PySide/QtGui/QLayout.html - QValidator
https://pyside.github.io/docs/pyside/PySide/QtGui/QValidator.html - QStackedLayout
https://pyside.github.io/docs/pyside/PySide/QtGui/QStackedLayout.html - QFormLayout
https://pyside.github.io/docs/pyside/PySide/QtGui/QFormLayout.html - QBoxLayout
https://pyside.github.io/docs/pyside/PySide/QtGui/QBoxLayout.html - QHBoxLayout
https://pyside.github.io/docs/pyside/PySide/QtGui/QHBoxLayout.html - QVBoxLayout
https://pyside.github.io/docs/pyside/PySide/QtGui/QVBoxLayout.html - QGridLayout
https://pyside.github.io/docs/pyside/PySide/QtGui/QGridLayout.html - QAction
https://pyside.github.io/docs/pyside/PySide/QtGui/QAction.html - QDialog
https://pyside.github.io/docs/pyside/PySide/QtGui/QDialog.html - QMessageBox
https://pyside.github.io/docs/pyside/PySide/QtGui/QMessageBox.html - QErrorMessage
https://pyside.github.io/docs/pyside/PySide/QtGui/QErrorMessage.html - QInputDialog
https://pyside.github.io/docs/pyside/PySide/QtGui/QInputDialog.html - QColorDialog
https://pyside.github.io/docs/pyside/PySide/QtGui/QColorDialog.html - QListWidget
https://pyside.github.io/docs/pyside/PySide/QtGui/QListWidget.html - Signals & Slots
http://doc.qt.io/qt-4.8/signalsandslots.html - Signals and Slots in PySide
http://wiki.qt.io/Signals_and_Slots_in_PySide - Intro to PySide/PyQt: Basic Widgets and Hello, World!
http://www.pythoncentral.io/intro-to-pysidepyqt-basic-widgets-and-hello-world/ - QLineEdit
https://pyside.github.io/docs/pyside/PySide/QtGui/QLineEdit.html - QTextEdit
https://pyside.github.io/docs/pyside/PySide/QtGui/QTextEdit.html - QValidator
https://pyside.github.io/docs/pyside/PySide/QtGui/QValidator.html - QIntValidator
https://pyside.github.io/docs/pyside/PySide/QtGui/QIntValidator.html - QRegExpValidator
https://pyside.github.io/docs/pyside/PySide/QtGui/QRegExpValidator.html - QWidget
https://pyside.github.io/docs/pyside/PySide/QtGui/QWidget.html - QMainWindow
https://pyside.github.io/docs/pyside/PySide/QtGui/QMainWindow.html - QLabel
https://pyside.github.io/docs/pyside/PySide/QtGui/QLabel.html - QAbstractButton
https://pyside.github.io/docs/pyside/PySide/QtGui/QAbstractButton.html - QCheckBox
https://pyside.github.io/docs/pyside/PySide/QtGui/QCheckBox.html - QRadioButton
https://pyside.github.io/docs/pyside/PySide/QtGui/QRadioButton.html - QButtonGroup
https://pyside.github.io/docs/pyside/PySide/QtGui/QButtonGroup.html - QFrame
https://pyside.github.io/docs/pyside/PySide/QtGui/QFrame.html#PySide.QtGui.PySide.QtGui.QFrame - QFrame.frameStyle
https://pyside.github.io/docs/pyside/PySide/QtGui/QFrame.html#PySide.QtGui.PySide.QtGui.QFrame.frameStyle - Leo editor
http://leoeditor.com/ - IPython Qt Console aneb vylepšený pseudoterminál
https://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-ipython-a-ipython-notebook/#k06 - Vývojová prostředí ve Fedoře (4. díl)
https://mojefedora.cz/vyvojova-prostredi-ve-fedore-4-dil/ - Seriál Letní škola programovacího jazyka Logo
http://www.root.cz/serialy/letni-skola-programovaciho-jazyka-logo/ - Educational programming language
http://en.wikipedia.org/wiki/Educational_programming_language - Logo Tree Project:
http://www.elica.net/download/papers/LogoTreeProject.pdf - Hra Breakout napísaná v Tkinteri
https://www.root.cz/clanky/hra-breakout-napisana-v-tkinteri/ - Hra Snake naprogramovaná v Pythone s pomocou Tkinter
https://www.root.cz/clanky/hra-snake-naprogramovana-v-pythone-s-pomocou-tkinter/ - 24.1. turtle — Turtle graphics
https://docs.python.org/3.5/library/turtle.html#module-turtle - TkDND
http://freecode.com/projects/tkdnd - Python Tkinter Fonts
https://www.tutorialspoint.com/python/tk_fonts.htm - The Tkinter Canvas Widget
http://effbot.org/tkinterbook/canvas.htm - Ovládací prvek (Wikipedia)
https://cs.wikipedia.org/wiki/Ovl%C3%A1dac%C3%AD_prvek_%28po%C4%8D%C3%ADta%C4%8D%29 - Rezervovaná klíčová slova v Pythonu
https://docs.python.org/3/reference/lexical_analysis.html#keywords - TkDocs: Styles and Themes
http://www.tkdocs.com/tutorial/styles.html - Drawing in Tkinter
http://zetcode.com/gui/tkinter/drawing/ - Changing ttk widget text color (StackOverflow)
https://stackoverflow.com/questions/16240477/changing-ttk-widget-text-color - The Hitchhiker's Guide to Pyhton: GUI Applications
http://docs.python-guide.org/en/latest/scenarios/gui/ - 7 Top Python GUI Frameworks for 2017
http://insights.dice.com/2014/11/26/5-top-python-guis-for-2015/ - GUI Programming in Python
https://wiki.python.org/moin/GuiProgramming - Cameron Laird's personal notes on Python GUIs
http://phaseit.net/claird/comp.lang.python/python_GUI.html - Python GUI development
http://pythoncentral.io/introduction-python-gui-development/ - Graphic User Interface FAQ
https://docs.python.org/2/faq/gui.html#graphic-user-interface-faq - TkInter
https://wiki.python.org/moin/TkInter - Tkinter 8.5 reference: a GUI for Python
http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html - TkInter (Wikipedia)
https://en.wikipedia.org/wiki/Tkinter - appJar
http://appjar.info/ - appJar (Wikipedia)
https://en.wikipedia.org/wiki/AppJar - appJar na Pythonhosted
http://pythonhosted.org/appJar/ - appJar widgets
http://appjar.info/pythonWidgets/ - Stránky projektu PyGTK
http://www.pygtk.org/ - PyGTK (Wikipedia)
https://cs.wikipedia.org/wiki/PyGTK - Stránky projektu PyGObject
https://wiki.gnome.org/Projects/PyGObject - Stránky projektu Kivy
https://kivy.org/#home - Stránky projektu PyQt
https://riverbankcomputing.com/software/pyqt/intro - PyQt (Wikipedia)
https://cs.wikipedia.org/wiki/PyGTK - Stránky projektu PySide
https://wiki.qt.io/PySide - PySide (Wikipedia)
https://en.wikipedia.org/wiki/PySide - Stránky projektu Kivy
https://kivy.org/#home - Kivy (framework, Wikipedia)
https://en.wikipedia.org/wiki/Kivy_(framework) - QML Applications
http://doc.qt.io/qt-5/qmlapplications.html - KDE
https://www.kde.org/ - Qt
https://www.qt.io/ - GNOME
https://en.wikipedia.org/wiki/GNOME - Category:Software that uses PyGTK
https://en.wikipedia.org/wiki/Category:Software_that_uses_PyGTK - Category:Software that uses PyGObject
https://en.wikipedia.org/wiki/Category:Software_that_uses_PyGObject - Category:Software that uses wxWidgets
https://en.wikipedia.org/wiki/Category:Software_that_uses_wxWidgets - GIO
https://developer.gnome.org/gio/stable/ - GStreamer
https://gstreamer.freedesktop.org/ - GStreamer (Wikipedia)
https://en.wikipedia.org/wiki/GStreamer - Wax Gui Toolkit
https://wiki.python.org/moin/Wax - Python Imaging Library (PIL)
http://infohost.nmt.edu/tcc/help/pubs/pil/ - 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/