Rheinwerk Computing < openbook >

 
Inhaltsverzeichnis
1 Einleitung
2 Die Programmiersprache Python
Teil I Einstieg in Python
3 Erste Schritte im interaktiven Modus
4 Der Weg zum ersten Programm
5 Kontrollstrukturen
6 Dateien
7 Das Laufzeitmodell
8 Funktionen, Methoden und Attribute
9 Informationsquellen zu Python
Teil II Datentypen
10 Das Nichts – NoneType
11 Operatoren
12 Numerische Datentypen
13 Sequenzielle Datentypen
14 Zuordnungen
15 Mengen
16 Collections
17 Datum und Zeit
18 Aufzählungstypen – Enum
Teil III Fortgeschrittene Programmiertechniken
19 Funktionen
20 Modularisierung
21 Objektorientierung
22 Ausnahmebehandlung
23 Iteratoren
24 Kontextobjekte
25 Manipulation von Funktionen und Methoden
Teil IV Die Standardbibliothek
26 Mathematik
27 Kryptografie
28 Reguläre Ausdrücke
29 Schnittstelle zu Betriebssystem und Laufzeitumgebung
30 Kommandozeilenparameter
31 Dateisystem
32 Parallele Programmierung
33 Datenspeicherung
34 Netzwerkkommunikation
35 Debugging und Qualitätssicherung
36 Dokumentation
Teil V Weiterführende Themen
37 Anbindung an andere Programmiersprachen
38 Distribution von Python-Projekten
39 Grafische Benutzeroberflächen
40 Python als serverseitige Programmiersprache im WWW – ein Einstieg in Django
41 Wissenschaftliches Rechnen
42 Insiderwissen
43 Von Python 2 nach Python 3
A Anhang
Stichwortverzeichnis

Download:
- Beispielprogramme, ca. 464 KB

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Python 3 von Johannes Ernesti, Peter Kaiser
Das umfassende Handbuch
Buch: Python 3

Python 3
Pfeil 39 Grafische Benutzeroberflächen
Pfeil 39.1 Toolkits
Pfeil 39.2 Einführung in tkinter
Pfeil 39.2.1 Ein einfaches Beispiel
Pfeil 39.2.2 Steuerelementvariablen
Pfeil 39.2.3 Der Packer
Pfeil 39.2.4 Events
Pfeil 39.2.5 Steuerelemente
Pfeil 39.2.6 Zeichnungen – das Canvas-Widget
Pfeil 39.2.7 Weitere Module
Pfeil 39.3 Einführung in PyQt
Pfeil 39.3.1 Installation
Pfeil 39.3.2 Grundlegende Konzepte von Qt
Pfeil 39.3.3 Entwicklungsprozess
Pfeil 39.4 Signale und Slots
Pfeil 39.5 Wichtige Widgets
Pfeil 39.5.1 QCheckBox
Pfeil 39.5.2 QComboBox
Pfeil 39.5.3 QDateEdit, QTimeEdit, QDateTimeEdit
Pfeil 39.5.4 QDialog
Pfeil 39.5.5 QLineEdit
Pfeil 39.5.6 QListWidget, QListView
Pfeil 39.5.7 QProgressBar
Pfeil 39.5.8 QPushButton
Pfeil 39.5.9 QRadioButton
Pfeil 39.5.10 QSlider, QDial
Pfeil 39.5.11 QTextEdit
Pfeil 39.5.12 QWidget
Pfeil 39.6 Zeichenfunktionalität
Pfeil 39.6.1 Werkzeuge
Pfeil 39.6.2 Koordinatensystem
Pfeil 39.6.3 Einfache Formen
Pfeil 39.6.4 Grafiken
Pfeil 39.6.5 Text
Pfeil 39.6.6 Eye Candy
Pfeil 39.7 Model-View-Architektur
Pfeil 39.7.1 Beispielprojekt: ein Adressbuch
Pfeil 39.7.2 Auswählen von Einträgen
Pfeil 39.7.3 Bearbeiten von Einträgen
 
Zum Seitenanfang

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

In den vorangegangenen Abschnitten haben wir Ihnen das Qt-Framework anhand eines kleinen Beispielprogramms vorgestellt und daraufhin die wichtigsten Widgets besprochen. In diesem Abschnitt wird das Zeichnen in Qt behandelt. Thema des letzten Abschnitts zu Qt wird die Model-View-Architektur sein.

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 kann zum Beispiel ein Diagramm oder eine spezifische Grafik sein.

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

