Hlavní navigace

Další užitečné ovládací prvky nabízené frameworkem PySide

20. 2. 2018
Doba čtení: 32 minut

Sdílet

V popisu widgetů dnes budeme pokračovat. Nejprve si popíšeme použití splashscreenu, pak probereme všechny ovládací prvky založené na obecném posuvníku. Jedná se o scrollbar, klasický posuvník a otočný prvek (dial).

Obsah

1. Další užitečné ovládací prvky poskytované frameworkem PySide

2. Využití splashscreenu u aplikací s pomalejší inicializací

3. První demonstrační příklad: zobrazení splashscreenu při spouštění aplikace

4. Druhý demonstrační příklad: využití splashscreenu ještě před inicializací a zobrazením hlavního okna aplikace

5. Třetí demonstrační příklad: automatické skrytí splashscreenu po zobrazení hlavního okna aplikace

6. Scrollbar ve funkci samostatného ovládacího prvku

7. Čtvrtý demonstrační příklad: zobrazení vertikálního scrollbaru

8. Pátý demonstrační příklad: změna orientace scrollbaru z vertikálního na horizontální

9. Události generované při práci se scrollbarem

10. Šestý demonstrační příklad: nastavení výchozí hodnoty scrollbaru

11. Sedmý demonstrační příklad: nastavení dalších parametrů scrollbaru

12. Výběr celočíselné hodnoty s využitím ovládacího prvku QSlider

13. Osmý demonstrační příklad: horizontální posuvník v hlavním okně aplikace

14. Devátý demonstrační příklad: zobrazení různých typů značek u horizontálních posuvníků

15. Desátý demonstrační příklad: svislé (vertikální) posuvníky s různým typem značek

16. Ovládací prvek QDial a způsob jeho použití

17. Zobrazení widgetu QDial na ploše hlavního okna aplikace

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

19. Odkazy na Internetu

1. Další užitečné ovládací prvky poskytované frameworkem PySide

Ve třináctém článku věnovaném tvorbě aplikací s grafickým uživatelským rozhraním založeným na frameworku PySide si popíšeme některé další užitečné ovládací prvky (widgety), které lze při tvorbě aplikací použít. Nejprve se zmíníme o možnosti zobrazení tzv. splashscreenu při spouštění aplikace a zejména ještě před inicializací a zobrazením hlavního okna. Ve druhé části článku si popíšeme tři ovládací prvky, které jsou určeny pro zadávání (celo)číselných údajů, ale nikoli přímým zápisem jednotlivých cifer (k této činnosti by ostatně dostačovalo běžné vstupní textové pole), ale interaktivně – s využitím scrollbaru, posuvníku (slideru) nebo prvku typu dial, který svým vzhledem i způsobem ovládání připomíná otočné ovládací prvky používané například v audio zařízeních (ovládání hlasitosti atd.).

2. Využití splashscreenu u aplikací s pomalejší inicializací

U mnoha rozsáhlejších aplikací s grafickým uživatelským rozhraním se setkáme s použitím tzv. splashscreenu. Jedná se o jednoduché okno (typicky bez rámečku i bez dalších dekorací), které se zobrazí ihned po spuštění aplikace, tj. tehdy, kdy ještě neproběhla úplná inicializace aplikace a kdy například ještě ani není zobrazeno hlavní okno. Splashscreen typicky obsahuje obrázek s logem aplikace, popř. se zde mohou zobrazovat i další zprávy informující uživatele o postupné inicializaci jednotlivých subsystémů aplikace (viz například sekvence spouštění GIMPu).

Obrázek 1: Logo projektu PySide, které použijeme pro splashscreen v dále uvedených demonstračních příkladech.

Splashscreen si můžeme vytvořit velmi jednoduše, a to s využitím objektu typu QSplashScreen. V nejjednodušším případě předáme tomuto objektu instanci třídy QPixmap s obrázkem, který se má ve splashscreenu zobrazit:

# splashscreen
pixmap = QtGui.QPixmap("pixmaps/pysidelogo.png")
splash = QtGui.QSplashScreen(pixmap)
splash.show()

Následně můžeme vytvořit hlavní okno aplikace, provést inicializaci všech widgetů, datových struktur atd.:

# vytvoření a zobrazení hlavního okna
window = MainWindow()

Splashscreen se může automaticky zavřít po zobrazení hlavního okna. Tohoto chování dosáhneme použitím metody QSplashScreen.finish(), které předáme referenci na okno, po jehož zobrazení se splashscreen automaticky zavře:

# zajistíme, aby se po zobrazení hlavního okna splashscreen automaticky skryl
splash.finish(window)
 
window.showMainWindow(app)

3. První demonstrační příklad: zobrazení splashscreenu při spouštění aplikace

V prvním demonstračním příkladu je ukázáno základní použití splashscreenu. Komponenta představující splashscreen je inicializována a zobrazena ještě před zobrazením hlavního okna. Ve splashscreenu je zobrazen rastrový obrázek s logem frameworku PySide, který jsme již viděli v předchozí kapitole. Ovšem vzhledem k tomu, že žádným způsobem neřešíme skrytí splashscreenu po inicializaci hlavního okna, budou nakonec obě komponenty na desktopu zobrazeny současně, což je ostatně patrné z následujícího screenshotu:

Obrázek 2: Zobrazení splashscreenu společně s hlavním oknem aplikace.

Zdrojový kód dnešního prvního demonstračního 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):
        # vytvoření widgetů vkládaných do okna
        quitButton = self.prepareQuitButton()
 
        # vytvoření správce geometrie
        layout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        layout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(layout)
 
    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
 
 
# 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):
        # self.resize(450, 450)
        self.setWindowTitle("QSplashScreen")
 
        # vložení komponenty do okna
        self.setCentralWidget(MainWindowContent())
 
    def showMainWindow(self, app):
        # zobrazení okna na obrazovce
        self.show()
 
 
def main():
    app = QtGui.QApplication(sys.argv)
 
    # splashscreen
    pixmap = QtGui.QPixmap("pixmaps/pysidelogo.png")
    splash = QtGui.QSplashScreen(pixmap)
    splash.show()
 
    # vytvoření a zobrazení hlavního okna
    window = MainWindow()
    window.showMainWindow(app)
 
    # vstup do smyčky událostí (event loop)
    app.exec_()
 
 
if __name__ == '__main__':
    main()

4. Druhý demonstrační příklad: využití splashscreenu ještě před inicializací a zobrazením hlavního okna aplikace

Ve druhém příkladu schválně pozdržíme zobrazení hlavního okna, aby bylo patrné, že se splashscreen skutečně zobrazí prakticky okamžitě. Celá věc má ale jeden háček – pokud zobrazení hlavního okna pozdržíme funkcí time.sleep(), splashscreen se nezobrazí ihned podle našeho očekávání. Je tomu tak z toho důvodu, že time.sleep() je blokující operace, takže se ani nezavolá smyčka pro správu událostí. Řešení spočívá v „rozsekání“ intervalu, v němž hlavní vlákno aplikace čeká v time.sleep(), na menší části, přičemž se vždy v každém mezičase zavolá metoda QApplication.processEvents(), která zpracování událostí zajistí.

V dalším kódu je čekání „rozsekáno“ po 100ms, takže se splashscreen zobrazí skutečně prakticky okamžitě:

# uspání hlavního vlákna aplikace na zadaný počet sekund
def sleep(app, seconds):
    print('sleeping')
 
    for i in range(0, 10*seconds):
        print(i)
        app.processEvents()
        time.sleep(1/10.0)
 
    print('waking up')

Opět se podívejme na zdrojový kód 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
 
# používáme jen pro import funkce sleep
import time
 
 
# uspání hlavního vlákna aplikace na zadaný počet sekund
def sleep(app, seconds):
    print('sleeping')
 
    for i in range(0, 10*seconds):
        print(i)
        app.processEvents()
        time.sleep(1/10.0)
 
    print('waking up')
 
 
# 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):
        # vytvoření widgetů vkládaných do okna
        quitButton = self.prepareQuitButton()
 
        # vytvoření správce geometrie
        layout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        layout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(layout)
 
    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
 
 
# 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):
        # self.resize(450, 450)
        self.setWindowTitle("QSplashScreen")
 
        # vložení komponenty do okna
        self.setCentralWidget(MainWindowContent())
 
    def showMainWindow(self, app):
        sleep(app, 2)
        # zobrazení okna na obrazovce
        self.show()
 
 
def main():
    app = QtGui.QApplication(sys.argv)
 
    # splashscreen
    pixmap = QtGui.QPixmap("pixmaps/pysidelogo.png")
    splash = QtGui.QSplashScreen(pixmap)
    splash.show()
 
    # vytvoření a zobrazení hlavního okna
    window = MainWindow()
    window.showMainWindow(app)
 
    # vstup do smyčky událostí (event loop)
    app.exec_()
 
 
if __name__ == '__main__':
    main()

5. Třetí demonstrační příklad: automatické skrytí splashscreenu po zobrazení hlavního okna aplikace

Ve třetím příkladu je zajištěno automatické skrytí splashscreenu ve chvíli, kdy je již zobrazeno hlavní okno aplikace. Skrytí je provedeno asynchronně, tj. nikoli explicitním voláním metody destroy či hide, ale nepřímo specifikací, po zobrazení jakého widgetu či kontejneru se má splashscreen skrýt:

app = QtGui.QApplication(sys.argv)
 
# splashscreen
pixmap = QtGui.QPixmap("pixmaps/pysidelogo.png")
splash = QtGui.QSplashScreen(pixmap)
splash.show()
 
# vytvoření a zobrazení hlavního okna
window = MainWindow()
window.showMainWindow(app)
 
# zajistíme, aby se po zobrazení hlavního okna splashscreen automaticky skryl
splash.finish(window)
 
# vstup do smyčky událostí (event loop)
app.exec_()

Poznámka: vyzkoušejte si, jak se projeví prohození řádku s voláním splash.finish() s řádkem obsahujícím window.showMainWindow().

Opět 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
 
# používáme jen pro import funkce sleep
import time
 
 
# uspání hlavního vlákna aplikace na zadaný počet sekund
def sleep(app, seconds):
    print('sleeping')
 
    for i in range(0, 10*seconds):
        print(i)
        app.processEvents()
        time.sleep(1/10.0)
 
    print('waking up')
 
 
# 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):
        # vytvoření widgetů vkládaných do okna
        quitButton = self.prepareQuitButton()
 
        # vytvoření správce geometrie
        layout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        layout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(layout)
 
    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
 
 
# 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):
        # self.resize(450, 450)
        self.setWindowTitle("QSplashScreen")
 
        # vložení komponenty do okna
        self.setCentralWidget(MainWindowContent())
 
    def showMainWindow(self, app):
        sleep(app, 2)
        # zobrazení okna na obrazovce
        self.show()
 
 
def main():
    app = QtGui.QApplication(sys.argv)
 
    # splashscreen
    pixmap = QtGui.QPixmap("pixmaps/pysidelogo.png")
    splash = QtGui.QSplashScreen(pixmap)
    splash.show()
 
    # vytvoření a zobrazení hlavního okna
    window = MainWindow()
    window.showMainWindow(app)
 
    # zajistíme, aby se po zobrazení hlavního okna splashscreen automaticky skryl
    splash.finish(window)
 
    # vstup do smyčky událostí (event loop)
    app.exec_()
 
 
if __name__ == '__main__':
    main()

6. Scrollbar ve funkci samostatného ovládacího prvku

Ve frameworku PySide máme k dispozici hned několik ovládacích prvků (widgetů) určených pro interaktivní zadávání celočíselných numerických údajů. Tyto údaje mohou představovat různé veličiny, například podíly barvových složek při míchání barev atd. Všechny tyto ovládací prvky jsou odvozeny od třídy QAbstractSlider. V první řadě se jedná o samostatný scrollbar, tj. scrollbar nenavázaný na žádnou další komponentu, dále pak o posuvník (slider) a PySide programátorům dokonce nabízí i otočný prvek (dial). Nejprve se věnujme klasickému scrollbaru. Ten je možné použít pro mnoho operací, například pro posun dat v jiném widgetu (například při zobrazení dokumentů), ovšem scrollbar může vystupovat i jako zcela samostatný ovládací prvek.

Vytvoření scrollbaru je snadné. Pokud vyžadujeme vertikální scrollbar, použije se konstruktor bez parametrů:

scrollbar = QtGui.QScrollBar()

Při požadavku na použití scrollbaru horizontálního se musí jeho orientace určit explicitně:

scrollbar = QtGui.QScrollBar(QtCore.Qt.Horizontal)

Při práci se scrollbarem se může generovat několik typů událostí, přičemž pravděpodobně nejčastěji budeme reagovat na událost vytvořenou ve chvíli, kdy se změní pozice posuvné části scrollbaru (té se pro větší zmatení také říká posuvník). Touto problematikou se budeme zabývat v deváté kapitole. Samozřejmě je možné programově nastavit mezní hodnoty posuvníku (implicitně 0..99) i jeho aktuální pozici v rámci vybíraných hodnot. Poslední užitečnou operací je stanovení výšky nebo délky posuvné oblasti, čehož se využívá v těch případech, kdy velikost posuvné oblasti například reprezentuje stránku dokumentu (pokud tedy uživatel pracuje se čtyřstránkovým dokumentem, měla by být velikost posuvné oblasti zhruba čtvrtinová v porovnání s celkovou délkou nebo výškou scrollbaru).

7. Čtvrtý demonstrační příklad: zobrazení vertikálního scrollbaru

V dnešním čtvrtém demonstračním příkladu je ukázán způsob vytvoření vertikálního scrollbaru. Tato orientace scrollbaru je výchozí, takže scrollbar vlastně není zapotřebí žádným způsobem konfigurovat a metoda pro vytvoření scrollbaru je tedy jen dvouřádková:

def prepareScrollbar(self):
    # vytvoření scrollbaru
    scrollbar = QtGui.QScrollBar()
 
    return scrollbar

Scrollbar umístíme do kontejneru naprosto stejným způsobem, jako jakýkoli jiný widget:

# vytvoření widgetů vkládaných do okna
scrollBar = self.prepareScrollbar()
quitButton = self.prepareQuitButton()
 
# vytvoření správce geometrie
layout = QtGui.QVBoxLayout()
 
# umístění widgetů do okna
layout.addWidget(scrollBar)
layout.addWidget(quitButton)
 
# nastavení správce geometrie a vložení všech komponent do okna
self.setLayout(layout)
 

Obrázek 3: Screenshot čtvrtého demonstračního příkladu se zobrazeným vertikálně orientovaným scrollbarem.

Podívejme se na zdrojový kód příkladu se scrollbarem:

#!/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):
        # vytvoření widgetů vkládaných do okna
        scrollBar = self.prepareScrollbar()
        quitButton = self.prepareQuitButton()
 
        # vytvoření správce geometrie
        layout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        layout.addWidget(scrollBar)
        layout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(layout)
 
    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 prepareScrollbar(self):
        # vytvoření scrollbaru
        scrollbar = QtGui.QScrollBar()
 
        return scrollbar
 
 
# 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):
        self.resize(450, 450)
        self.setWindowTitle("QScrollBar")
 
        # 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. Pátý demonstrační příklad: změna orientace scrollbaru z vertikálního na horizontální

Pátý příklad se od příkladu předchozího odlišuje pouze tím, že je scrollbar orientován horizontálně, tj. vodorovně. Jediná změna v programovém kódu spočívá v předání parametru do konstruktoru widgetu QScrollBar:

def prepareScrollbar(self):
    # vytvoření scrollbaru
    scrollbar = QtGui.QScrollBar(QtCore.Qt.Horizontal)
 
    return scrollbar

Obrázek 4: Screenshot pátého demonstračního příkladu se zobrazeným horizontálně orientovaným scrollbarem.

Opět si ukážeme úplný zdrojový kód 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):
        # vytvoření widgetů vkládaných do okna
        scrollBar = self.prepareScrollbar()
        quitButton = self.prepareQuitButton()
 
        # vytvoření správce geometrie
        layout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        layout.addWidget(scrollBar)
        layout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(layout)
 
    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 prepareScrollbar(self):
        # vytvoření scrollbaru
        scrollbar = QtGui.QScrollBar(QtCore.Qt.Horizontal)
 
        return scrollbar
 
 
# 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):
        self.resize(450, 300)
        self.setWindowTitle("QScrollBar")
 
        # 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. Události generované při práci se scrollbarem

Při manipulaci se scrollbary samozřejmě mohou vzniknout události různého typu. Popis těchto událostí nalezneme v dokumentaci ke třídě QAbstractSlider:

Událost Parametry svázané s událostí
actionTriggered action
rangeChanged min, max
sliderMoved position
sliderPressed ×
sliderReleased ×
valueChanged value

Nejčastěji je nutné reagovat na změnu pozice posuvníku scrollbaru, k čemuž slouží událost reprezentovaná signálem valueChanged. Propojení události s jejím handlerem je snadné:

def prepareScrollbar(self):
    # vytvoření scrollbaru
    scrollbar = QtGui.QScrollBar(QtCore.Qt.Horizontal)
    scrollbar.valueChanged.connect(self.onScrollBarValueChanged)
    scrollbar.setValue(50)
 
    return scrollbar

Samotnému handleru je předána nová hodnota posuvníku, ovšem vzhledem k tomu, že voláme metodu a nikoli obyčejnou funkci, nesmíme zapomenout ani na parametr self:

def onScrollBarValueChanged(self, value):
    text = "Scrollbar value: {v}".format(v=value)
    self.label.setText(text)

Obrázek 5: Nastavení výchozí hodnoty scrollbaru.

10. Šestý demonstrační příklad: nastavení výchozí hodnoty scrollbaru

V dnešním šestém demonstračním příkladu je ukázáno, jak lze naprogramovat reakci na změnu pozice posuvníku scrollbaru. Vzhledem k tomu, že v příkladu využíváme funkce prepareScrollbar() a onScrollBarValueChanged() popsané v předchozí kapitole, si zde můžeme bez dalších podrobnějších komentářů přímo ukázat kód 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):
        # vytvoření widgetů vkládaných do okna
        self.label = QtGui.QLabel("")
        scrollBar = self.prepareScrollbar()
        quitButton = self.prepareQuitButton()
 
        # vytvoření správce geometrie
        layout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        layout.addWidget(self.label)
        layout.addWidget(scrollBar)
        layout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(layout)
 
    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 prepareScrollbar(self):
        # vytvoření scrollbaru
        scrollbar = QtGui.QScrollBar(QtCore.Qt.Horizontal)
        scrollbar.valueChanged.connect(self.onScrollBarValueChanged)
        scrollbar.setValue(50)
 
        return scrollbar
 
    def onScrollBarValueChanged(self, value):
        text = "Scrollbar value: {v}".format(v=value)
        self.label.setText(text)
 
 
# 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):
        self.resize(450, 300)
        self.setWindowTitle("QScrollBar")
 
        # 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()

Obrázek 6: Scrollbar má nulovou hodnotu přesně uprostřed svého dráhy.

11. Sedmý demonstrační příklad: nastavení dalších parametrů scrollbaru

V dnešním sedmém demonstračním příkladu je ukázáno, jakým způsobem se nastavují další parametry scrollbaru. Jedná se samozřejmě především o specifikaci nejmenší a největší hodnoty, které odpovídají mezní polohy posuvníku (nezávisle na orientaci scrollbaru). Výchozí hodnoty jsou 0 a 100, ale je možné nastavit prakticky libovolné celé číslo z 32bitového rozsahu, i když je nutné říci, že v případě použití větších rozdílů mezi minimální a maximální hodnotou nebude ovládání pomocí klávesnice příliš praktické. Dále je možné nastavit výchozí krok posuvníku při ovládání z klávesnice a v neposlední řadě také krok odpovídající jedné stránce (použitelné ve chvíli, kdy se scrollbar používá pro listování nějakým dokumentem). Toto nastavení současně změní šířku posuvníku, což si sami můžete vyzkoušet změnou parametru metody QScrollBar.setPageStep():

def prepareScrollbar(self):
    # vytvoření scrollbaru
    scrollbar = QtGui.QScrollBar(QtCore.Qt.Horizontal)
    scrollbar.valueChanged.connect(self.onScrollBarValueChanged)
 
    scrollbar.setMinimum(-100)
    scrollbar.setMaximum(100)
    scrollbar.setSingleStep(1)
    scrollbar.setPageStep(10)
    scrollbar.setValue(1)
 
    return scrollbar

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):
        # vytvoření widgetů vkládaných do okna
        self.label = QtGui.QLabel("")
        scrollBar = self.prepareScrollbar()
        quitButton = self.prepareQuitButton()
 
        # vytvoření správce geometrie
        layout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        layout.addWidget(self.label)
        layout.addWidget(scrollBar)
        layout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(layout)
 
    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 prepareScrollbar(self):
        # vytvoření scrollbaru
        scrollbar = QtGui.QScrollBar(QtCore.Qt.Horizontal)
        scrollbar.valueChanged.connect(self.onScrollBarValueChanged)
 
        scrollbar.setMinimum(-100)
        scrollbar.setMaximum(100)
        scrollbar.setSingleStep(1)
        scrollbar.setPageStep(10)
        scrollbar.setValue(1)
 
        return scrollbar
 
    def onScrollBarValueChanged(self, value):
        text = "Scrollbar value: {v}".format(v=value)
        self.label.setText(text)
 
 
# 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):
        self.resize(450, 300)
        self.setWindowTitle("QScrollBar")
 
        # 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. Výběr celočíselné hodnoty s využitím ovládacího prvku QSlider

Scrollbar popsaný v předchozích kapitolách je primárně určen pro orientaci uživatele v rozsáhlejších dokumentech popř. v obrázcích atd. Sice ho je možné použít i pro přímé zadání celočíselné hodnoty, což jsme si ostatně ukázali, ale pro tuto činnost je výhodnější spíše použití posuvníku neboli widgetu typu slider. Předností posuvníku je fakt, že je u něj možné zobrazit značky představující zvolenou škálu hodnot a tak zrychlit změnu hodnot prováděnou uživatelem.

Posuvník se ve frameworku PySide vytváří prakticky stejným způsobem jako scrollbar, tj. při jeho konstrukci specifikujeme orientaci posuvníku (svislou či vodorovnou):

def prepareSlider(self):
    # vytvoření slideru
    slider = QtGui.QSlider(QtCore.Qt.Horizontal)
    slider.valueChanged.connect(self.onSliderValueChanged)

Následně můžeme posuvník umístit do libovolného kontejneru, například do hlavního okna aplikace:

# vytvoření widgetů vkládaných do okna
self.label = QtGui.QLabel("")
slider = self.prepareSlider()
quitButton = self.prepareQuitButton()
 
# vytvoření správce geometrie
layout = QtGui.QVBoxLayout()
 
# umístění widgetů do okna
layout.addWidget(self.label)
layout.addWidget(slider)
layout.addWidget(quitButton)
 
# nastavení správce geometrie a vložení všech komponent do okna
self.setLayout(layout)

Obrázek 7: Horizontální posuvník v hlavním okně aplikace.

13. Osmý demonstrační příklad: horizontální posuvník v hlavním okně aplikace

V dalším demonstračním příkladu je ukázán způsob umístění horizontálního posuvníku do hlavního okna aplikace. Hlavní části kódu jsme si již vysvětlili v předchozí kapitole, takže se jen podívejme na úplný zdrojový kód 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):
        # vytvoření widgetů vkládaných do okna
        self.label = QtGui.QLabel("")
        slider = self.prepareSlider()
        quitButton = self.prepareQuitButton()
 
        # vytvoření správce geometrie
        layout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        layout.addWidget(self.label)
        layout.addWidget(slider)
        layout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(layout)
 
    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 prepareSlider(self):
        # vytvoření slideru
        slider = QtGui.QSlider(QtCore.Qt.Horizontal)
        slider.valueChanged.connect(self.onSliderValueChanged)
 
        return slider
 
    def onSliderValueChanged(self, value):
        text = "Slider value: {v}".format(v=value)
        self.label.setText(text)
 
 
# 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):
        self.resize(450, 300)
        self.setWindowTitle("QSlider")
 
        # 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. Devátý demonstrační příklad: zobrazení různých typů značek u horizontálních posuvníků

Posuvníky se od klasických scrollbarů odlišují především tím, že je u nich možné zobrazit (osové) značky. Ty lze umístit na libovolnou stranu posuvníku, popř. na obě strany. Pro nastavení stylů značek se používá metoda QSlider.setTickPosition(), které se předá jedna z konstant:

  • QtGui.QSlider.NoTicks
  • QtGui.QSlider.TicksBothSides
  • QtGui.QSlider.TicksAbove
  • QtGui.QSlider.TicksBelow
  • QtGui.QSlider.TicksLeft
  • QtGui.QSlider.TicksRight

Všechny kombinace můžete vidět na dalším screenshotu:

Obrázek 8: Horizontální posuvníky s různými kombinacemi značek.

Opět se podívejme na zdrojový kód příkladu, po jehož spuštění se zobrazí různé typy značek u posuvníků:

#!/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):
        # vytvoření widgetů vkládaných do okna
        quitButton = self.prepareQuitButton()
 
        # vytvoření správce geometrie
        layout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
 
        tickPositions = (
            QtGui.QSlider.NoTicks,
            QtGui.QSlider.TicksBothSides,
            QtGui.QSlider.TicksAbove,
            QtGui.QSlider.TicksBelow,
            QtGui.QSlider.TicksLeft,
            QtGui.QSlider.TicksRight
        )
 
        for tickPosition in tickPositions:
            layout.addWidget(QtGui.QLabel(str(tickPosition)))
            layout.addWidget(self.prepareSlider(tickPosition))
 
        layout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(layout)
 
    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 prepareSlider(self, tickPosition):
        # vytvoření slideru
        slider = QtGui.QSlider(QtCore.Qt.Horizontal)
        slider.setTickInterval(4)
        slider.setValue(1)
        slider.setTickPosition(tickPosition)
 
        return slider
 
 
# 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):
        self.resize(450, 450)
        self.setWindowTitle("QSlider")
 
        # 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. Desátý demonstrační příklad: svislé (vertikální) posuvníky s různým typem značek

Nepatrnou úpravou předchozího příkladu je možné zabezpečit zobrazení vertikálních posuvníků s různými typy značek:

tickPositions = (
    QtGui.QSlider.NoTicks,
    QtGui.QSlider.TicksBothSides,
    QtGui.QSlider.TicksAbove,
    QtGui.QSlider.TicksBelow,
    QtGui.QSlider.TicksLeft,
    QtGui.QSlider.TicksRight
)
 
for tickPosition in tickPositions:
    subLayout.addWidget(self.prepareSlider(tickPosition))

Metoda pro vytvoření posuvníku vypadá takto:

def prepareSlider(self, tickPosition):
    # vytvoření slideru
    slider = QtGui.QSlider(QtCore.Qt.Vertical)
    slider.setTickInterval(4)
    slider.setValue(1)
    slider.setTickPosition(tickPosition)
 
    return slider

Obrázek 9: Vertikální posuvníky s různými kombinacemi značek.

Zdrojový kód dnešního desátého demonstračního příkladu vypadá takto:

#!/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):
        # vytvoření widgetů vkládaných do okna
        quitButton = self.prepareQuitButton()
 
        # vytvoření prvního správce geometrie
        topLayout = QtGui.QVBoxLayout()
 
        # vytvoření druhého správce geometrie
        subLayout = QtGui.QHBoxLayout()
 
        # umístění widgetů do okna
 
        tickPositions = (
            QtGui.QSlider.NoTicks,
            QtGui.QSlider.TicksBothSides,
            QtGui.QSlider.TicksAbove,
            QtGui.QSlider.TicksBelow,
            QtGui.QSlider.TicksLeft,
            QtGui.QSlider.TicksRight
        )
 
        for tickPosition in tickPositions:
            subLayout.addWidget(self.prepareSlider(tickPosition))
 
        topLayout.addLayout(subLayout)
        topLayout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(topLayout)
 
    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 prepareSlider(self, tickPosition):
        # vytvoření slideru
        slider = QtGui.QSlider(QtCore.Qt.Vertical)
        slider.setTickInterval(4)
        slider.setValue(1)
        slider.setTickPosition(tickPosition)
 
        return slider
 
 
# 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):
        self.resize(450, 300)
        self.setWindowTitle("QSlider")
 
        # 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. Ovládací prvek QDial a způsob jeho použití

Od třídy QAbstractSlider je odvozen i další ovládací prvek nazvaný příhodně QDial. Skutečně se jedná o prvek, který se podobá potenciometru či laditelnému kondenzátoru na rádiích (v dnešních audio zařízeních ovšem i otočné prvky mívají díky použití inkrementálního snímače digitální výstup). Vlastnosti QDialu se podobají klasickému slideru, samozřejmě až na odlišný vzhled. I způsob vytvoření popř. registrace handleru událostí je shodný:

def prepareDial(self):
    # vytvoření widget
    dial = QtGui.QDial()
    dial.valueChanged.connect(self.onDialValueChanged)
 
    return dial

Obrázek 10: Otočný ovládací prvek QDial.

root_podpora

17. Zobrazení widgetu QDial na ploše hlavního okna aplikace

Podívejme se nyní na způsob použití otočného ovládacího prvku. Ze zdrojového kódu je patrné, že se tento widget používá prakticky stejně, jako klasický posuvník, samozřejmě až na vizuální rozdíly. Otočný prvek sice v okně zabírá mnohem více místa, ovšem pro některé účely a pro některé typy aplikací to nemusí být kritické (například u hudebních aplikací je použití otočného prvku mnohem přirozenější):

#!/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):
        # vytvoření widgetů vkládaných do okna
        self.label = QtGui.QLabel("")
        dial = self.prepareDial()
        quitButton = self.prepareQuitButton()
 
        # vytvoření správce geometrie
        layout = QtGui.QVBoxLayout()
 
        # umístění widgetů do okna
        layout.addWidget(self.label)
        layout.addWidget(dial)
        layout.addWidget(quitButton)
 
        # nastavení správce geometrie a vložení všech komponent do okna
        self.setLayout(layout)
 
    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 prepareDial(self):
        # vytvoření widget
        dial = QtGui.QDial()
        dial.valueChanged.connect(self.onDialValueChanged)
 
        return dial
 
    def onDialValueChanged(self, value):
        text = "Dial value: {v}".format(v=value)
        self.label.setText(text)
 
 
# 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):
        self.resize(450, 450)
        self.setWindowTitle("QDial")
 
        # 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 jedenácti 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:

19. 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. QMessageBox
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QMes­sageBox.html
  36. QListWidget
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QLis­tWidget.html
  37. Signals & Slots
    http://doc.qt.io/qt-4.8/signalsandslots.html
  38. Signals and Slots in PySide
    http://wiki.qt.io/Signals_an­d_Slots_in_PySide
  39. Intro to PySide/PyQt: Basic Widgets and Hello, World!
    http://www.pythoncentral.io/intro-to-pysidepyqt-basic-widgets-and-hello-world/
  40. QLineEdit
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QLi­neEdit.html
  41. QTextEdit
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QTex­tEdit.html
  42. QValidator
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QVa­lidator.html
  43. QIntValidator
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QIn­tValidator.html
  44. QRegExpValidator
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QRe­gExpValidator.html
  45. QWidget
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QWid­get.html
  46. QMainWindow
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QMa­inWindow.html
  47. QLabel
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QLa­bel.html
  48. QAbstractButton
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QAb­stractButton.html
  49. QCheckBox
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QChec­kBox.html
  50. QRadioButton
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QRa­dioButton.html
  51. QButtonGroup
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QBut­tonGroup.html
  52. QFrame
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QFra­me.html#PySide.QtGui.PySi­de.QtGui.QFrame
  53. QFrame.frameStyle
    https://pyside.github.io/doc­s/pyside/PySide/QtGui/QFra­me.html#PySide.QtGui.PySi­de.QtGui.QFrame.frameStyle
  54. Leo editor
    http://leoeditor.com/
  55. IPython Qt Console aneb vylepšený pseudoterminál
    https://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-ipython-a-ipython-notebook/#k06
  56. Vývojová prostředí ve Fedoře (4. díl)
    https://mojefedora.cz/vyvojova-prostredi-ve-fedore-4-dil/
  57. Seriál Letní škola programovacího jazyka Logo
    http://www.root.cz/serialy/letni-skola-programovaciho-jazyka-logo/
  58. Educational programming language
    http://en.wikipedia.org/wi­ki/Educational_programmin­g_language
  59. Logo Tree Project:
    http://www.elica.net/downlo­ad/papers/LogoTreeProject­.pdf
  60. Hra Breakout napísaná v Tkinteri
    https://www.root.cz/clanky/hra-breakout-napisana-v-tkinteri/
  61. Hra Snake naprogramovaná v Pythone s pomocou Tkinter
    https://www.root.cz/clanky/hra-snake-naprogramovana-v-pythone-s-pomocou-tkinter/
  62. 24.1. turtle — Turtle graphics
    https://docs.python.org/3­.5/library/turtle.html#mo­dule-turtle
  63. TkDND
    http://freecode.com/projects/tkdnd
  64. Python Tkinter Fonts
    https://www.tutorialspoin­t.com/python/tk_fonts.htm
  65. The Tkinter Canvas Widget
    http://effbot.org/tkinter­book/canvas.htm
  66. Ovládací prvek (Wikipedia)
    https://cs.wikipedia.org/wi­ki/Ovl%C3%A1dac%C3%AD_prvek_­%28po%C4%8D%C3%ADta%C4%8D%29
  67. Rezervovaná klíčová slova v Pythonu
    https://docs.python.org/3/re­ference/lexical_analysis.html#ke­ywords
  68. TkDocs: Styles and Themes
    http://www.tkdocs.com/tuto­rial/styles.html
  69. Drawing in Tkinter
    http://zetcode.com/gui/tkin­ter/drawing/
  70. Changing ttk widget text color (StackOverflow)
    https://stackoverflow.com/qu­estions/16240477/changing-ttk-widget-text-color
  71. The Hitchhiker's Guide to Pyhton: GUI Applications
    http://docs.python-guide.org/en/latest/scenarios/gui/
  72. 7 Top Python GUI Frameworks for 2017
    http://insights.dice.com/2014/11/26/5-top-python-guis-for-2015/
  73. GUI Programming in Python
    https://wiki.python.org/mo­in/GuiProgramming
  74. Cameron Laird's personal notes on Python GUIs
    http://phaseit.net/claird/com­p.lang.python/python_GUI.html
  75. Python GUI development
    http://pythoncentral.io/introduction-python-gui-development/
  76. Graphic User Interface FAQ
    https://docs.python.org/2/faq/gu­i.html#graphic-user-interface-faq
  77. TkInter
    https://wiki.python.org/moin/TkInter
  78. Tkinter 8.5 reference: a GUI for Python
    http://infohost.nmt.edu/tcc/hel­p/pubs/tkinter/web/index.html
  79. TkInter (Wikipedia)
    https://en.wikipedia.org/wiki/Tkinter
  80. appJar
    http://appjar.info/
  81. appJar (Wikipedia)
    https://en.wikipedia.org/wiki/AppJar
  82. appJar na Pythonhosted
    http://pythonhosted.org/appJar/
  83. appJar widgets
    http://appjar.info/pythonWidgets/
  84. Stránky projektu PyGTK
    http://www.pygtk.org/
  85. PyGTK (Wikipedia)
    https://cs.wikipedia.org/wiki/PyGTK
  86. Stránky projektu PyGObject
    https://wiki.gnome.org/Pro­jects/PyGObject
  87. Stránky projektu Kivy
    https://kivy.org/#home
  88. Stránky projektu PyQt
    https://riverbankcomputin­g.com/software/pyqt/intro
  89. PyQt (Wikipedia)
    https://cs.wikipedia.org/wiki/PyGTK
  90. Stránky projektu PySide
    https://wiki.qt.io/PySide
  91. PySide (Wikipedia)
    https://en.wikipedia.org/wiki/PySide
  92. Stránky projektu Kivy
    https://kivy.org/#home
  93. Kivy (framework, Wikipedia)
    https://en.wikipedia.org/wi­ki/Kivy_(framework)
  94. QML Applications
    http://doc.qt.io/qt-5/qmlapplications.html
  95. KDE
    https://www.kde.org/
  96. Qt
    https://www.qt.io/
  97. GNOME
    https://en.wikipedia.org/wiki/GNOME
  98. Category:Software that uses PyGTK
    https://en.wikipedia.org/wi­ki/Category:Software_that_u­ses_PyGTK
  99. Category:Software that uses PyGObject
    https://en.wikipedia.org/wi­ki/Category:Software_that_u­ses_PyGObject
  100. Category:Software that uses wxWidgets
    https://en.wikipedia.org/wi­ki/Category:Software_that_u­ses_wxWidgets
  101. GIO
    https://developer.gnome.or­g/gio/stable/
  102. GStreamer
    https://gstreamer.freedesktop.org/
  103. GStreamer (Wikipedia)
    https://en.wikipedia.org/wi­ki/GStreamer
  104. Wax Gui Toolkit
    https://wiki.python.org/moin/Wax
  105. Python Imaging Library (PIL)
    http://infohost.nmt.edu/tcc/hel­p/pubs/pil/
  106. 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ý?