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