Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.

...powered by haas.homelinux.net...

Inhaltsverzeichnis
1 Einleitung
2 Überblick über Python
3 Die Arbeit mit Python
4 Der interaktive Modus
5 Grundlegendes zu Python-Programmen
6 Kontrollstrukturen
7 Das Laufzeitmodell
8 Basisdatentypen
9 Benutzerinteraktion und Dateizugriff
10 Funktionen
11 Modularisierung
12 Objektorientierung
13 Weitere Spracheigenschaften
14 Mathematik
15 Strings
16 Datum und Zeit
17 Schnittstelle zum Betriebssystem
18 Parallele Programmierung
19 Datenspeicherung
20 Netzwerkkommunikation
21 Debugging
22 Distribution von Python-Projekten
23 Optimierung
24 Grafische Benutzeroberflächen
25 Python als serverseitige Programmiersprache im WWW mit Django
26 Anbindung an andere Programmiersprachen
27 Insiderwissen
28 Zukunft von Python
A Anhang
Stichwort

Download:
- ZIP, ca. 4,8 MB
Buch bestellen
Ihre Meinung?

Spacer
 <<   zurück
Python von Peter Kaiser, Johannes Ernesti
Das umfassende Handbuch - Aktuell zu Python 2.5
Buch: Python

Python
gebunden, mit CD
819 S., 39,90 Euro
Galileo Computing
ISBN 978-3-8362-1110-9
Pfeil 24 Grafische Benutzeroberflächen
  Pfeil 24.1 Toolkits
  Pfeil 24.2 Einführung in PyQt
    Pfeil 24.2.1 Installation
    Pfeil 24.2.2 Grundlegende Konzepte von Qt
  Pfeil 24.3 Entwicklungsprozess
    Pfeil 24.3.1 Erstellen des Dialogs
    Pfeil 24.3.2 Schreiben des Programms
  Pfeil 24.4 Signale und Slots
  Pfeil 24.5 Überblick über das Qt-Framework
  Pfeil 24.6 Zeichenfunktionalität
    Pfeil 24.6.1 Werkzeuge
    Pfeil 24.6.2 Koordinatensystem
    Pfeil 24.6.3 Einfache Formen
    Pfeil 24.6.4 Grafiken
    Pfeil 24.6.5 Text
    Pfeil 24.6.6 Eye-Candy
  Pfeil 24.7 Model-View-Architektur
    Pfeil 24.7.1 Beispielprojekt: Ein Adressbuch
    Pfeil 24.7.2 Auswählen von Einträgen
    Pfeil 24.7.3 Editieren von Einträgen
  Pfeil 24.8 Wichtige Widgets
    Pfeil 24.8.1 QCheckBox
    Pfeil 24.8.2 QComboBox
    Pfeil 24.8.3 QDateEdit
    Pfeil 24.8.4 QDateTimeEdit
    Pfeil 24.8.5 QDial
    Pfeil 24.8.6 QDialog
    Pfeil 24.8.7 QGLWidget
    Pfeil 24.8.8 QLineEdit
    Pfeil 24.8.9 QListView
    Pfeil 24.8.10 QListWidget
    Pfeil 24.8.11 QProgressBar
    Pfeil 24.8.12 QPushButton
    Pfeil 24.8.13 QRadioButton
    Pfeil 24.8.14 QScrollArea
    Pfeil 24.8.15 QSlider
    Pfeil 24.8.16 QTableView
    Pfeil 24.8.17 QTableWidget
    Pfeil 24.8.18 QTabWidget
    Pfeil 24.8.19 QTextEdit
    Pfeil 24.8.20 QTimeEdit
    Pfeil 24.8.21 QTreeView
    Pfeil 24.8.22 QTreeWidget
    Pfeil 24.8.23 QWidget


Galileo Computing - Zum Seitenanfang

24.6 Zeichenfunktionalität  Zur nächsten ÜberschriftZur vorigen Überschrift

Nachdem die praxisorientierte Einführung in die Programmierung grafischer Benutzeroberflächen mithilfe des Qt-Frameworks hinter uns liegt, möchten wir uns dem ersten Spezialgebiet von Qt zuwenden: der Zeichenfunktionalität. Wenn Sie ein eigenes Widget erstellen, also eine Klasse definieren, die von einem Steuerelement oder direkt von QWidget erbt, haben Sie die Möglichkeit, selbst beliebige Inhalte in das Widget zu zeichnen. Das ist besonders dann interessant, wenn eine Anwendung Inhalte in einem Widget anzeigen möchte, für die es im Qt-Framework keine vorgefertigte Klasse gibt. Das könnte zum Beispiel ein Diagramm oder eine spezifische Grafik sein.

Im Folgenden werden wir uns zunächst mit den Grundlagen des Zeichnens in Qt beschäftigen und danach einige einfache Formen, beispielsweise einen Kreis oder ein Rechteck, auf den Bildschirm bringen.

Die in den folgenden Unterkapiteln präsentieren Beispielklassen verstehen sich im folgenden Kontext:

from PyQt4 import QtGui 
import sys
class MeinWidget(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent)
app = QtGui.QApplication(sys.argv) widget = MeinWidget() widget.resize(150, 150) widget.show() sys.exit(app.exec_())

Dabei werden wir in den Beispielen jeweils nur die Klasse MeinWidget neu implementieren. Um aus diesen Beispielen ein tatsächlich lauffähiges PyQt-Programm zu erstellen, muss die vorgestellte Klasse in den obigen Kontext eingefügt werden. Beachten Sie, dass je nach Beispielprogramm auch noch der Namensraum QtCore eingebunden werden muss.


Galileo Computing - Zum Seitenanfang

24.6.1 Werkzeuge  Zur nächsten ÜberschriftZur vorigen Überschrift

Um innerhalb eines Widgets zeichnen zu können, muss der Eventhandler paintEvent implementiert werden. Dabei handelt es sich um eine Methode, die vom Qt-Framework immer dann aufgerufen wird, wenn das Widget teilweise oder vollständig neu gezeichnet werden muss. Das passiert beispielsweise dann, wenn das Anwendungsfenster teilweise verdeckt oder minimiert war und vom Benutzer in den Vordergrund geholt wurde. Die Methode paintEvent bekommt eine Instanz der Klasse QPaintEvent übergeben, die unter anderem den Bereich des Widgets enthält, der neu gezeichnet werden soll. [In unseren einfachen Beispielen werden wir beim Aufrufen der paintEvent-Methode stets die komplette Zeichnung neu zeichnen. Je komplexer und aufwendiger eine Zeichnung jedoch zu zeichnen ist, desto eher sollte man nur den durch die QPaintEvent-Instanz spezifizierten Bereich tatsächlich neu zeichnen. ]

Innerhalb der paintEvent-Methode muss der sogenannte Painter (dt. Maler) erzeugt werden, mit dessen Hilfe die Zeichenoperationen später durchgeführt werden können. Bei einem Painter handelt es sich um eine Instanz der Klasse QtGui.QPainter. Ein grundlegendes Widget, das das Paint-Event implementiert und einen Painter erzeugt, sieht folgendermaßen aus:

class MeinWidget(QtGui.QWidget): 
    def __init__(self, parent=None): 
        QtGui.QWidget.__init__(self, parent)
def paintEvent(event): painter = QtGui.QPainter(self)

Nach dem Erzeugen der QPainter-Instanz können mithilfe des Painters beliebige Zeichenoperationen durchgeführt werden.

Zum Zeichnen gibt es in Qt neben dem Painter zwei grundsätzliche Werkzeuge: einen Pen und einen Brush.

Als Pen (dt. Stift) wird eine Instanz der Klasse QtGui.QPen bezeichnet. Um einen Pen zu verwenden, muss dieser dem Painter – also einer QPainter-Instanz – mithilfe der Methode setPen bekannt gegeben werden. Grundsätzlich wird ein Pen zum Zeichnen von Linien, beispielsweise für Umrandungen bestimmter Figuren, verwendet. Dazu enthält ein Pen im Wesentlichen drei Informationen: die Linienfarbe, die Liniendicke und den Linienstil. Ein Pen wird folgendermaßen erzeugt:

pen = QtGui.QPen(QtGui.QColor(255,0,0))

Dem Konstruktor des Pens wird eine Instanz der Klasse QColor übergeben, um die Farbe des Pens, in diesem Fall Rot [Eine Farbangabe besteht aus drei einzelnen Werten zwischen 0 und 255. Der erste übergebene Wert spezifiziert den Rot-, der zweite den Grün- und der dritte den Blauanteil der Farbe. Nähere Informationen dazu finden Sie im Internet unter dem Stichwort »RGB«. ] , zu spezifizieren. Nachdem ein Pen erzeugt worden ist, kann seine Liniendicke bzw. der Linienstil mithilfe der Methoden setWidth und setStyle festgelegt werden:

pen.setWidth(7) 
pen.setStyle(QtCore.Qt.DashLine)

Die der Methode setWidth übergebene ganze Zahl entspricht der Liniendicke in Pixeln, die eine mit diesem Pen gezeichnete Linie später auf dem Bildschirm haben wird. Der Methode setStyle können verschiedene Konstanten übergeben werden, die jeweils einen bestimmten Linienstil vorschreiben. Eine Auswahl dieser Konstanten finden Sie in der folgenden Tabelle:


Tabelle 24.3  Linienstile eines Pens
Konstante Beschreibung
QtCore.Qt.SolidLine

Eine durchgezogene Linie. Dies ist die Standardeinstellung und braucht nicht explizit gesetzt zu werden.

QtCore.Qt.DashLine

Eine gestrichelte Linie

QtCore.Qt.DotLine

Eine gepunktete Linie

QtCore.Qt.DashDotLine

Eine Linie, die abwechselnd gestrichelt und gepunktet ist


Das zweite wichtige Werkzeug zum Zeichnen ist der sogenannte Brush (dt. Pinsel), mit dessen Hilfe Flächen gefüllt werden. Ein Brush spezifiziert, ähnlich wie ein Pen, zunächst einmal die Farbe, in der eine Fläche gefüllt werden soll. Analog zum Pen wird ein Brush folgendermaßen erzeugt:

brush = QtGui.QBrush(QtGui.QColor(0,0,255))

Auch dem Konstruktor des Brushs wird der Farbwert, in diesem Fall Blau, in Form einer QColor-Instanz übergeben. Nachdem der Brush erzeugt worden ist, kann auch hier mit der Methode setStyle ein Stil festgelegt werden. Mithilfe eines solches Stils ist es beispielsweise möglich, Flächen verschieden stark bzw. in unterschiedliche Richtungen schraffiert zu füllen. Näheres dazu erfahren Sie in der Qt-Dokumentation.

Allgemein gilt, dass Pens und Brushes selektiert werden müssen, bevor sie benutzt werden können. Dazu werden die Methoden setPen bzw. setBrush eines Painters aufgerufen und wird die jeweilige QPen- bzw. QBrush-Instanz als Parameter übergeben. Eine darauf folgende Zeichenoperation wird dann mit den ausgewählten Werkzeugen durchgeführt. Beachten Sie, dass immer nur ein Brush und ein Pen gleichzeitig selektiert sein können.


Galileo Computing - Zum Seitenanfang

24.6.2 Koordinatensystem  Zur nächsten ÜberschriftZur vorigen Überschrift

Bevor es ans Zeichnen einfacher geometrischer Formen geht, müssen wir uns Gedanken über das in Qt verwendete Koordinatensystem machen. Dieses lehnt sich an andere GUI-Toolkits an und soll durch Abbildung 24.12 veranschaulicht werden.

Abbildung 24.12  Das Koordinatensystem

Jeder Pixel innerhalb des Widgets kann mithilfe des Koordinatensystems beschrieben werden. Beachten Sie, dass der Ursprung des Koordinatensystems in der oberen linken Ecke des Widgets liegt und dass die Y-Achse, im Gegensatz zum in der Mathematik verwendeten kartesischen Koordinatensystem, nach unten zeigt. Die Einheit des Koordinatensystems ist Pixel.

Jedes Widget verfügt über ein eigenes lokales Koordinatensystem, dessen Ursprung stets relativ zur Position des Widgets in dessen oberer linken Ecke liegt. Das hat den Vorteil, dass eine Zeichnung nicht angepasst werden muss, wenn das Widget in seiner Position auf dem Bildschirm oder innerhalb eines anderen Widgets verändert wird.


Galileo Computing - Zum Seitenanfang

24.6.3 Einfache Formen  Zur nächsten ÜberschriftZur vorigen Überschrift

Das Qt-Framework bietet eine ganze Reihe von abstrakten Zeichenoperationen, die das Zeichnen einfacher geometrischer Formen, wie beispielsweise eines Rechtecks oder einer Ellipse, ermöglichen. Grundsätzlich sind Zeichenoperationen als Methoden der Klasse QPainter, also eines Painters, implementiert.

Wir beginnen damit, ein Rechteck zu zeichnen. Dazu wird die Methode drawRect eines Painters verwendet. Bevor ein Rechteck gezeichnet werden kann, sollten ein Pen für den Rand des Rechtecks und ein Brush für die Füllung erzeugt und ausgewählt werden:

class MeinWidget(QtGui.QWidget): 
    def __init__(self, parent=None): 
        QtGui.QWidget.__init__(self, parent) 
        self.pen = QtGui.QPen(QtGui.QColor(0,0,0)) 
        self.pen.setWidth(3) 
        self.brush = QtGui.QBrush(QtGui.QColor(255,255,255))
def paintEvent(self, event): painter = QtGui.QPainter(self) painter.setPen(self.pen) painter.setBrush(self.brush) painter.drawRect(10, 10, 130, 130)

Im Konstruktor der Widget-Klasse MeinWidget werden Pen und Brush angelegt, die zum Zeichnen des Rechtecks verwendet werden sollen. In diesem Fall handelt es sich um einen schwarzen Pen mit einer Stiftdicke von drei Pixeln sowie um einen weißen Brush. In der Methode paintEvent wird zunächst ein Painter erzeugt und werden die für die Zeichnung zu verwendenden Werkzeuge, also ein Brush und ein Pen, selektiert. Danach wird mittels drawRect ein Rechteck auf dem Bildschirm gemalt. Die übergebenen Parameter kennzeichnen der Reihe nach die X-Koordinate der oberen linken Ecke, die Y-Koordinate der oberen linken Ecke, die Breite des Rechtecks sowie die Höhe des Rechtecks. Alle Werte werden in Pixel angegeben. Beachten Sie, dass das Koordinatensystem, in dem das Rechteck gezeichnet wird, relativ zur Position des Widgets liegt.

Auf dem Bildschirm erscheint das Rechteck, genauer betrachtet ein Quadrat (siehe Abbildung 24.13).

Abbildung 24.13  Ein mit drawRect gezeichnetes Quadrat

Auf ganz ähnliche Weise können noch weitere Figuren gezeichnet werden, deren Form durch Angabe eines umschließenden Rechtecks beschrieben ist. So braucht beispielsweise nur der Methodenname drawRect ausgetauscht zu werden, um ein Rechteck mit runden Ecken (drawRoundRect) oder eine Ellipse (drawEllipse) zu zeichnen.

Abbildung 24.14  Ein Rechteck mit runden Ecken und eine Ellipse

Um eine dieser Figuren in ihrer Größe an das Widget anzupassen, kann die parameterlose Methode rect einer Widgetklasse verwendet werden, die die Dimensionen des Widgets als QRect-Instanz [Die Klasse QRect beschreibt ein Rechteck und verfügt unter anderem über die Methoden x, y, width und height, mit denen auf die Koordinaten der oberen linken Ecke und die Dimensionen des Rechtecks zugegriffen werden kann. Näheres zur Klasse QRect finden Sie in der Qt-Dokumentation. ] zurückgibt. Auf diese Weise ist es beispielsweise möglich, das gesamte Widget mit einer Form zu füllen.

Neben diesen drei grundlegenden Formen existiert eine Reihe weiterer Methoden zum Zeichnen spezieller Formen. Die folgende Tabelle gibt eine Übersicht über die wichtigsten dieser Methoden, die in diesem Kapitel nicht weiter besprochen werden. [Ein Polygon ist eine Fläche, die durch einen Linienzug begrenzt ist. Eine Fläche heißt konvex, wenn die Verbindungslinie zwischen je zwei Punkten in der Fläche vollständig innerhalb der Fläche verläuft. Das Gegenteil eines konvexen Polygons ist ein konkaves Polygon, das wesentlich aufwendiger darzustellen ist. ]


Tabelle 24.4  Methoden eines Painters
Methode Beschreibung
drawArc

Zeichnet einen geöffneten Bogen mit dem selektierten Pen. »Geöffnet« bedeutet in diesem Fall, dass die beiden Enden des Bogens nicht durch eine Linie miteinander verbunden sind.

drawChord

Zeichnet einen geschlossenen Bogen mit dem selektierten Pen, der mit dem selektierten Brush gefüllt wird. »Geschlossen« bedeutet, dass die beiden Enden des Bogens durch eine Linie miteinander verbunden sind.

drawConvexPolygon

Zeichnet ein konvexes Polygon mit dem selektierten Pen, das mit dem selektierten Brush gefüllt wird.

drawLine

Zeichnet eine Linie mit dem selektierten Pen.

drawLines

Zeichnet einen Linienzug mit dem selektierten Pen.

drawPie

Zeichnet mit dem selektierten Pen einen Ausschnitt einer Ellipse, der umgangssprachlich als »Tortenstück« bezeichnet wird.

drawPolygon

Zeichnet mit dem selektierten Pen ein beliebiges Polygon, das mit dem selektierten Brush gefüllt wird. Diese Methode ist allgemeiner und hat eine komplexere Schnittstelle als drawConvexPolygon.

fillRect

Zeichnet ein Rechteck ohne Rand. Dieses Rechteck wird mit dem selektierten Brush gefüllt.



Galileo Computing - Zum Seitenanfang

24.6.4 Grafiken  Zur nächsten ÜberschriftZur vorigen Überschrift

Neben dem Zeichnen der grundlegenden geometrischen Formen ermöglicht es das Qt-Framework komfortabel, Grafiken der verschiedensten Formate von der Festplatte zu laden und mithilfe eines Painters anzuzeigen.

Das Laden einer Grafik von der Festplatte hat noch nichts mit der Anzeige und damit auch nichts mit der Klasse QPainter zu tun. Dafür existiert die Klasse QImage, die eine Grafik repräsentiert und Methoden anbietet, um Grafiken diverser Formate zu laden, zu manipulieren und zu speichern. [Eine Liste aller Grafikformate, die Qt »versteht«, finden Sie in der Dokumentation der Klasse QImage. ] Das folgende Beispielprogramm lädt die Grafik buch.png und zeigt sie mithilfe der Methode drawImage des Painters an:

class MeinWidget(QtGui.QWidget): 
    def __init__(self, parent=None): 
        QtGui.QWidget.__init__(self, parent) 
        self.grafik = QtGui.QImage("buch.png") 
        self.ziel = QtCore.QRect(10, 10, 130, 130) 
        self.quelle = QtCore.QRect(0, 0, 
                                   self.grafik.width(), 
                                   self.grafik.height())
def paintEvent(self, event): painter = QtGui.QPainter(self) painter.drawImage(self.ziel, self.grafik, self.quelle)

Im Konstruktor der Widgetklasse MeinWidget wird zunächst eine Instanz der Klasse QImage erzeugt. Dem Konstruktor der QImage-Klasse wird der Dateipfad der zu ladenden Grafik übergeben.

Nachdem die Grafik geladen wurde, werden zwei Rechtecke namens self.quelle und self.ziel erzeugt. Das Rechteck self.ziel spezifiziert das Rechteck im Widget, in das die Grafik gezeichnet werden soll. Das Rechteck self.quelle spezifiziert den Ausschnitt der Grafik, der dabei gezeichnet werden soll. In diesem Fall umschließt das Quellrechteck das gesamte Bild.

Das mit diesem Code erstellte Widget sieht so aus wie in Abbildung 24.15.

Abbildung 24.15  Eine Grafik in einem Widget

Beachten Sie, dass in diesem Fall ein nicht quadratisches Bild auf eine quadratische Fläche gezeichnet und somit beim Zeichnen leicht gestreckt wird. Um dies zu vermeiden, müsste das Seitenverhältnis des Zielrechtecks an das des Quellrechtecks angepasst werden.

Abgesehen vom bloßen Laden eines Bildes bietet die Klasse QImage eine Fülle von Methoden, mit denen das geladene Bild manipuliert werden kann. Es ist nicht sinnvoll, in dieser Einführung einen vollständigen Überblick über diese Möglichkeiten zu geben. Stattdessen verweisen wir auf die ausführliche Qt-Dokumentation, in der Sie weiterführende Informationen zu QImage finden.


Galileo Computing - Zum Seitenanfang

24.6.5 Text  Zur nächsten ÜberschriftZur vorigen Überschrift

Nachdem wir sowohl geometrische Formen als auch Grafiken in ein Widget zeichnen können, fehlt noch eine mehr oder weniger große Disziplin: das Zeichnen von Text. Für viele Zeichnungen wird die Ausgabe von Text benötigt, sei es für die Beschriftungen eines Diagramms oder das Ziffernblatt einer Uhr.

Zum Zeichnen von Text in einem Widget wird die Methode drawText eines Painters verwendet. Im folgenden Beispiel wird der Text »Hallo Welt« im Widget zentriert ausgegeben:

class MeinWidget(QtGui.QWidget): 
    def __init__(self, parent=None): 
        QtGui.QWidget.__init__(self, parent) 
        self.font = QtGui.QFont("Helvetica", 16) 
        self.pen = QtGui.QPen(QtGui.QColor(0,0,255))
def paintEvent(self, event): painter = QtGui.QPainter(self) painter.setPen(self.pen) painter.setFont(self.font) painter.drawText(self.rect(), QtCore.Qt.AlignCenter, "Hallo Welt")

Im Konstruktor der Klasse MeinWidget wird zunächst eine Instanz der Klasse QFont erzeugt. Diese Klasse repräsentiert einen Font, also einen Schrifttyp in einer bestimmten Größe und mit bestimmten weiteren Eigenschaften. Zudem wird ein Pen erzeugt, der die Schriftfarbe vorgibt, in der unser Text geschrieben werden soll.

In der Methode paintEvent wird zunächst, wie gehabt, ein Painter erzeugt, und dann werden mittels setFont und setPen Font und Pen selektiert. Durch einen Aufruf der Methode drawText wird der Text gezeichnet. Die Methode bekommt ein Rechteck als ersten und eine Positionsanweisung innerhalb dieses Rechtecks als zweiten Parameter übergeben. Als dritter Parameter wird der zu schreibende Text übergeben. Zur Positionierung des Texts innerhalb des angegebenen Rechtecks können mehrere Konstanten mithilfe des binären ODERs verknüpft werden. Die wichtigsten dieser Konstanten sind in folgender Tabelle aufgelistet und kurz erläutert:


Tabelle 24.5  Konstanten zur Positionierung des Texts
Konstante Beschreibung
QtCore.Qt.AlignLeft

Richtet den Text am linken Rand des Rechtecks aus.

QtCore.Qt.AlignRight

Richtet den Text am rechten Rand des Rechtecks aus.

QtCore.Qt.AlignHCenter

Richtet den Text horizontal zentriert im Rechteck aus.

QtCore.Qt.AlignTop

Richtet den Text am oberen Rand des Rechtecks aus.

QtCore.Qt.AlignBottom

Richtet den Text am unteren Rand des Rechtecks aus.

QtCore.Qt.AlignVCenter

Richtet den Text vertikal zentriert im Rechteck aus.

QtCore.Qt.AlignCenter

Richtet den Text horizontal und vertikal zentriert im Rechteck aus.


Das mit diesem Code erstellte Widget sieht so aus wie in Abbildung 24.16.

Abbildung 24.16  Mittels drawText kann Text gezeichnet werden.

Es gibt noch eine zweite, vereinfachte Variante, drawText zu verwenden. Dabei werden ebenfalls drei Parameter übergeben: die X-Koordinate, an die der Text geschrieben werden soll, die Y-Koordinate, an die der Text geschrieben werden soll, und ein String, der den Text enthält. Wenn im obigen Beispielprogramm der Aufruf von drawText durch folgende Codezeile ersetzt wird,

painter.drawText(0, 16, "Hallo Welt")

dann sieht das erstellte Widget so aus wie in Abbildung 24.17.

Abbildung 24.17  Eine Variante von drawText

Beachten Sie, dass sich die Koordinaten, die bei der zweiten Variante von drawText übergeben werden, auf die untere linke Ecke des Texts beziehen, sodass der Text nicht an die Position 0/0 geschrieben werden kann. Der als Y-Koordinate übergebene Wert von 16 Pixeln entspricht genau der gewählten Schriftgröße, weswegen der Text direkt unter dem oberen Rand des Widgets erscheint.


Galileo Computing - Zum Seitenanfang

24.6.6 Eye-Candy  topZur vorigen Überschrift

Eingangs wurde erwähnt, dass das Qt-Framework unter anderem in Bezug auf seine Zeichenfunktionalität aus der Masse der GUI-Toolkits heraussticht. Zugegebenermaßen sind die bislang besprochenen Grundlagen zum Zeichnen in einem Qt-Widget zwar wichtig, aber auch nicht besonders beeindruckend. Funktionalität zum Zeichnen von grundlegenden geometrischen Formen, Grafiken und Text finden Sie so oder so ähnlich auch in vielen anderen Toolkits. Aus diesem Grund möchten wir in diesem Kapitel einige Aspekte der Zeichenfunktionalität von Qt in den Vordergrund holen und als »Eye-Candy« (dt. Blickfang, Augenweide) präsentieren. Die hier besprochenen Aspekte des Zeichnens in Qt dienen als Demonstration der Zeichenfunktionalität und sollen Stichwörter liefern, unter denen in der Qt-Dokumentation näher nachgeforscht werden kann. Den Quelltext der hier vorgeführten Beispielanwendungen finden Sie auf der CD, die diesem Buch beiliegt.

Farbverläufe

Abgesehen von einem flächigen Farbanstrich kann ein Brush einen beliebigen Bereich auch mit komplexeren Strukturen füllen. So kann ein Brush beispielsweise verwendet werden, um das Innere eines Rechtecks mit einem Farbverlauf zu füllen, wie in dem Widget aus Abbildung 24.18 zu sehen ist.

Abbildung 24.18  Ein Farbverlauf mit QLinearGradient

Um einen Brush zu erstellen, der Flächen mit einem Farbverlauf füllt, muss zunächst eine Instanz einer Gradient-Klasse erzeugt werden. Eine solche Gradient-Klasse (dt. Gefälle) enthält alle Informationen, die benötigt werden, um einen Farbverlauf zu zeichnen. Es existieren drei verschiedene Gradient-Klassen, die jeweils einen eigenen Typus von Farbverlauf beschreiben. Die folgende Tabelle benennt und erläutert kurz jede dieser Klassen:


Tabelle 24.6  Gradient-Klassen
Klasse Beschreibung
QtGui.QConicalGradient

Beschreibt einen konischen Farbverlauf. Das Ergebnis ähnelt der Draufsicht eines Kegels.

QtGui.QLinearGradient

Beschreibt einen linearen Farbverlauf. Ein solcher wurde im Beispielwidget aus Abbildung 24.18 verwendet.

QtGui.QRadialGradient

Beschreibt einen radialen (kreisförmigen) Farbverlauf.


Nachdem eine Instanz einer Gradient-Klasse mit den erforderlichen Informationen über den Farbverlauf erzeugt wurde, kann diese dem Konstruktor eines Brushs als Parameter übergeben werden. Ein auf diese Weise erzeugter Brush kann dann verwendet werden, um eine Fläche mit einem Farbverlauf zu füllen.

Transparenz

Das Qt-Framework unterstützt sowohl bei einem Brush als auch bei einem Pen das sogenannte Alpha-Blending. Darunter versteht man einen Transparenzwert, den jeder Farbwert besitzt und der bei der Erzeugung einer QColor-Instanz als vierter Parameter übergeben werden kann. Auf diese Weise ist es möglich, teilweise transparente, Formen zu zeichnen, die sich überlappen. Das soll das Beispiel-Widget aus Abbildung 24.19 demonstrieren.

Abbildung 24.19  Alpha-Blending

Zum Verwenden von Alpha-Blending reicht es tatsächlich aus, bei der Erzeugung eines Brushs bzw. eines Pens eine QColor-Instanz mit einem Transparenzwert zu übergeben.

Diese Möglichkeiten zur Darstellung von Transparenzen lassen sich beispielsweise im Zusammenhang mit den bereits besprochenen Farbverläufen für interessante Effekte nutzen (siehe Abbildung 24.20).

Abbildung 24.20  Transparenzeffekt

In diesem Beispielwidget wird eine Grafik angezeigt, die von einem Rechteck überlagert wird. Das Innere dieses Rechtecks ist mit einem Farbverlauf-Brush gezeichnet. Die Zielfarbe dieses Farbverlaufs ist vollständig transparent. Dieses Beispiel soll demonstrieren, dass das Qt-Framework tatsächlich eine grundlegende Unterstützung für Transparenzen in allen Bereichen des Zeichnens bietet.

Anti-Aliasing

Wenn Sie sich das Beispielwidget mit den beiden überlappenden, teilweise transparenten Kreisen noch einmal ansehen, werden Sie feststellen, dass man die einzelnen Pixel, aus denen der Umriss der Kreise besteht, erkennen kann. Die Kreise sehen deswegen nicht besonders ansprechend aus. In vielen Fällen soll eine solche oder ähnliche Zeichnung »sauber« aussehen. Genau zu diesem Zweck existiert eine Technik namens Anti-Aliasing, von der Sie vielleicht schon im Zusammenhang mit Computerspielen gehört haben. Beim Anti-Aliasing werden die Randbereiche einer Zeichnung geglättet, sodass einzelne Pixel nicht mehr auszumachen sind. Das Qt-Framework bietet grundlegende Unterstützung zum Zeichnen mit Anti-Aliasing.

Das Transparenz-Beispiel mit aktiviertem Anti-Aliasing sieht so aus wie in Abbildung 24.21.

Abbildung 24.21  Anti-Aliasing

Um Anti-Aliasing bei einem Painter zu aktivieren, wird die Codezeile

painter.setRenderHints(QtGui.QPainter.Antialiasing)

verwendet, wobei painter eine QPainter-Instanz ist.

Transformationen

Eine weitere interessante Möglichkeit, die Qt bietet, sind Transformationen, die mithilfe einer Transformationsmatrix auf eine beliebige zu zeichnende Form angewandt werden können. Eine Transformationsmatrix wird durch die Klasse QMatrix repräsentiert.

Abbildung 24.22  Matrixtransformationen

Im Beispiel aus Abbildung 24.22 wurde zunächst eine Figur erstellt, die nachher transformiert werden sollte. Da es sich dabei nicht um eine Form handelt, die in Qt bereits vorgesehen ist, wie beispielsweise ein Rechteck oder eine Ellipse, muss die Figur mithilfe eines sogenannten Painter Path zu einer Einheit zusammengefügt werden. Ein Painter Path ist eine Instanz der Klasse QPainterPath. Die Form dieses Beispiels besteht aus zwei Linien und einer Beziérkurve [Eine Beziérkurve ist eine Kurve, die durch eine mathematische Funktion mit, im Falle einer kubischen Beziérkurve, vier Parametern beschrieben wird. Beziérkurven können auch in vielen Grafikprogrammen erstellt werden. ] .

Nachdem sowohl die Matrix als auch der Painter Path erstellt worden sind, kann die Matrix auf den Painter Path angewandt und der resultierende, transformierte Painter Path schließlich gezeichnet werden. Im Beispiel wurde die Matrix in fünf Iterationsschritten immer wieder verändert und die entstandende Figur jeweils mit einem unterschiedlichen Pen gezeichnet.

Beide Klassen, QPainterPath und QMatrix, enthalten viele Methoden, die das Arbeiten mit ihnen erheblich erleichtern. In der Qt-Dokumentation finden Sie ausführliche und grafisch sehr ansprechende Beispielprogramme zu dieser Thematik.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






 <<   zurück
  
  Zum Katalog
Zum Katalog: Python






Python
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Linux






 Linux


Zum Katalog: Ubuntu GNU/Linux






 Ubuntu GNU/Linux


Zum Katalog: Praxisbuch Web 2.0






 Praxisbuch Web 2.0


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Praxisbuch Objektorientierung






 Praxisbuch Objektorientierung


Zum Katalog: Einstieg in SQL






 Einstieg in SQL


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für Fachinformatiker


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo