© Liashko/Shutterstock.com
Einfache GUIs mit Python und Qt

Außen GUI, innen hui!


Im Zeitalter der Smartphones und Tablets sind grafische Applikationen ein Muss geworden. Die Programmierung von GUIs auf der Ebene des Quelltexts ist allerdings nach wie vor aufwändig, da in klassischen statisch typisierten Programmiersprachen wie C++ relativ viel Code benötigt wird, um ein GUI zu implementieren. Doch es geht auch anders …

Ein gängiger Weg zur Implementierung ist der Einsatz von IDEs, die den benötigten Code automatisiert erzeugen. Bei diesem Vorgehen nimmt die IDE dem Entwickler viele Aufgaben ab, indem GUI-Elemente in GUI-Buildern entworfen und der entsprechende Code automatisch generiert wird. Eine Alternative kann hier die Verwendung einer Kombination einer modernen dynamisch typisierten Skriptsprache mit einem leistungsfähigen GUI-Toolkit sein. In dieser zweiteiligen Artikelserie soll gezeigt werden, wie mit Python und Qt mit wenig Code eine GUI-Anwendung realisiert werden kann. Der erste Teil der Artikelserie stellt den Anwendungsfall vor und erläutert die Implementierung der einzelnen GUI-Komponenten mit Python und Qt.

Bereitstellung von Qt-Funktionalität für Python

Um die Funktionalität der Qt-Bibliothek für die Programmierung mit Python zur Verfügung zu stellen, werden entsprechende Anbindungen (Bindings) benötigt. Es stehen hier zwei Alternativen für solche Bindings zur Verfügung:

  • PyQt: Dieses ist das zuerst entstandene Qt-Binding für Python, das von der britischen Firma Riverbank Computing entwickelt wurde.

  • PySide: Eine alternative Implementierung eines Qt-Binding für Python, das weitgehend identische Funktionalität bietet wie PyQt und dabei weitestgehende Kompatibilität zu PyQt zu wahren sucht. PySide entstand, nachdem es Nokia als damaliger Besitzer der Rechte an Qt nicht gelang, mit Riverbank zu einer Einigung zur Änderung der Lizenzierung von PyQt zu kommen [1].

PyQt gilt dabei im Allgemeinen als das ausgereiftere Binding, während an PySide die liberalere Lizenzierung geschätzt wird (Kasten: „Lizenzierung von PyQt und PySide“).

The Aim of the Game

Die Programmierung eines GUI mit Python und Qt soll anhand eines einfachen Anwendungsfalls demonstriert werden. Es soll eine Quiz-Anwendung implementiert werden, wie sie z. B. bei Messen oder Konferenzen zum Einsatz kommen kann. Ein Teilnehmer muss zunächst seine Adressdaten eingeben. Anschließend werden ihm eine Reihe von Fragen in Form von Multiple-Choice-Formularen gestellt. Nach Beendigung des Quiz werden die Ergebnisse persistiert. Zum Abschluss wird dem Teilnehmer sein Ergebnis präsentiert.

schmidt_python_qt_1.tif_fmt1.jpgAbb. 1: Interface-Flow-Diagramm der Anwendung

Abbildung 1 zeigt den Aufbau der Anwendung anhand eines Interface-Flow-Diagramms (zu Interface-Flow-Diagrammen [2]). Die Kästen stellen dabei die jeweils angezeigten Bildschirmelemente dar, die Pfeile repräsentieren die möglichen Übergänge. Einfacher Text an den Pfeilen dient zur Notation von Bedingungen, in eckige Klammern eingeschlossener Text steht für die Aktivierung des Übergangs über das Betätigen der betreffenden Schaltfläche. Entsprechend haben wir es mit folgenden Oberflächenelementen zu tun:

  • Start Screen: Startbildschirm

  • Registration Screen: Anmeldedialog, Formular für die Eingabe der persönlichen Daten

  • Question Screen: Dialog für die Darstellung einer Quizfrage als Multiple-Choice-Auswahl

  • Confirm Quit Dialog: Bestätigungsdialog für den Fall, dass „Abbrechen“ betätigt wird

  • Result Screen: Präsentierung des Ergebnisses des Quiz

Sollen die folgenden Beispiele am Rechner nachvollzogen werden, müssen ggf. vorher Python, Qt, PySide und lxml mit dem entsprechenden Python Binding installiert werden, näheres dazu im Kasten „Installation von Python, Qt, PyQt, PySide und lxml“.

Aller Anfang ist schwer – Der Startbildschirm

Der Startbildschirm ist der Teil der Anwendung, mit dem der Teilnehmer als Erstes in Berührung kommt. Bei einer Messe oder einer ähnlichen Veranstaltung müssen potenzielle Teilnehmer unter Umständen durch den Startbildschirm angelockt und dazu verführt werden, an dem Quiz teilzunehmen. Einerseits ist der Startbildschirm also über eine relativ lange Zeit zu sehen (nämlich in den Pausen zwischen den jeweiligen Quizläufen), andererseits ist die Gestaltung sehr wichtig, um das Quiz attraktiv zu machen. Natürlich könnte dieser Startbildschirm auch mit den „Bordmitteln“ von Qt gestaltet werden. Allerdings finden sich wahrscheinlich deutlich mehr Designer im Webbereich, die es gewohnt sind, ihre Oberflächen in HTML und CSS zu erzeugen. Es liegt also nahe, für die Darstellung des Startbildschirms ebenfalls diese Technologien zu nutzen, d. h. das entsprechende Bild mit den Techniken des Webdesigns entwickeln zu lassen. Eine entsprechende Implementierung hat darüber hinaus den Vorteil, dass Webdesigner meist seit Jahren darin geübt sind, Seiten so zu entwerfen, dass sie auch auf verschiedenen Ausgabegeräten vom Widescreen-Monitor bis zu Tablet und Smartphone benutzbar und ansehnlich sind. Der Startbildschirm soll daher wie folgt implementiert werden:

  • Es soll eine HTML-Seite angezeigt werden.

  • Er sollte im Vollbildmodus laufen, möglichst gut sichtbar sein und gleichzeitig den Desktop verdecken.

  • Da das grafische Design des Startbildschirms am aufwändigsten ist, sollte der Startbildschirm als Hintergrund der Applikation dienen und entsprechend dauerhaft sichtbar sein.

  • Es sollen Steuerelemente benutzt werden, mit denen das Quiz gestartet oder beendet werden kann.

Wir gehen die Implementierung für den Startbildschirm jetzt Schritt für Schritt durch. Der Inhalt wird in einer Datei startscreen.py abgelegt:

#!/usr/bin/env python # -*- coding: latin-1 -*- # file startscreen.py from PySide import QtGui, QtWebKit

Die erste Zeile besteht aus dem so genannten Shebang. Es erlaubt unter unixoiden Betriebssystemen, dass das Skript direkt mit dem hier spezifizierten Interpreter (python) ausgeführt wird, wenn es direkt (also ohne dass explizit der Interpreter aufgerufen wird) gestartet wird.

Die nächste Zeile legt die Kodierung der Quelltextdatei fest – in diesem Fall latin-1. Wichtig ist in diesem Zusammenhang, dass der Editor, mit dem die Datei erstellt wird, das hier angegebene Encoding benutzt. Es folgt eine informelle Zeile, die nur den Namen der Quelltextdatei enthält – sie kann ggf. weggelassen werden. Anschließend werden die notwendigen Bibliotheken QtGui (für die grafischen Elemente) und QWebKit (zur Bereitstellung von Browserfunktionalität) importiert:

class QuizMain(QtGui.QMainWindow): def __init__(self, parent=None): super(QuizMain, self).__init__(parent)

Im nächsten Schritt wird eine Klasse QuizMain definiert, die von der Klasse QtGui.QMainWindow erbt. Letztere wird in Qt benutzt, um das Hauptfenster einer Anwendung zu implementieren. Es folgt mit __init__() der Initializer der Klasse (das entspricht in Python weitgehend, aber nicht vollständig, dem Konstruktor in Sprachen wie C++ oder Java – der Unterschied spielt für unser Beispiel aber keine Rolle). Er empfängt einen zusätzlichen Default-Parameter parent. Das entsprechend übergebene Argument wird dabei zum Parent-Objekt der Instanz gemacht. Die Parent-Child-Beziehung zwischen Qt-Objekten dient dabei zwei Zwecken: Zum einen kann so festgestellt werden, was das so genannte Top-Level-Window ist. Das ist dasjenige Widget, bei dem das parent-Attribut den Wert „None“ hat. Normalerweise ist es das Hauptfenster der Applikation (in diesem Fall QuizMain), prinzipiell kann aber jedes Qt-Widget als Top-Level-Window benutzt werden. Ein solches Top-Level-Window ist nicht Bestandteil eines anderen Fensters, und die Verantwortung für das Schließen des Fensters liegt beim Programmierer. Andererseits definiert die Beziehung Object Ownership, d. h. welche Widgets in welchen anderen Widgets enthalten sind. In einem Dialog sind z. B. die Buttons Chil...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang