Anmelden Registrieren

Badges

Follow Peter Bouda on Google Plus

Feeds

Neueste BlogeinträgeBlog

Wie man ein Python- oder PySide-Projekt für Maemo erstellt

Bearbeitet am Dienstag, 14. September 2010, 16:27 Uhr von pbouda

Qt-Programme lassen sich nicht nur in C++ entwicklen, mit PyQt4 und PySide gibt es zwei geeignete Python-Bibliotheken für die Entwicklung auf dem Desktop und für Maemo. Der Vorteil von Python ist dabei die Schnelligkeit: kleine Programme lassen sich (sogar mit Qt-GUI) direkt auf dem Gerät entwickeln und starten. Wird das Programm komplexer, oder will man seine Anwendung gar in die Maemo-Repositories für den Programmmanager bringen, dann muss man irgendwann ein debian-Paket aus seinem Python-Quellcode erstellen. Dieses Tutorial zeigt euch, wie ihr dabei vorgeht. Dabei wird hier Scratchbox zum Einsatz kommen, eine Alternative ist die Paketerstellung mit py2deb direkt auf dem Gerät.

Voraussetzungen

Als Voraussetzung solltet ihr das offizielle Maemo-SDK als virtuelles Image installiert und startklar haben (ihr braucht die Desktop-Version des SDKs, also die Datei “Maemo_Ubuntu_Intrepid_Desktop_SDK_Virtual_Image_Final.7z”). Das SDK ist ein virtuelles Image, ihr startet das Entwicklungsbetriebssystem am Besten mit dem VMWare Player. Wenn ihr PySide benutzen wollt müsst ihr außerdem sowohl im Scratchbox der virtuellen Maschine, also auch auf dem N900 die PySide-Pakete installieren. Da wir in diesem Tutorial auch die WebKit-Komponente von Qt bzw. PySide brauchen werden installieren wir einfach das PySide-WebKit-Paket. Diese zieht dann alle anderen PySide-Pakete als Abhängigkeiten nach. Auf dem N900 muss man root sein, dann reicht ein “apt-get install pyside-qt4-webkit”:

~ $ sudo gainroot
Root shell enabled
BusyBox v1.10.2 (Debian 3:1.10.2.legal-1osso26+0,5) built-in shell (ash)
Enter 'help' for a list of built-in commands.
/home/user # apt-get install pyside-qt4-webkit
 . . . 

In der virtuellen Maschine des SDK ist Scratchbox zu starten, dann das ARMEL-Target auszuwählen. Dann wird das Paket mit demselben “apt-get”-Befehl, aber in einer fakeroot-Umgebung installiert:

maemo@maemo-desktop:~$ /scratchbox/login 
Welcome to Scratchbox, the cross-compilation toolkit!
Use 'sb-menu' to change your compilation target.
See /scratchbox/doc/ for documentation.
[sbox-FREMANTLE_X86: ~] > sb-conf select FREMANTLE_ARMEL
Shell restarting...
[sbox-FREMANTLE_ARMEL: ~] > fakeroot apt-get install pyside-qt4-webkit
 . . .

Damit haben wir alle Voraussetzungen geschaffen, um aus einer PySide-Anwendung ein debian-Paket erstellen zu können und die Anwendung auf dem N900 starten zu können. Als Beispiel nehmen wir für unsere Anwendung ein kleines Beispiel aus meinem Blog. Die Anwendung besteht nur aus einer Quellcodedatei und öffnet eine Webseite in einem QWebView. Das gesamte Beispielprojekt könnt ihr euch hier herunterladen:

Beispielprojekt für das Tutorial als ZIP-Datei

Projektstruktur

Zunächst erstellen wir für das Projekt in einem Projektordner vier Ordner “bin”, “src”, “data”, “debian” und “src”. Der Ordner “bin” wird die Hautanwendungsdatei enthalten, der Ordner “src” sonstige Klassen und Module unserer Anwendung. Der “data”-Ordner enthält dann die Icons und Deskop-Datei, damit die Anwendung später über das Anwendungsmenü auf dem N900 gestartet werden kann. Der “debian”-Ordner enthält schliesslich alle Dateien zur Erstellung des deb-Paket zur Installation.

Im Hautpprojekteordner erstellt ihr außerdem gleich fünf Dateien, die wir auch zur Paketerstellung benötigen, mit folgenden Dateinamen:

  • CHANGES
  • LICENESE
  • Makefile
  • README
  • setup.py

Der Projektordner sollte dann folgendermaßen aussehen:

Den Ordner “data” füllen wir gleich mit zwei Icons (in den Größen 48×48 und 64×64 für das Anwendungsmenü) und einer .desktop-Datei. Für die Icons machen wir einen Unterordner pro Größe:

Die .desktop-Datei hat folgenden Inhalt:

[Desktop Entry]
Encoding=UTF-8
Version=0.1
Type=Application
Name=WebKitProcessing
Exec=/usr/bin/webkitprocessing
Icon=webkitprocessing
X-HildonDesk-ShowInToolbar=true
X-Window-Icon=webkitprocessing
X-Window-Icon-Dimmed=webkitprocessing
X-Osso-Type=application/x-executable

Falls eure Anwendung einen anderen Namen habt, dann müsst ihr nur jeweils “webkitprocessing” durch euren Namen ersetzen.

Der Quellcode der Anwendung

Meist bestehen Pythonanwendungen aus einer Hauptanwendungsdatei und weiteren Klassen und Modulen. Für uns würde hier eine Datei ausreichen, um das Projekt ausbaufähig zu machen erstellen wir aber gleich die Struktur für zusätzliche Klassen und Module. Dazu legen wir im Ordner “src” einen Unterordner “webkitprocessing” (oder einem anderen Namen) an und in diesem wiederum eine Datei mit Namen “init.py” Damit haben wir unseren eigenen Python-Namespace “webprocessing” eingerichtet, in dem wir nun weitere Klassen und Untermodule einrichten können. In unserem Fall besteht der Namespace “webprocessing” nur aus ein paar Daten für die Anwendung, die wir später auch zur Paketerstellung verwenden werden. Dazu fügen wir folgende Zeilen in “init.py” ein:

__author__    = 'Peter Bouda <p.bouda@gmx.de>'
__version__   = '0.1'
__date__      = '2010-03-20'
__copyright__ = '© 2009 Peter Bouda'
__licence__   = 'GNU General Public License, version 3 or later'
__url__       = 'http://mobileqt.de'

Im Ordner “bin” erstellen wir die Hauptanwendungsdatei, in unserem Fall heißt sie einfach “webprocessing”. Für dieses Beispiel nehmen wir einfach den Code aus dem oben genannten Blogeintrag und fügen in diese Datei ein:

#!/usr/bin/env python

import sys
from PySide import QtGui, QtWebKit, QtCore

def main():
    app = QtGui.QApplication(sys.argv)
    QtGui.QApplication.setApplicationName("Processing")
    MainWindow = QtWebKit.QWebView()
    page = MyWebPage()
    MainWindow.setPage(page)
    MainWindow.show()
    MainWindow.load(QtCore.QUrl("http://p.altcanvas.com/"))
    sys.exit(app.exec_())

class MyWebPage(QtWebKit.QWebPage):

    def __init__(self):
        QtWebKit.QWebPage.__init__(self)

    def userAgentForUrl(self, url):
        return "Mozilla/5.0 (X11; U; Linux armv7l; de-DE; rv:1.9.2a1pre) Gecko/20091127 Firefox/3.5 Maemo Browser 1.5.6 RX-51 N900"
        
main()

Die Projektstruktur sieht jetzt folgendermaßen aus:

Makefile und setup.py zum Testen, zur Installation und zur Paketerstellung

Die zentrale Datei für die Installation und zur Paketerstellung ist für Python-Anwendungen die “setup.py”. Diese Datei beschreibt die Projektdateien, die installiert werden sollen sowie die allgemeinen Metainformationen wie Author, E-Mail-Adresse, Version, usw. Diese Datei wird auch verwendet, um Quellcodepakete oder plattformspezifische Binärpakete zu erstellen. Hier werden wir die Datei aber nicht direkt aufrufen, sondern überlassen alles einem “Makefile” samt den Daten im “debian”-Ordner. Der folgende Link führt zu einer Beispiel setup.py:

Beispiel für setup.py

Ein zugehöriges “Makefile” sieht so aus:

Beispiel für Makefile

Per “make test” könnt ihr die Anwendung aus dem Projektverzeichnis starten, auf Scratchbox heißt der Befehl “make mtest”. Die sonstigen Dateien im Projektverzeichnis, “LICENSE”, “CHANGES” und “README” können erst einmal leer bleiben, oder ihr schreibt gleich eure eigenen Inhalte hinein.

Der debian-Ordner

Nun bereiten wir das Projekt für die Debian-Paketierung vor. Der Debian-Paketierer braucht etwa zwei Hände voll Dateien, die das Paket beschreiben. Diese Dateien müssen im oben erstellten “debian”-Ordner liegen. Um euch die Sache zu vereinfachen habe ich euch diese Dateien als Beispiel in ein separates Archiv gepackt:

Debian-Dateien für das mobileqt-Projekt

Die Dateien müsst ihr also aus dem Archiv in den “debian”-Ordner entpacken. Folgende Dateien müssen für jedes Projekt angepasst werden:

  • changelog: Hier könnt ihr zunächst einmal euren Projektnamen eintragen. Für spätere Versionen muss das changelog jeweils erweitert werden, und zwar über den Befehl “debchange”. Genaueres dazu gibt es hier.
  • control: Hier muss zunächst Projektname und -beschreibung angepasst werden. In der Zeile “Maintainer:” sollte euer Name und E-Mail-Adresse stehen. Wichtig sind die Felder mit den Präfixen “XSBC-” bzw. “XB-”. Um euer Paket später in das maemo-Repository zu bekommen (zur Installation über den Programmmanager), solltet ihr einen “XSBC-Bugtracker:” angeben. Die einfachste Möglichkeit ist eine Anmeldung eurer Anwendung bei “bugs.maemo.org”, so wie es hier beschrieben ist. Die Felder “XB-Maemo-Icon-26:” und “XSBC-Maemo-Display-Name:” geben ein Icon und einen Namen für den Programmmanager auf dem N900 an. Wenn ihr diese Felder leer lasst, dann wird kein Icon verwendet und es erscheint der Name, wie er in der “Package:” Zeile steht. Das Icon muss die Größe 48×48 haben. Wie ihr den Icon-Code für die “control”-Datei erstellt, könnt ihr hier nachlesen. Wenn ihr kein Icon braucht dann könnt ihr das entsprechende Feld einfach aus “control” entfernen. Dieses Icon ist wie gesagt nur für den Programmmanager. Das Anwendungsicon kommt aus dem Ordner “data/64×64”.
  • copyright: Hier müsst hier halt euren Namen und die entsprechenden Copyright-Informationen eintragen.
  • files: In dieser Datei den Projektnamen ändern, bei späteren, neuen Versionen eurer Anwendung auch die Versionsnummer.

Das war es dann auch schon für die Vorbereitung der Paketierung. Eine genauere Beschreibung der einzelnen Dateien findet ihr beispielsweise hier. Für die C++-Interessierten: im Vergleich zur Qt-Projekterstellung für Maemo mit C++ ist zum Einen die “control”-Datei anzupassen (für die PySide-Pakete nach “Depends:”), zum Anderen aber auch die “rules”-Datei. Damit der Paketierer in Scratchbox später die richtige Python-Version verwendet müssen folgende vier Zeilen hinzugefügt werden:

PATH := /usr/bin:$(PATH)
export PATH
SBOX_REDIRECT_IGNORE = /usr/bin/python
export SBOX_REDIRECT_IGNORE

Ansonsten wird euch der Paketierer die Zeile “#!/scratchbox/tools/bin/python” in eure Hauptanwendungsdatei schreiben und das Programm kann nicht mehr gestartet werden (s. hier).

Paket in Scratchbox erstellen

Nun müsst ihr den gesamten Verzeichnisbaum in die virtuelle Maschine des SDKs kopieren. Also den VMWare Player anwerfen, warten bis das SDK gebootet wurde, dann das Projekt komplett in die Maschine kopieren; das sollte per Copy&Paste funktionieren, wenn ihr die “VMWare Tools” innerhalb der virtuellen Maschine installiert habt. Dort am Besten in den Pfad “/scratchbox/users/maemo/home/maemo”, dann habt ihr aus Scratchbox gleich Zugriff darauf. Anschließend startet ihr in der virtuellen Maschine ein Terminal. In diesem Terminal startet ihr Scratchbox mit dem Befehl “/scratchbox/login”, in dieser Umgebung werden alle Maemo-Anwendungen kompiliert. Mit “sb-conf select FREMANTLE_ARMEL” wählt ihr innerhalb von Scratchbox das ARMEL-Target aus, so läuft die Anwendung dann später auf dem ARM-Prozessor des N900:

maemo@maemo-desktop:~$ /scratchbox/login 
Welcome to Scratchbox, the cross-compilation toolkit!
Use 'sb-menu' to change your compilation target.
See /scratchbox/doc/ for documentation.
[sbox-FREMANTLE_X86: ~] > sb-conf select FREMANTLE_ARMEL
Shell restarting...
[sbox-FREMANTLE_ARMEL: ~] >

Mit “cd webkitprocessing-0.1” ins Projektverzeichnis wechseln. Nun reicht ein einfaches “dpkg-buildpackage -rfakeroot” um das .deb-Paket zu erstellen:

[sbox-FREMANTLE_ARMEL: ~] > cd webkitprocessing-0.1/
[sbox-FREMANTLE_ARMEL: ~/webkitprocessing-0.1] > dpkg-buildpackage -rfakeroot  
dpkg-buildpackage: source package is webkitprocessing
dpkg-buildpackage: source version is 0.1-1
dpkg-buildpackage: source changed by Peter Bouda 
dpkg-buildpackage: host architecture armel
dpkg-buildpackage: source version without epoch 0.1-1
: Using Scratchbox tools to satisfy builddeps
 . . . hier kommen viele Zeilen . . .
dpkg-deb: ignoring 3 warnings about the control file(s)
 dpkg-genchanges
dpkg-genchanges: warning: unknown information field `Xb-Maemo-Icon-26' in input data in package's section of control info file
dpkg-genchanges: including full source code in upload
dpkg-buildpackage: full upload; Debian-native package (full source is included)

In dem Verzeichnis “über” dem Projektverzeichnis (im Beispiel: “/scratchbox/users/maemo/home/maemo”) findet ihr jetzt u.a. eine Datei mit dem Namen “webkitprocessing_0.1-1_armel.deb”. Glückwunsch: Dieses Paket kann sofort auf dem N900 installiert werden!

Installation auf dem Gerät

Zum Abschluss installieren wir das Paket per “X Terminal” und dem “dpkg”—Kommandozeilentool auf das N900. Dazu muss der root-Zugang auf dem Gerät aktiviert sein, am einfachsten geht das per rootsh—Paket. Dann einfach die im sechsten Schritt erstellt .deb-Datei auf das Gerät kopieren (per USB, Bluetooth, SSH oder auf eine Speicherkarte). Ich kopiere die Datei meist per SSH nach “/home/user/MyDocs”, dann findet man die Datei später auch einfach per Dateimanager (im Prinzip kann man das Paket auuh einfach per Klick im N900-Dateimanager installieren, für coole Hacker wie uns wäre das aber viel zu einfach). Auf dem Gerät das “X Terminal” starten und als erstes mit “sudo gainroot” zum Chef werden. Dann in das Verzeichnis wecheln, in dem die .deb-Datei liegt, und das Paket mit “dpkg -i projektname_0.1-1_armel.deb” installieren:

~ $ sudo gainroot
Root shell enabled
BusyBox v1.10.2 (Debian 3:1.10.2.legal-1osso26+0,5) built-in shell (ash)
Enter 'help' for a list of built-in commands.
/home/user # cd MyDocs
/home/user/MyDocs # dpkg -i webkitprocessing_0.1-1_armel.deb
(Reading database ... 25458 files and directories currently installed.)
Unpacking webkitprocessing (from webkitprocessing_0.1-1_armel.deb) ...
Setting up webkitprocessing (0.1-1) ...
/home/user/MyDocs #

Fertig! Jetzt könnt ihr die Anwendung über den Anwendungsbildschirm starten:

Probiert in der “Gallery” mal das Beispiel “touch” aus; ein kleines Beispiel für Toucheingaben unter Processing.js :-). Die Anwendung kann übrigens jederzeit per “dpkg -r projektname” im Terminal oder über den Programmmanager wieder vom Gerät entfernt werden.

Fazit

Python zur Anwendungsentwicklung ist gerade für Nokia keine Programmiersprache zweiter Wahl mehr. Mit PySide lassen sich schnell und einfach Anwendungen für das N900 erstellen, alle erforderlichen Schritte wurden in diesem Tutorial erklärt. Es gibt noch keine vernünftige IDE für die mobile PySide-Entwicklung, ich benutze meist einen einfachen Editor wie gedit oder (für PyQt4) Eric. Und wer seine Anwendung dann doch mit C++ und dem Qt Creator weiter entwicken möchte kann mein entsprechendes Tutorial für die ersten Schritte verwenden. Die Paketerstellung mit Scratchbox habt ihr ja hier schon gelernt…