Die in den folgenden Abschnitten präsentierten Beispielklassen verstehen sich im folgenden Kontext:

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

Wir werden in den Abschnitten jeweils nur die Klasse MeinWidget neu implementieren. Um aus diesen Beispielen ein lauffähiges PyQt-Programm zu erstellen, muss die vorgestellte Klasse in den oben dargestellten Kontext eingefügt werden.

 
Zum Seitenanfang

39.6.1    Werkzeuge Zur vorigen ÜberschriftZur nächsten Ü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.[ 194 ](In unseren einfachen Beispielen werden wir beim Aufrufen der paintEvent-Methode stets die komplette Grafik neu zeichnen. Je komplexer und aufwendiger eine Grafik jedoch ist, desto eher sollten Sie nur den durch die QPaintEvent-Instanz spezifizierten Bereich tatsächlich neu zeichnen. )

Innerhalb der paintEvent-Methode muss ein Painter (dt. »Maler«) erzeugt werden, mit dessen Hilfe die Zeichenoperationen 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(QtWidgets.QWidget): 
def __init__(self, parent=None):
super().__init__(parent)
def paintEvent(self, event):
painter = QtGui.QPainter(self)

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

Als Pen (dt. »Stift«) wird eine Instanz der Klasse QtGui.QPen bezeichnet. Um einen Pen zu verwenden, muss dieser dem Painter mithilfe der Methode setPen bekannt gegeben werden. Grundsätzlich wird ein Pen zum Zeichnen von Linien, beispielsweise für Umrandungen bestimmter Figuren, verwendet. Dazu benötigt 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[ 195 ](Eine RGB-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. ), zu spezifizieren. Nachdem ein Pen erzeugt worden ist, kann seine Liniendicke bzw. der Linienstil durch die 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 Pixel, 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 Tabelle 39.23.

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

Tabelle 39.23    Linienstile eines Pens

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

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

Auch dem Konstruktor des Brushes 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. Hier können beispielsweise Schraffierungen, Farbverläufe oder Texturen gesetzt werden, worauf wir an dieser Stelle aber nicht näher eingehen werden.

Allgemein gilt, dass Pens und Brushes ausgewählt werden müssen, bevor sie benutzt werden können. Dazu werden die Methoden setPen bzw. setBrush des Painters mit der jeweiligen QPen- bzw. QBrush-Instanz als Parameter aufgerufen. Eine darauffolgende Zeichenoperation wird dann mit den ausgewählten Werkzeugen durchgeführt. Es können immer nur ein Brush und ein Pen gleichzeitig ausgewählt sein.

 
Zum Seitenanfang

39.6.2    Koordinatensystem Zur vorigen ÜberschriftZur nächsten Überschrift

Bevor es ans Zeichnen geht, müssen wir uns Gedanken über das in Qt verwendete Koordinatensystem machen. Dieses lehnt sich an andere GUI-Toolkits an und ist in Abbildung 39.41 dargestellt.

Das Qt-Koordinatensystem

Abbildung 39.41    Das Qt-Koordinatensystem

Der Ursprung des Koordinatensystems liegt in der oberen linken Ecke des Widgets, und die Y-Achse zeigt, im Gegensatz zu dem in der Mathematik verwendeten kartesischen Koordinatensystem, nach unten. 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 linker 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.

 
Zum Seitenanfang

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

Das Qt-Framework bietet eine Reihe abstrakter 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(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(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 Stift mit einer Dicke von drei Pixeln und um einen weißen Pinsel. In der Methode paintEvent werden nach dem Erzeugen des Painters die beiden Werkzeuge ausgewählt. 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.

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

Ein mit drawRect gezeichnetes Quadrat

Abbildung 39.42    Ein mit drawRect gezeichnetes Quadrat

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

Um eine dieser Figuren in ihrer Größe an das Widget anzupassen, kann die parameterlose Methode rect einer Widget-Klasse verwendet werden, die die Dimensionen des Widgets als QRect-Instanz[ 196 ](Die Klasse QRect beschreibt ein Rechteck und verfügt unter anderem über die parameterlosen Methoden x, y, width und height, mit denen auf die Koordinaten der oberen linken Ecke und die Dimensionen des Rechtecks zugegriffen werden kann. ) 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. Tabelle 39.24 gibt Ihnen eine Übersicht über die wichtigsten dieser Methoden, die in diesem Kapitel nicht weiter besprochen werden.

Methode Beschreibung
drawArc(x, y, w, h, a, alen) Zeichnet einen geöffneten Bogen mit dem Startwinkel a und dem Spannwinkel alen. Die anderen Parameter spezifizieren das umgebende Rechteck. »Geöffnet« bedeutet in diesem Fall, dass die beiden Enden des Bogens nicht durch eine Linie miteinander verbunden sind.
drawChord(x, y, w, h, a, alen) Zeichnet einen geschlossenen Bogen. »Geschlossen« bedeutet, dass die beiden Enden des Bogens durch eine Linie miteinander verbunden sind.
drawConvexPolygon( point, …) Zeichnet ein konvexes Polygon*. Es können entweder eine QPolygon-Instanz oder beliebig viele QPoint-Instanzen übergeben werden.
drawLine(x1, y1, x2, y2) Zeichnet eine Linie von (x1, y1) nach (x2, y2).
drawLines(line) Zeichnet einen Linienzug. Dieser kann in Form einer Liste von QPoint-Instanzen übergeben werden.
drawPie(x, y, w, h, a, alen) Zeichnet einen Ausschnitt einer Ellipse, der umgangssprachlich als Tortenstück bezeichnet wird.
drawPolygon(point, …) Zeichnet ein beliebiges Polygon. Diese Methode ist allgemeiner als drawConvexPolygon.
* 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. Ein nichtkonvexes Polygon ist wesentlich aufwendiger darzustellen als ein konvexes.

Tabelle 39.24    Methoden eines Painters

 
Zum Seitenanfang

39.6.4    Grafiken Zur vorigen ÜberschriftZur nächsten Überschrift

Neben dem Zeichnen der grundlegenden geometrischen Formen ermöglicht es das Qt-Framework über die Klasse QImage, Grafiken der verschiedensten Formate von der Festplatte zu laden und mithilfe eines Painters anzuzeigen.[ 197 ](Qt »versteht« unter anderem die Dateiformate BMP, GIF, JPG und PNG. ) Das folgende Beispielprogramm lädt die Grafik buch.jpg und zeigt sie mithilfe der Methode drawImage des Painters an:

class MeinWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.grafik = QtGui.QImage("lena.jpg")
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 Widget-Klasse MeinWidget wird zunächst unter Angabe des Pfades der zu ladenden Grafik eine Instanz der Klasse QImage erzeugt. Danach 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 entspricht dem 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 39.43.

Eine Grafik in einem Widget

Abbildung 39.43    Eine Grafik in einem Widget

[»]  Hinweis

In diesem Fall wurde ein nicht quadratisches Bild auf eine quadratische Fläche gezeichnet und somit beim Zeichnen leicht gestreckt. Um dies zu vermeiden, muss das Seitenverhältnis des Zielrechtecks an das des Quellrechtecks angepasst werden.

 
Zum Seitenanfang

39.6.5    Text Zur vorigen ÜberschriftZur nächsten Überschrift

Nachdem Sie nun sowohl geometrische Formen als auch Grafiken in ein Widget zeichnen können, fehlt noch das Zeichnen von Text, beispielsweise für die Beschriftung von Diagrammen.

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(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(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 Schrifttyp in einer bestimmten Größe. Zudem wird ein Pen erzeugt, der die Schriftfarbe vorgibt, in der der Text geschrieben werden soll.

In der Methode paintEvent wird zunächst, wie gehabt, ein Painter erzeugt. Danach werden mittels setFont und setPen Schriftart und Stift ausgewählt. 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 Textes innerhalb des angegebenen Rechtecks können mehrere Konstanten mithilfe des binären ODER verknüpft werden. Die wichtigsten dieser Konstanten sind in Tabelle 39.25 aufgelistet und kurz erläutert:

Konstante Ausrichtung
QtCore.Qt.AlignLeft links
QtCore.Qt.AlignRight rechts
QtCore.Qt.AlignHCenter horizontal zentriert
QtCore.Qt.AlignTop oben
QtCore.Qt.AlignBottom unten
QtCore.Qt.AlignVCenter vertikal zentriert
QtCore.Qt.AlignCenter horizontal und vertikal zentriert

Tabelle 39.25    Konstanten zur Positionierung des Textes

Das mit diesem Code erstellte Widget ist in Abbildung 39.44 dargestellt.

Mit drawText kann Text gezeichnet werden.

Abbildung 39.44    Mit drawText kann Text gezeichnet werden.

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

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

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

 
Zum Seitenanfang

39.6.6    Eye Candy Zur vorigen ÜberschriftZur nächsten Ü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. Funktionen zum Zeichnen grundlegender geometrischer 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 Sie in der Qt-Dokumentation später genauer nachforschen können.

Den lauffähigen Quellcode zu den gezeigten Beispielen finden Sie im Onlineangebot zu diesem Buch (www.rheinwerk-verlag.de/4467).

Farbverläufe

Abgesehen von einem flächigen Farbanstrich kann ein Brush einen Bereich auch mit komplexeren Strukturen füllen. So kann beispielsweise das Innere eines Rechtecks mit einem Farbverlauf gefüllt werden, wie in Abbildung 39.45 zu sehen ist.

Ein Farbverlauf mit QLinearGradient

Abbildung 39.45    Ein Farbverlauf mit QLinearGradient

Um einen Brush zu erstellen, der Flächen mit einem Farbverlauf füllt, müssen Sie zunächst eine Instanz einer Gradient-Klasse (dt. »Gefälle«) erzeugen. Eine solche Klasse 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:

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 Beispiel-Widget aus Abbildung 39.45 verwendet.
QtGui.QRadialGradient Beschreibt einen kreisförmigen Farbverlauf.

Tabelle 39.26    Gradient-Klassen

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 das Zeichnen teilweise transparenter Strukturen. Abbildung 39.46 zeigt zwei sich überschneidende, semitransparente Kreise.

Alpha-Blending

Abbildung 39.46    Alpha-Blending

Zum Verwenden von Alpha-Blending reicht es aus, bei der Erzeugung eines Brushs bzw. eines Pens eine QColor-Instanz mit einem Transparenzwert zu übergeben. Dieser Transparenzwert wird dem QColor-Konstruktor als vierter Parameter übergeben. Hier sind ganzzahlige Werte zwischen 0 (vollständig transparent) und 255 (opak) möglich.

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

Transparenzeffekt

Abbildung 39.47    Transparenzeffekt

In diesem Beispiel-Widget wird eine von einem Rechteck überlagerte Grafik angezeigt. Das Innere dieses Rechtecks ist mit einem Farbverlauf-Brush gezeichnet. Die Zielfarbe dieses Farbverlaufs ist vollständig transparent.

Anti-Aliasing

Wenn Sie sich das Beispiel-Widget 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. 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 sehen Sie in Abbildung 39.48.

Anti-Aliasing

Abbildung 39.48    Anti-Aliasing

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

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 von Transformationsmatrizen auf beliebige zu zeichnende Formen angewendet werden können. Eine Transformationsmatrix wird durch die Klasse QMatrix repräsentiert.

Matrixtransformationen

Abbildung 39.49    Matrixtransformationen

Im Beispiel aus Abbildung 39.49 wurde zunächst eine Figur erstellt. Da es sich dabei nicht um eine vorgefertigte Form handelt, 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 Bézierkurve[ 198 ](Eine Bézierkurve ist eine Kurve, die durch eine mathematische Funktion mit – im Falle einer kubischen Bézierkurve – vier Parametern beschrieben wird. Bézierkurven können auch in vielen Grafikprogrammen erstellt werden. ).

Nachdem sowohl die Transformation als QTransform-Instanz als auch der Painter Path erstellt worden sind, kann die Transformation auf den Painter angewandt und der resultierende transformierte Painter Path schließlich gezeichnet werden. Im Beispiel wurde die Transformation in fünf Iterationsschritten immer wieder verändert und die entstandene Figur jeweils gezeichnet.

 


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Python 3 Python 3
Jetzt Buch bestellen

 Buchempfehlungen
Zum Rheinwerk-Shop: Einstieg in Python
Einstieg in Python


Zum Rheinwerk-Shop: Python. Der Grundkurs
Python. Der Grundkurs


Zum Rheinwerk-Shop: Algorithmen mit Python
Algorithmen mit Python


Zum Rheinwerk-Shop: Objektorientierte Programmierung
Objektorientierte Programmierung


Zum Rheinwerk-Shop: Raspberry Pi. Das umfassende Handbuch
Raspberry Pi. Das umfassende Handbuch


Zum Rheinwerk-Shop: Roboter-Autos mit dem Raspberry Pi
Roboter-Autos mit dem Raspberry Pi


Zum Rheinwerk-Shop: Neuronale Netze programmieren mit Python
Neuronale Netze programmieren mit Python


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2020
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 
[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern