Open Source im professionellen Einsatz

Programmieren mit Py Side, Ressourcendateien, Qt Quick und QML

Ressourcendateien, Qt Quick und QML

,

Dieser Beitrag ergänzt den Artikel "Starkes Gespann - Py Side: Programmieren mit Python und Qt" aus dem Linux-Magazin 11/11. Hier erfahren Entwickler, wie sie Ressourcendateien sowie Qt Quick und QML für GUI-Anwendungen einsetzen.

Ressourcendateien stellen eine alternative Möglichkeit dar, Elemente der grafischen Benutzeroberfläche wie UI-Dateien und Icons zu verwalten. Seit Version 1.0.6 von Py Side können Anwendungen derartige Dateien problemlos zur Laufzeit laden. Der Vorteil bei der Verwaltung der mit Qt Creator erstellten GUI-Ressourcen auf diese Weise liegt darin, dass ein Überführen in Python-Code in einem Ruck erfolgt. Daneben befinden sich die Ressourcen in einer einzigen Datei, was das Deployment der Applikation vereinfacht.

Das Listing "gui_resources.qrc" zeigt ein Beispiel für eine solche Ressource-Datei, die sich übrigens direkt mit dem Qt Creator zusammenklicken lässt. Das Attribut "prefix" gibt Verzeichnisse an (Zeilen 2 und 6), in denen sich Dateien ablegen lassen (Zeilen 3, 4 und 7). Das Überführen in Python-Code erfolgt auf der Kommandozeile (Listing "pyside-rcc").

Listing: "qui_resources.qrc"

<RCC>
    <qresource prefix="/forms">
        <file>customwidget.ui</file>
        <file>mainwindow.ui</file>
    </qresource>
    <qresource prefix="/images">
        <file>icon.png</file>
    </qresource>
</RCC>

Listing "pyside-rcc": Kompilieren der Ressourcedatei

 
% pyside-rcc gui_resources.qrc > gui_resources.py

Das Listing "QtUiTools" zeigt, wie der Programmierer GUI-Ressourcen mit Hilfe von "QUiLoader" aus der Ressourcendatei lädt (Zeilen 5 bis 7). Pfade innerhalb dieser Dateien beginnen prinzipiell mit einem Doppelpunkt. Die Ressourcendatei wird per Python-Import (Zeile 1) der zuvor generierten Python-Datei bekanntgegeben. Entgegen der mit "pyside-uic" kompilierten Dateien sind aus Ressourcen geladene Widgets sofort verfügbar, wie deren Verwendung in den Zeilen 9 bis 10 zeigt.

Listing "QtUiTools": GUI-Komponenten aus Ressourcedateien laden

 
import gui_resources
 
lLoader = QtUiTools.QUiLoader()
 
self.mUi = lLoader.load(":/forms/mainwindow.ui")
self.customwidget = lLoader.load(":/forms/customwidget.ui")
self.mIcon = QtGui.QIcon(":/images/icon.png")
 
self.mUi.setWindowIcon(self.mIcon)
self.mUi.setCentralWidget(self.customwidget)

Qt Quick und QML

Nokia hat Qt Quick und QML konzipiert, um ansprechende Benutzerschnittstellen für moderne Geräte zu schaffen. Die grundlegende Problematik bei der Entwicklung grafischer Oberflächen liegt - zumindest laut Qt-Dokumentation - in den Kompetenzen der einzelnen Beteiligten: Während Programmierer gut mit der Logik umgehen können, fehlt es ihnen am Händchen für ansprechendes Design. Genau umgekehrt stellt sich diese Situation für die Designer grafischer Elemente dar.

Darum verfolgt Qt Quick den Ansatz, die Elemente der grafischen Oberfläche mit der deklarativen Sprache QML zu beschreiben. Einerseits wird dadurch eine explizitere Trennung der Programmlogik von der Darstellung erreicht, andererseits soll Qt den Entwicklern und Designern von Haus aus viele verschiedene Gestaltungsstile und Animationsmöglichkeiten zur Verfügung stellen. Damit werden jene Anforderungen, die den meisten Anwendungen gemein sind, durch eine performante, parametrierbare Implementierung erfüllt.

Listing "qml_test.py": Die Programmlogik des Qt-Quick-Beispiels

 
#!/usr/bin/python
 
import sys
from PySide import QtCore, QtGui, QtDeclarative
 
 
class RotationAngle(QtCore.QObject):
    def __init__(self):
        super(RotationAngle, self).__init__()
        self.mAngle = 0
 
    @QtCore.Slot(result=int)
    def val(self):
        self.mAngle += (45)
        return self.mAngle
 
if __name__ == '__main__':
    lApp = QtGui.QApplication(sys.argv)
    lView = QtDeclarative.QDeclarativeView()
    lRotationAngle = RotationAngle()
    lContext = lView.rootContext()
    lContext.setContextProperty("rotationAngle", lRotationAngle)
    lView.setSource(QtCore.QUrl('view.qml'))
    lView.show()
    sys.exit(lApp.exec_())

Das Listing "qml_test.py" verdeutlicht das Prinzip. Die Initialisierung der Applikation erfolgt unverändert in Zeile 18. Die grafische Oberfläche (Zeile 19) ist diesmal eine Instanz der Klasse "QDeclarativeView" aus dem Namensraum "QtDeclarative". Zuordnungen an Eigenschaften der grafischen Oberfläche werden mit Hilfe der Methode "setContextProperty()" (Zeile 22) gesetzt, sobald Kontext ermittelt ist (Zeile 21). Da die Kommunikation zwischen der Programmlogik und dem View-Element im gezeigten Beispiel über Signale und Slots erfolgt, bietet sich die Kapselung in Form einer eigenen Klasse an (Zeilen 7 bis 15). Mit der Methode "setSource()" (Zeile 23) liest der Code die QML-Definition der Oberfläche ein.

Listing "view.qml": Die Beschreibung der grafischen Oberfläche mit QML

import Qt 4.7
 
Rectangle {
    id: page
 
    width: 250; height: 200
    color: "lightblue"
 
    Text {
        id: helloText
        text: "Huuiiiii!"
        anchors.horizontalCenter: page.horizontalCenter
        y: 70
        font.pointSize: 12
        font.bold: true
        Behavior on rotation {
            SpringAnimation {
                spring: .9
                damping: .02
            }  
        }  
    }  
 
    Rectangle {
        id: button
        width: 105; height: 20
        color: "darkblue"
        anchors.horizontalCenter: page.horizontalCenter
        y: 150
        MouseArea {
            id: buttonMouseArea
            objectName: "buttonMouseArea"
            anchors.fill: parent
            onClicked: {
                helloText.rotation = rotationAngle.val()
            }  
        }  
        Text {
            id: buttonText
            color: "white"
            text: "Rotate the text!"
            anchors.horizontalCenter: button.horizontalCenter
            anchors.verticalCenter: button.verticalCenter
            font.pointSize: 8;
        }  
    }  
}

Die Beschreibung der grafischen Oberfläche in "view.qml" erfolgt in mehreren Teilschritten. Die Basis stellt ein Rechteck mit der ID "page" dar (Zeile 3). Neben der Geometrie (Zeile 6) legt der Designer die Hintergrundfarbe (Zeile 7) fest. Weitere Elemente werden durch ihre Typ-Nennung hinzugefügt (Zeilen 9 und 24). Ein für die Demonstration wesentliches Element zeigen die Zeilen 16 bis 21. Sie beschreiben das Verhalten im Falle einer angeordneten Rotation. Im gezeigten Beispiel ist dies die "SpringAnimation", die an ein gedämpftes System erinnert.

Die Qt-Quick-Applikation rotiert auf Knopfdruck den angezeigten Text.

Die Qt-Quick-Applikation rotiert auf Knopfdruck den angezeigten Text.

Der Aufruf der Rotation erfolgt durch Anklicken des "button"-Rechtecks in den Zeilen 34 bis 36. An dieser Stelle treffen sich der Programmierer und der Designer: vom Objekt "helloText" wird die Eigenschaft "rotation" auf den Winkel des im Programm (Listing "qml_test.py", Zeilen 10, 11 und 22) festgelegten Slots gesetzt. Dieses Verändern der Rotationseigenschaft (Zeile 35) des "helloText"-Objekts löst wiederum die Darstellung mit Hilfe der festgelegten "SpringAnimation" aus. Die folgende Abbildung zeigt, wie die Applikation zur Laufzeit aussieht. Der Winkel des Texts wird hierbei mit jedem Klick auf die Schaltfläche sukzessive um 45 Grad erhöht. (mhu)

Diesen Artikel als PDF kaufen

Als digitales Abo

Als PDF im Abo bestellen

comments powered by Disqus

Ausgabe 07/2013

Preis € 6,40

Insecurity Bulletin

Insecurity Bulletin

Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...

Linux-Magazin auf Facebook