Aus Linux-Magazin 11/2011

Py Side: Programmieren mit Python und Qt

© Jakob Kamender, 123RF

Die Bibliothek Py Side kombiniert Python mit den GUI-Fähigkeiten von Qt. Unter anderem bietet sie plattformunabhängige Techniken für Nebenläufigkeit und Netzwerkprogrammierung.

Dass die umfangreiche Bibliothek Qt auf mehreren Plattformen läuft, ist nur eine ihrer Stärken. Daneben bietet das Toolkit viele weitere Funktionen, etwa einheitliche Socket-Programmierung über Betriebssysteme hinweg. Kombiniert man Qt mit einer Skriptsprache wie Python, fällt außerdem das Neukompilieren der Programme für die unterschiedlichen Plattformen weg. Das ist die Idee hinter Py Side [1], einer freien Bibliothek für die Anwendungsentwicklung.

Freie Lizenz

Vor Py Side hatte sich schon das Projekt Py Qt [2] als Ziel gesetzt, die GUI-Programmierung mit Qt unter Python zu ermöglichen. Die Py-Qt-Entwickler haben es jedoch versäumt, die Bibliothek unter einer freien Lizenz anzubieten, weshalb Nokia Py Side ins Leben gerufen hat, das unter der LGPL steht.

Qt-SDK

Auf der DELUG-DVD dieses Magazins befindet sich das Qt-SDK von Nokia samt der beschriebenen Entwicklungsumgebung Qt Creator.

Die Unterschiede für Programmierer sind unter [3] zusammengefasst. Neben dem offensichtlich unterschiedlichen Modulnamen ist vor allem das von Py Side unterstützte API relevant. Py Qt bietet nämlich zwei verschiedene APIs, wobei sich das eine an der C++-/Qt-Programmierung orientiert und daher für reine Python-Programmierer unsauber wirkt. Die Macher von Py Side haben sich daher entschieden, das API 2 von Py Qt zu unterstützen.

Erste Schritte

Um auf einem aktuellen Debian-System Py Side verwenden zu können, sind zwei Pakete zu installieren:

aptitude install python-pyside/unstable pyside-tools/unstable

Wichtig ist dabei, beide Pakete sowie deren Abhängigkeiten von Debian Unstable zu beziehen. Debian Testing oder gar Stable bieten nur alte Pakete mit weniger Funktionalität an. Wer die Software unter Ubuntu installieren möchten, kann das wie folgt von einem PPA (Personal Package Archive) tun:

sudo add-apt-repository ppa:pyside
sudo apt-get update
sudo apt-get install python-pyside pyside-tools

Das Paket »python-pyside« ist ein Metapaket, das alle Py-Side-Module installiert. Einige wichtige Module sind »QtCore« , das Hauptmodul von Qt, das jede Anwendung benötigt, »QtGui« , das die Elemente der grafischen Oberfläche wie Textfelder und Buttons zur Verfügung stellt, sowie »QtNetwork« , eine vielseitige Schnittstelle für Socketprogrammierung, HTTP und SSL. Eine umfassende Übersicht gibt es unter [4].

Aktuell bietet Py Side die Qt-Module aber nur für Python 2.x an, was Benutzern den Umstieg auf das mittlerweile als stabil deklarierte Python 3 schwer bis unmöglich macht. Die Py-Side-Entwickler kennen das Problem und es bleibt zu hoffen, dass sie die Python-3-Unterstützung bald umsetzen.

Das traditionelle “Hello World”-Anfängerprogramm für Py Side zeigt Listing 1. Wie in den Zeilen 4 und 5 zu sehen ist, müssen Py-Side-Applikationen zumindest die Pakete »QtCore« und »QtGui« importieren, welche die wichtigsten Klassen zum Aufbau von Qt-Anwendungen enthalten. »QtCore« ist für die Bearbeitung von Signalen und Slots zuständig, »QtGui« stellt Widgets für die grafische Aufbereitung der GUI-Applikation bereit.

Listing 1

hello_pyside.py

01 #!/usr/bin/python
02
03 import sys
04 from PySide import QtCore
05 from PySide import QtGui
06
07 app = QtGui.QApplication(sys.argv)
08 label = QtGui.QLabel("Hello World")
09 label.show()
10 lReturn = app.exec_()
11 sys.exit(lReturn)

Nach dem Importieren erstellt der Code ein »QApplication« -Objekt, das die Qt-Anwendung repräsentiert und in so gut wie jedem Qt-Programm vorkommt. Das erste und in diesem Fall auch einzige erstellte Widget ist ein »QLabel« zur Textausgabe. Am Ende des Listings dient die Methode »exec_()« des »QApplication« -Objekts dazu, die Qt-Hauptschleife zu betreten. Zu beachten ist hierbei der Unterstrich als Postfix des Methodennamens. Diesen haben die Py-Side-Autoren auch für Methoden wie »bin_()« , »hex_()« und »oct_()« eingeführt, um eine Verwechslung mit gleichnamigen eingebauten Python-Funktionen zu vermeiden.

Widgets

In Qt gibt es eine Vielzahl verschiedener Widgets, die umfangreiche Aufgaben von GUI-Komponenten abdecken, unter [5] findet sich eine Übersicht zu Elementen und deren Stil. Alle Widgets sind bei Py Side als Module unterhalb des Moduls »QtGui« implementiert und somit nach der Anweisung »from PySide import QtGui« verfügbar. Listing 2 zeigt ein Beispielprogramm, das sich dreier häufig eingesetzter Widgets bedient. Es nimmt eine Texteingabe entgegen und gibt sie auf Knopfdruck wieder aus.

Listing 2

widget_example.py

01 import sys
02
03 from PySide import QtCore
04 from PySide import QtGui
05
06
07 class MyDialog(QtGui.QDialog):
08 def __init__(self, parent=None):
09 super(MyDialog, self).__init__(parent)
10
11 boxlayout = QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom, self)
12
13 self.lineedit = QtGui.QLineEdit()
14 boxlayout.addWidget(self.lineedit)
15
16 self.button = QtGui.QPushButton("Abschicken")
17 self.button.clicked.connect(self.buttonClicked)
18 boxlayout.addWidget(self.button)
19
20 self.label = QtGui.QLabel()
21 boxlayout.addWidget(self.label)
22
23 self.setLayout(boxlayout)
24
25 def buttonClicked(self):
26 self.label.setText(self.lineedit.text())
27 self.lineedit.setText("")
28
29 if __name__ == "__main__":
30 app = QtGui.QApplication(sys.argv)
31 dialog = MyDialog()
32 sys.exit(dialog.exec_())

Die Klasse »MyDialog« ist von »QtDialog« abgeleitet (Zeile 7) und stellt ein GUI-Fenster zur Verfügung, das Widgets aufnimmt. Das Platzieren der Elemente erfolgt anhand eines Box-Layouts, das mit dem Parameter »QBoxLayout.TopToBottom« die Elemente zeilenweise von oben nach unten anordnet (Zeile 11). Py Side und Qt bieten natürlich viel umfangreichere Layout-Widgets an, zum Beispiel das »QGridLayout« , bei welchem der Programmierer die einzelnen GUI-Komponenten in mehreren Zeilen und Spalten anordnen kann.

Das Codebeispiel fügt dem Box-Layout nun der Reihe nach drei Elemente hinzu: Das »QLineEdit« dient zur Eingabe einer Textzeile. Für umfangreichere, mehrzeilige Eingaben käme »QTextEdit« zum Einsatz. Zur Interaktion mit dem Benutzer dient das nächste Element, ein »QPushButton« . Der Programmierer verwendet die Methode »connect()« des »clicked« -Signals von »QButton« , um die selbst gemachte Methode »self.buttonClicked« mit dem entsprechenden Ereignis zu verbinden (Zeile 17). Als dritte GUI-Komponente erzeugt das Listing ein »QLabel« zur Textausgabe, um den eingegebenen Text nach einem Klick auf den Button im Label anzuzeigen. Um die Elemente grafisch auszugeben, weist der Entwickler der Klasse »MyDialog« noch das Layout zu (Zeile 23), dem er zuvor die drei Widgets per »addWidget()« hinzugefügt hat.

Natürlich bieten Py Side und Qt noch eine Vielfalt weiterer GUI-Komponenten. Statt »QDialog« kann der Programmierer als Grundlage der grafischen Oberfläche auch ein »QMainWindow« [6] einsetzen. Es bietet neben Textfeldern, Buttons und Labels auch Platz für eine Menü- und Statusleiste sowie für Toolbars im oberen Teil des Fensters. Beispiele zur Verwendung unterschiedlichster Widgets finden sich unter [7] und [8].

GUI-Picasso

Nutzt der Programmierer prototypischer Applikationen geeignete Werkzeuge, bleibt ihm das recht mühsame Zusammenstellen der GUI-Elemente von Hand erspart. Der Entwicklerausgabe des Qt-Framework liegt die eigene Entwicklungsumgebung Qt Creator bei. Sie lässt sich von der offiziellen Projekthomepage [9] oder über den Paketmanager der Linux-Distributionen beziehen.

Obwohl er auf die Entwicklung mit der Programmiersprache C++ spezialisiert ist, unterstützt Qt Creator auch den Py-Side-Anwender bei der GUI-Gestaltung. Qt legte die Elemente der Benutzerschnittstelle in einem XML-Dateiformat in den UI-Dateien an.

Bei den Programmierarbeiten für diesen Artikel hat sich Qt Creator in den Versionen 1.3.1 und 2.2.1 bewährt. Beide beherrschen das Erstellen von UI-Dateien, die sich als Textformat in eine Versionsverwaltung einspielen lassen. Qt Creator unterstützt die gängigsten Systeme wie Git, Subversion, CVS, Bazaar sowie Mercurial und nimmt die Versionierung über Aufrufe der Kommandozeilen-Programme vor.

Wechselstube

Das folgende Programmierbeispiel enthält die wesentlichen Elemente der Anwendungsprogrammierung mit Py Side. Es handelt sich um einen Währungsumrechner, der auf die im Internet frei verfügbare XML-RPC-Schnittstelle von [http://foxrate.org] zugreift, um die aktuellen Kurse zu beziehen. Zunächst erstellt der Entwickler das GUI: Nach dem Start von Qt Creator wählt er den Menü-Eintrag »Datei | Neu … | Dateien und Klassen | Qt| Qt-Designer-Formular« , um eine UI-Datei anzulegen. Anschließend gilt es, das Mutterelement zu bestimmen. Im Falle eines neuen GUI-Projekts ist das »Main Window« .

Nach der Namensgebung sowie der Angabe des Speicherorts präsentiert sich die Oberfläche wie in Abbildung 1. Die Elemente lassen sich per Drag&Drop aus dem GUI-Klassenbereich in die zukünftige Benutzerschnittstelle ziehen. Die Klassen- und Objektübersicht verdeutlicht die Hierarchie der einzelnen Elemente. Eigenschaften wie geometrische Größen oder Masken für Eingabefelder legt der Anwender im Eigenschaftsfenster rechts unten fest.

Abbildung 1: Die grafische Oberfläche des Beispielprojekts in Qt Creator.

Abbildung 1: Die grafische Oberfläche des Beispielprojekts in Qt Creator.

Die fertigen UI-Dateien sowie der gesamte Quelltext für diesen Artikel stehen unter [10] zum Download bereit. Die Dateien »customwidget.ui« für das Hauptfenster sowie »mainwindow.ui« für ein benutzerspezifisches Widget lassen sich über den Datei-öffnen-Dialog in Qt Creator laden. Nach dem Bearbeiten überführt der Programmierer die UI-Dateien in Python-Skripte. Dazu dient das Programm »pyside-uic« aus den Py-Side-Tools:

pyside-uic customwidget.ui > customwidget.py
pyside-uic mainwindow.ui > mainwindow.py.

Listing 3 zeigt das Einbinden der generierten Klassen. Im weiteren Sinn arbeiten diese nach dem Prinzip des Factory-Pattern. Die Methode »setupUi()« der Factory-Objekte (Zeilen 5 und 9) erwartet als Parameter die zu initialisierenden Widgets. Im Falle des Hauptfensters steht hier »self« , da die Basisklasse ein »QMainWindow« ist. Für das benutzerdefinierte Widget erstellt der Code eine Instanz der Klasse »QWidget« (Zeile 7). Eine Alternative zu dieser Vorgehensweise ist das Laden von Widgets aus so genannten Ressourcendateien, wobei der Programmierer bereits fertig initialisierte Widget-Objekte erhält.

Listing 3

Einbinden der erzeugten UI-Dateien

01 from customwidget import Ui_customWidget
02 from mainwindow import Ui_MainWindow
03
04 self.ui = Ui_MainWindow()
05 self.ui.setupUi(self)
06
07 self.centralwidget = QtGui.QWidget()
08 self.customwidget = Ui_customWidget()
09 self.customwidget.setupUi(self.centralwidget)
10 self.setCentralWidget(self.centralwidget)

Signale und Slots

Qt zeichnet sich bei der Kommunikation zwischen Objekten durch eine Besonderheit aus: Sie lässt sich mit Hilfe so genannter Signale und Slots bewerkstelligen [11]. Diese Mechanismen ähneln dem traditionellen Callback-Prinzip, sind jedoch flexibler. Callbacks sind nicht Typ-sicher. Eine Methode mit exakt den gewünschten Parametern ist oft nicht vorhanden oder vorhersehbar. Der Programmierer muss bei Callbacks genau wissen, welche Methoden samt zugehörigen Methodenparamtern aufzurufen sind.

In der Implementierung des Signal-Slot-Prinzips gibt es daher eine zusätzliche Abstraktionsschicht. Der Entwickler kann exakt festlegen, welche Methode (Slot) Qt beim Auftreten eines bestimmten Signals aufruft und welche Parametertypen diese erwartet. Die gewünschte Konfiguration gibt er beim Verbinden mit der »connect()« -Methode an.

Für den zusätzlich notwendigen Code sorgen bei kompilierten Sprachen wie C++ das Qt-Buildsystem Qmake sowie der Meta-Object-Compiler. Bei Py Side passiert dies zur Laufzeit im Hintergrund. Alle Klassen, die von »QObject« erben, können Signale und Slots verarbeiten. Es ist möglich, beliebig viele Signale mit einem Slot oder beliebig viele Slots mit einem Signal zu verbinden.

Bei der neuen Syntax ergeben sich die Typen der Methodenparameter aus dem Kontext: Listing 4 zeigt die zugrunde liegende Syntax. Zeile 3 deklariert ein benutzerdefiniertes Signal. Mit Hilfe der Methode »emit()« kann der Programmierer das Signal aussenden (Zeile 6). Die Zuordnung der gewünschten Slots erfolgt im Vorfeld mit »connect()« (Zeile 16). Die dem Signal beim Aufruf übergebenen Parameter bekommen alle verbundenen Slots weitergereicht (den Wert »20« von Zeile 6 an den Methodenparameter »pValue« in Zeile 20).

Listing 4

Signale und Slots mit Py Side

01 class CSomeClass(QtCore.QObject):
02
03 sProgress = QtCore.Signal(int)
04
05 def someMethod(self):
06 sProgress.emit(20)
07 #sProgress[int].emit(20)
08
09
10 class CSomeOtherClass(QtCore.QObject):
11
12 def __init__(self):
13 self.mSome = CSomeClass()
14
15 def someOtherMethod(self):
16 self.mSome.sProgress.connect(self.onSome)
17 # QtCore.QObject.connect(self.mSome,
18 # QtCore.SIGNAL('sProgress(int)'), self.onSome)
19
20 def onSome(self, pValue):
21 print "Called with value: " + str(pValue)

Bei grafischen Benutzeroberflächen senden Aktionselemente und Widgets wie etwa »QPushButton« Signale aus, wenn der Benutzer sie anklickt. Ist das Signal mit einer benutzerdefinierten Methode, dem Slot, durch »connect()« verbunden, wird diese aufgerufen. Ein weiteres Beispiel sind Aktionen, die bei der Wahl von Menüpunkten ausgesendet werden. Diesen Anwendungsfall zeigt die erweiterte Hauptfenster-Klasse in Listing 5 (Zeilen 16 und 17). Aus der grafischen Oberfläche kann der Benutzer nun das Programm beenden oder die Autoreninformation abfragen.

Listing 5

app.py

01 ][...]
02 class Gui_Qt(QtGui.QMainWindow):
03
04 def __init__(self, parent=None):
05 super(Gui_Qt, self).__init__(parent)
06
07 self.ui = Ui_MainWindow()
08 self.ui.setupUi(self)
09
10 self.centralwidget = QtGui.QWidget()
11 self.customwidget = Ui_customWidget()
12 self.customwidget.setupUi(self.centralwidget)
13 self.setCentralWidget(self.centralwidget)
14
15 # actions
16 self.ui.actionExit.triggered.connect(self.on_actionExit_triggered)
17 self.ui.actionAbout.triggered.connect(self.on_actionAbout_triggered)
18
19 def on_actionExit_triggered(self):
20 self.close()
21
22 def on_actionAbout_triggered(self):
23 QtGui.QMessageBox.about(self, "XML-RPC Currency Calculator",
24 "<html>&copy; Rainer Poisel und Marcus Nutzinger, 2011</html>")
25 [...]

Aus Gründen der Vollständigkeit ist in Listing 4 auch die ursprüngliche Syntax angegeben (Zeilen 7, 17 und 18). Diese findet sich hauptsächlich in Applikationen, die auf älteren Versionen der Py-Side-Bibliothek aufbauen. Hierbei musste der Entwickler die äquivalenten C++-Datentypen explizit beim Verbinden von Signalen mit deren zugehörigen Slots angeben.

Neben Signalen und Slots bietet Qt auch die Möglichkeit, so genannte Events zu verarbeiten. Diese sind für den Programmierer dann von Bedeutung, wenn er Ereignisse unterhalb des Widget-Levels auswerten muss. Ein Beispiel hierfür wäre, die aktuelle Position des Mauszeigers zu erfragen. Das Qt-Framework ruft die in den Schnittstellen der einzelnen Widgets vorgesehenen Callback-Routinen auf, sobald ein Event des entsprechenden Typs aufgetreten ist. Bei der Klasse »QWidget« ist dies die Methode »mouseMoveEvent()« .

Die Beispiel-Applikation soll den aktuellen Umrechnungskurs aus dem Internet holen. Da diese Operation unter Umständen länger dauert, erarbeitet der Entwickler eine Strategie, die die grafische Oberfläche ansprechbar hält. Glücklicherweise stellen die Entwickler von Qt und Py Side geeignete Mechanismen bereit.

Nebenläufig

Neben den Python-Mechanismen zur nebenläufigen Programmierung bietet das Qt-Framework im Wesentlichen drei Möglichkeiten, um Programmcode nebenläufig auszuführen:

  • »QtCore.QThread« stellt die Basisklasse für plattformunabhängige Threads dar. Ihre Schnittstelle ähnelt der in Pythons Threading-Bibliothek enthaltenen Thread-Klasse. Die Funktionalität des Thread wird entsprechend in der »run()« -Methode implementiert.
  • »QtCore.QObject.moveToThread()« ändert die Thread-Affinität eines Objekts und seiner Kinder nach deren Erstellung.
  • »QtCore.QtConcurrent« soll eine High-Level-Programmierschnittstelle für Nebenläufigkeit bei Py Side bieten, ist aber noch Zukunftsmusik.

Listing 6 haucht dem Währungsumrechner Leben ein und implementiert die Umrechnung mittels der XML-RPC-Schnittstelle in einem eigenen Thread. Der Zugriff auf die XML-RPC Schnittstelle erfolgt mit Hilfe des mit Python mitgelieferten Moduls »xmlrpclib« . Ein dazu notwendiges Proxy-Objekt legt Zeile 8 mit der entsprechenden URL an.

Listing 6

app_qthread.py (gekürzt)

01 [...]
02 class CCurrencyThread(QtCore.QThread):
03
04 calculated = QtCore.Signal(str)
05
06 def __init__(self):
07 super(CCurrencyThread, self).__init__()
08 self.mProxy = xmlrpclib.ServerProxy("http://foxrate.org/rpc/")
09 [...]
10
11 def setArgs(self, pCurSrc, pCurDst, pVal):
12 [...]
13
14 def run(self):
15 lResult = self.mProxy.foxrate.currencyConvert(\
16 self.mCurSrc, \
17 self.mCurDst, \
18 self.mVal)
19 if lResult['message'] != '"N/A"':
20 self.calculated.emit(str(lResult['amount']))
21 else:
22 self.calculated.emit('')
23
24
25 # Create a class for our main window
26 class Gui_Qt(QtGui.QMainWindow):
27
28 def __init__(self, parent=None):
29 super(Gui_Qt, self).__init__(parent)
30
31 self.mThread = CCurrencyThread()
32 self.mMutex = QtCore.QMutex()
33
34 [...]
35 self.mThread.calculated.connect(self.on_thread_calculated,
36 QtCore.Qt.QueuedConnection)
37
38 def on_actionExit_triggered(self):
39 while self.mThread.isRunning() == True:
40 QtCore.QThread.msleep(100)
41 self.close()
42
43 def on_processButton_clicked(self):
44 if self.mMutex.tryLock() == True:
45 self.mThread.setArgs(
46 self.customwidget.sourceCurrency.text(),
47 self.customwidget.destinationCurrency.text(),
48 int(self.customwidget.value.text()))
49 self.mThread.start()
50
51 def on_thread_calculated(self, pAmount):
52 if pAmount == '':
53 self.customwidget.result.setText("")
54 self.customwidget.status.setText("<html><font \
55 color=\"red\">Fehler!</font></html>")
56 else:
57 self.customwidget.result.setText(str(pAmount))
58 self.customwidget.status.setText("OK")
59 self.mMutex.unlock()
60 [...]

Die Zeilen 35 und 36 verbinden die Signale der grafischen Elemente mit den zugehörigen Slots. Hierbei kommt der Parameter »Qt.QueuedConnection« zum Einsatz, um die Thread-Sicherheit zu gewährleisten. Klickt der Benutzer auf den Knopf »Berechnen« , versucht das Programm ein »QMutex« -Objekt zu sperren. Diese Objekte dienen zur Synchronisation mehrerer Threads. Ist bereits eine Berechnung in Gange, schlägt die Bedingung in Zeile 44 fehl. Ist das Mutex frei, startet der Thread nach seiner Initialisierung (Zeilen 45 bis 48) in Zeile 49.

Die eigentliche Umrechnung findet per XML-RPC-Proxy in den Zeilen 15 bis 18 statt. Der Code macht das Ergebnis bekannt, indem er ein »calculated« -Signal aussendet (Zeilen 20 und 22). Dies ist als Klassenmethode in Zeile 4 deklariert. Auf Seiten der grafischen Oberfläche erfolgt die Auswertung des Ergebnisses im verbundenen Slot »on_thread_calculated()« (Zeilen 51 bis 59). An dieser Stelle erfolgt auch die Freigabe des Mutex (Zeile 59), sodass der Anwender eine neue Berechnung starten kann.

In Qt ist der zweite Ansatz, um Programmcode mit der Methode »QObject.moveToThread()« [12] in einen anderen Ausführungskontext zu verschieben, plattformübergreifend einheitlich implementiert. Listing 7 zeigt das Prinzip: Nachdem das Objekt und der Thread erzeugt sind, verschiebt das Programm die Thread-Affinität des Objekts. Methodenaufrufe des Objekts erfolgen nun im zugewiesenen Thread.

Listing 7

moveToThread()

01 lObject = QtCore.QObject()
02 lThread = QtCore.QThread()
03 lObject.moveToThread(lThread)
04 lThread.start()
05 lObject.exampleMethod()

Mit »moveToThread()« ergibt sich aber das Problem, dass sich Signale in einer Warteschlange sammeln. Es gibt dann zwar keine Schwierigkeiten mit der Thread-Sicherheit, sendet der Benutzer aber das Signal zum Starten einer so verschobenen Methode mehrmals rasch hintereinander, wird die unter Umständen zeitaufwändige Methode auch mehrmals hintereinander ausgeführt.

Bei komplexen Berechnungen muss sich der Entwickler aber ohnehin Gedanken machen, wie er die grafische Oberfläche ansprechbar hält. Der Artikel “Keeping the GUI responsive” von Witold Wysota [13] beschreibt gängige Strategien.

Gutes GUI-Gefühl

Die Verwendung von Threads ist in Python aufgrund des Global Interpreter Lock (GIL) generell problematisch. Die Abhängigkeiten bei der Ausführung von Code in mehreren Threads sind für den Skriptprogrammierer oft nicht erkennbar. Soll komplexerer Programmcode daher plattformübergreifend parallel laufen, hat sich der Einsatz des im Lieferumfang von Python enthaltenen Moduls »multiprocessing« am besten bewährt. Es ist zwar nur über Umwege möglich, aus gestarteten Prozessen auf Elemente der grafischen Benutzeroberfläche zuzugreifen, meist ist das aber auch unerwünscht oder widerspricht den Vorgaben der Software-Architektur.

Online PLUS

Ein weiterführender Artikel unter der URL [https://www.linux-magazin.de/plus/2011/11] zeigt Ihnen, wie Sie Ressourcendateien sowie Qt Quick und QML für GUI-Programme verwenden.

Abbildung 2: Das Beispielprogramm ist ein einfacher Währungsumrechner, der den Kurs aus dem Internet holt – hier unter Linux.

Abbildung 2: Das Beispielprogramm ist ein einfacher Währungsumrechner, der den Kurs aus dem Internet holt – hier unter Linux.

Das Beispielprogramm läuft bei installiertem Python und Py Side auf Linux (Abbildung 2), Windows (Abbildung  3) und Mac OS X. Die Installation von Py Side auf dem Maemo-Gerät N 900 dagegen erwies sich im Test als relativ schwierig. Eine Alternative besteht darin, die Anwendung mit dem Qt Simulator auszuprobieren [14]. Ein Aufruf des Programms startet die Applikation in der gewünschten Umgebung. Abbildung 4 zeigt die Konfiguration für das N 900.

Abbildung 3: Der Währungsumrechner läuft dank Python und Py Side mit unverändertem Code auch unter Windows.

Abbildung 3: Der Währungsumrechner läuft dank Python und Py Side mit unverändertem Code auch unter Windows.

Abbildung 4: Der Einsatz der Anwendung auf Mobilgeräten lässt sich mit Qt Simulator ohne Installationsaufwand testen.

Abbildung 4: Der Einsatz der Anwendung auf Mobilgeräten lässt sich mit Qt Simulator ohne Installationsaufwand testen.

Ausblick

Py Side bietet im aktuellen Entwicklungsstadium einen beachtlichen Funktionsumfang. In der Verwendung für Forschungs- und Entwicklungsprojekte hat es sich als geradezu ideal herausgestellt. Nicht nur Mockups, sondern auch Prototypen mit Programmlogik lassen sich im Handumdrehen umsetzen. Die Plattformunabhängigkeit des Qt-Framework sowie die umfangreiche Standardausstattung von Python bilden hier genau das passende Gespann.

Dass der Hersteller Nokia an der Verbreitung von Py Side interessiert ist, zeigt die konsequente Umsetzung der Qt-Programmierbeispiele in die Programmiersprache Python. Wer die Beispiele von der Projektseite [15] herunterlädt, wird reichlich belohnt. Dieser Code deckt mittlerweile fast alle Teilbereiche ab, die das Qt-Framework umfasst.

Die nahe Zukunft birgt allerdings auch große Herausforderungen: Denn einer Pressemeldung des Kernentwicklerteams [16] zufolge stellt Nokia die Förderung für das Py-Side-Projekt mit Ende des Jahres 2011 ein. Auf der Mailingliste wird das Thema ausgiebig erörtert. Dabei sind Orte für die notwendigen Treffen sowie Planungen der Ressourcen genauso Diskussionsthema wie die zukünftige Leitung des Projekts.

Einen großen Einfluss auf den weiteren Verlauf wird der Umgang des Herstellers mit dem gesamten Qt-Framework haben. Branchenkenner haben unterschiedliche Zukunftszenarien für Nokia ausgemalt. Da scheint Qt auch in Zukunft eine wesentliche Rolle einzunehmen.

Der Autor

Marcus Nutzinger arbeitet als Entwickler bei Theobroma Systems in Wien. Er programmiert in C und Python einerseits Kerneltreiber, andererseits Dienste und Anwendungen. Rainer Poisel ist wissenschaftlicher Mitarbeiter am Institut für IT-Sicherheitsforschung an der Fachhochschule St. Pölten in Österreich. Dort forscht er in der IT-Forensik und lehrt im Studiengang IT-Security.

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben