Programmieren für das N900 – Teil 2 Erstellen der Oberfläche mit dem Qt-Designer

Nach dem 1. Teil möchte ich nun zeigen, wie man sich für ein Programm eine Oberfläche zusammenstellt. Damit das Programm auch etwas Sinnvolles macht, habe ich mich dazu entschlossen, eine Oberfläche für ein Skript zu gestalten, die das N900 in eine WLAN-Webcam umfunktioniert und das Bild der Kamera ins lokale Netz streamt. Auf dem PC kann man dann mit dem vlc-Player das Bild betrachten.

Als Ausgangslage nehmen wir das Minimalbeispiel aus Teil 1:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Importe
import sys
from PyQt4.QtGui import QApplication, QMainWindow, QLabel, QFont

# Klasse für das Hauptfenster, abgeleitet von QMainWindow und
# unserer selbst erzeugten Klasse Ui_MainWindow mit dem QT-Designer

class Minimalbeispiel(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        font = QFont()
        font.setPointSize(100)
        label = QLabel(u"Hallo N900!")
        label.setFont(font)
        label.setGeometry(80, 120, 700, 150)
        label.show()

# Starten des Programms
if __name__=="__main__":
    # Qt-Umgebung erzeugen
    app=QApplication(sys.argv)
    # ein Objekt mit dem Namen fenster aus unserer Klasse
    # Minimalbeispiel erzeugen
    fenster=Minimalbeispiel()
    fenster.show()

    # Programmende
    sys.exit(app.exec_())

Dort hatte ich ein Label erzeugt, um einen Text anzeigen zu lassen. Bei unserem Programm brauchen wir aber noch Knöpfe, um den Stream zu starten und zu beenden, und eine Eingabemöglichkeit für die IP-Adresse und den Port. Man könnte zwar jetzt jedes einzelne Oberflächenelement im Quelltext erzeugen und selbst positionieren, jedoch ist das sehr mühsam und hat den Nachteil, dass man nicht sehr flexibel ist, wenn man im Nachhinein noch etwas ändern möchte.

Aus diesem Grund verwende ich den Qt-Designer, um die Oberfläche zu erstellen und binde diese Oberfläche dann in das Programm ein. Der Qt-Designer erzeugt ein ui-File, dass man auf zwei unterschiedliche Arten in den Quelltext integrieren kann:

  1. Man lässt sich mit Hilfe von pyuic4 eine Datei generieren, die eine Klasse unserer Oberfläche enthält und leitet unsere Klasse Minimalbeispiel von dieser ab. Diese Methode hat den Nachteil, dass man bei einer Veränderung immer wieder die Generierung anstoßen muss, was unkomfortabel ist.
  2. Man lädt die ui-Datei zur Laufzeit des Programms. Dabei wird jede Änderung im Qt-Designer beim Abspeichern automatisch beim Starten unseres Programms übernommen, da ja die aktuelle ui-Datei eingebunden wird.

Ich verwende die zweite Möglichkeit. Dazu nehmen wir zunächst aus dem Quelltext das Label und den Font raus und ersetzen sie durch

self.ui = loadUi("webcam.ui")
self.ui.show()

Unter self.ui werden wir dann innerhalb des Programms auf die Oberfläche (userinterface) zugreifen können. loadUi ist eine Klasse aus dem Modul uic, die es uns erlaubt eine Instanz unsere Oberfläche zu erzeugen.

Um diese Klasse verwenden zu können müssen wir aus dem Modul uic die Methode loadUi importieren. Die Importanweisung ergänzen wir also um

import sys
from PyQt4.QtGui import QApplication, QMainWindow
from PyQt4.uic import loadUi

Das Label und der Font aus dem Minimalbeispiel sind verschwunden, da wir ja jetzt die Oberfläche komplett in der ui-Datei verwalten. Außerdem benötigen wir im Hauptprogramm die Zeile fenster.show() nicht mehr, da das Anzeigen jetzt innerhalb der Klasse Minimalbeispiel über self.ui.show() erfolgt.

Zum Schluss benennen wir die Klasse noch in „Webcam_GUI“ um, da das Minimalbeispiel ja jetzt eine konkrete Aufgabe erfüllt und so beim Lesen des Quelltextes sofort ersichtlich wird, was diese Klasse für eine Funktion hat.

Der aktuelle Quelltext sieht also jetzt folgendermaßen aus:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Importe
import sys
# Modul uic muss importiert werden um zur Laufzeit die ui aus
# dem ui-File erzeugen zu können
# Importe
import sys
from PyQt4.QtGui import QApplication, QMainWindow
from PyQt4.uic import loadUi

# Klasse für das Hauptfenster, abgeleitet von QMainWindow
class Webcam_GUI(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        # Oberfläche abbilden:
        self.ui = loadUi("webcam.ui")
        self.ui.show()

# Starten des Programms
if __name__=="__main__":
    # Qt-Umgebung erzeugen
    app=QApplication(sys.argv)
    # ein Objekt mit dem Namen fenster aus unserer Klasse
    # Minimalbeispiel erzeugen
    fenster=Webcam_GUI()
    # Programmende
    sys.exit(app.exec_())

Hat man diese Vorbereitungen getroffen kann man sich an die Gestaltung der Oberfläche machen. Das geht sehr bequem mit dem bereits erwähnten Qt-Designer. Unter Ubuntu installiert man ihn übers Terminal mit einem beherzten

sudo apt-get install qt4-designer

Unter Windows benötigt man eine funktionierende Python-Installation und kann sich dann die passende PyQt4-Version herunterladen und installieren.

Die Bedienung des Qt-Designers ist mMn recht intuitiv, ich habe versucht das ganze innerhalb eines Screencasts zu erklären:

Innerhalb des Screencast sieht man auch die Verwendung des SDK. Damit hat man die Möglichkeit auch ohne N900 zu programmieren und alles lokal auf seinem PC zu testen. Allerdings können hardwarespezifische Dinge, wie die Kamera oder Vibration natürlich nur am Gerät selbst getestet werden.

Wie man das SDK installiert ist sehr ausführlich im Wiki von maemo.org beschrieben.

Zum Schluss benennen wir auch noch unsere Programmdatei minimal.py in webcam.py um. Unser Programm besteht also mittlerweile aus zwei Dateien, der Programmdatei webcam.py und der Oberflächendatei webcam.ui.

Damit sind wir am Ende des zweiten Teils angekommen, im dritten werde ich dann zeigen, wie man nun die Oberflächenelemente mit Leben füllt, so dass das Programm auch etwas tut sobald man z.B. auf einen Knopf drückt.

Fragen/Angregungen/Kritik bitte  in den Kommentaren.

7 Kommentare

  1. Hey,

    habe es geschafft das SDK / Zephyr und alles zu installieren, sogar das Xterm habe ich mir in die scratchbox geladen. Jedoch bekomme ich es nicht gebacken, die .py datei zum laufen zu bekommen. Habe Python2.5 und Qt4 eingeladen, aber irgendwie geht es nicht wenn ich mit python compile (versthet die Qt sachen nicht), und mit qmake mag er python nicht. Was hast du da gemacht?

    Grüße

    • Du wirfst da wohl etwas durcheinander. Bei der Entwicklung mit Python brauchst du selbst nichts manuell kompilieren. Es reicht aus, die Quelltextdatei mit
      > python name_der_datei.py
      im Terminal zu starten. Du musst natürlich vorher in der Scrachtbox irgendwo die Datei ablegen und dann innerhalb des Terminals in dieses Verzeichnis navigieren. Vielleicht postest du einfach mal die Fehlermeldung, wenn du den obigen Befehl in dem Verzeichnis ausführst, wo die Datei liegt.

      • also ich gehe ganz normal in scratchbox, sieht alles aus wie bei dir, öffne osso-term, gehe in mein verzeichnis und dann:

        > python webcam.py

        Traceback (most recent call last):
        File „webcam.py“, line 6, in
        from PyQt4.QtGui import QApplication, QMainWindow
        ImportError: No module named PyQt4.QtGui

        Python hab ich ja reingeladen, aber die PyQt Sachen fehlen halt denk ich noch. Wo find ich das denn?

        Grüße und danke dir

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.