Koordinatensystem
Das Koordinatensystem wird von der Klasse „ QPainter “ gesteuert. Zusammen mit den Klassen „ QPaintDevice “ und „ QPaintEngine “ bildet „ QPainter “ die Grundlage für das Zeichensystem von Qt, „Arthur“. „ QPainter “ wird zur Durchführung von Zeichenoperationen verwendet, „ QPaintDevice “ ist eine Abstraktion eines zweidimensionalen Raums, der mithilfe von „ QPainter “ gezeichnet werden kann, und „ QPaintEngine “ stellt die Schnittstelle bereit, über die der „Painter“ auf verschiedene Arten von Geräten zeichnet.
Die Klasse „ QPaintDevice “ ist die Basisklasse für Objekte, die gezeichnet werden können: Ihre Zeichenfunktionen werden von den Klassen „ QWidget “, „ QImage “, „ QPixmap “, „ QPicture “ und „ QOpenGLPaintDevice “ geerbt. Das Standardkoordinatensystem eines Zeichen-Geräts hat seinen Ursprung in der oberen linken Ecke. Die x-Werte nehmen nach rechts hin zu, die y-Werte nach unten hin. Die Standardeinheit ist ein Pixel auf pixelbasierten Geräten und ein Punkt (1/72 Zoll) auf Druckern.
Die Abbildung der logischen Koordinaten QPainter auf die physikalischen Koordinaten QPaintDevice erfolgt über die Transformationsmatrix, den Viewport und das „Fenster“ von QPainter. Das logische und das physikalische Koordinatensystem stimmen standardmäßig überein. QPainter unterstützt zudem Koordinatentransformationen (z. B. Drehung und Skalierung).
Rendering
Logische Darstellung
Die Größe (Breite und Höhe) einer Grafikprimitive entspricht stets ihrem mathematischen Modell, wobei die Breite des Stifts, mit dem sie gerendert wird, unberücksichtigt bleibt:
| QRect(QPoint(1, 2), QPoint(7, 6)) | QLine(QPoint(2, 7), QPoint(6, 1)) |
| QLine(2, 7, 6, 1) | |
| QRect(QPoint(1, 2), QSize(6, 4)) | |
| QRect(1, 2, 6, 4) |
Aliasing beim Zeichnen
Beim Zeichnen wird die Pixelwiedergabe durch den Render-Hinweis „ QPainter::Antialiasing “ gesteuert.
Die Enumeration „ RenderHint “ wird verwendet, um Flags für „ QPainter “ anzugeben, die von einer bestimmten Engine beachtet werden können oder auch nicht. Der Wert „ QPainter::Antialiasing “ gibt an, dass die Engine die Kanten von Primitiven nach Möglichkeit glätten soll, d. h. die Kanten durch unterschiedliche Farbintensitäten glätten soll.
Standardmäßig weist der „Painter“ jedoch Aliasing auf, und es gelten andere Regeln: Beim Rendern mit einem ein Pixel breiten Stift werden die Pixel rechts und unterhalb der mathematisch definierten Punkte gerendert. Zum Beispiel:
Beim Zeichnen mit einem Stift mit einer geraden Pixelanzahl werden die Pixel symmetrisch um die mathematisch definierten Punkte herum gezeichnet, während beim Zeichnen mit einem Stift mit einer ungeraden Pixelanzahl das zusätzliche Pixel wie im Fall eines Pixels rechts und unterhalb des mathematischen Punktes gezeichnet wird. Konkrete Beispiele finden Sie in den folgenden Diagrammen unter „ QRectF “.
| QRectF | |
|---|---|
![]() | ![]() |
| Logische Darstellung | Ein Pixel breiter Stift |
![]() | ![]() |
| Stift mit zwei Pixeln Breite | Drei Pixel breiter Stift |
Beachten Sie, dass der Rückgabewert der Funktionen ` QRect::right()` und ` QRect::bottom()` aus historischen Gründen von der tatsächlichen unteren rechten Ecke des Rechtecks abweicht.
QRectDie Funktion ` right()` gibt ` left()` + ` width()` - 1 zurück, und die Funktion ` bottom()` gibt ` top()` + ` height()` - 1 zurück. Der grüne Punkt unten rechts in den Diagrammen zeigt die Rückgabekoordinaten dieser Funktionen an.
Wir empfehlen Ihnen, stattdessen einfach QRectF zu verwenden: Die Klasse QRectF definiert ein Rechteck in der Ebene unter Verwendung von Gleitkomma-Koordinaten für höhere Genauigkeit (QRect verwendet ganzzahlige Koordinaten), und die Funktionen QRectF::right() und QRectF::bottom() geben tatsächlich die rechte untere Ecke zurück.
Alternativ können Sie mit „ QRect “ die Funktionen „ x()“ + „ width()“ und „ y()“ + „ height()“ anwenden, um die rechte untere Ecke zu ermitteln, und dabei die Funktionen „ right()“ und „ bottom()“ vermeiden.
Anti-Aliasing beim Zeichnen
Wenn Sie den Render-Hinweis „ anti-aliasing “ von „ QPainter “ festlegen, werden die Pixel symmetrisch zu beiden Seiten der mathematisch definierten Punkte gerendert:
Transformationen
Standardmäßig arbeitet der „ QPainter “ im eigenen Koordinatensystem des zugehörigen Geräts, unterstützt jedoch auch affine Koordinatentransformationen vollständig.
Mit der Funktion ` QPainter::scale()` können Sie das Koordinatensystem um einen bestimmten Versatz skalieren, mit der Funktion ` QPainter::rotate()` können Sie es im Uhrzeigersinn drehen und mit der Funktion ` QPainter::translate()` können Sie es verschieben (d. h. den Punkten einen bestimmten Versatz hinzufügen).
Mit der Funktion ` QPainter::shear()` können Sie das Koordinatensystem außerdem um den Ursprung verdrehen. Alle Transformationsoperationen wirken auf die Transformationsmatrix von ` QPainter`, die Sie mit der Funktion ` QPainter::worldTransform()` abrufen können. Eine Matrix transformiert einen Punkt in der Ebene in einen anderen Punkt.
Wenn Sie dieselben Transformationen immer wieder benötigen, können Sie auch „ QTransform “-Objekte sowie die Funktionen „ QPainter::worldTransform()“ und „ QPainter::setWorldTransform()“ verwenden. Sie können die Transformationsmatrix von „ QPainter “ jederzeit speichern, indem Sie die Funktion „ QPainter::save()“ aufrufen, die die Matrix auf einem internen Stack speichert. Die Funktion „ QPainter::restore()“ holt sie wieder vom Stack.
Die Transformationsmatrix wird häufig benötigt, wenn derselbe Zeichnungscode auf verschiedenen Ausgabegeräten wiederverwendet wird. Ohne Transformationen sind die Ergebnisse fest an die Auflösung des Ausgabegeräts gebunden. Drucker haben eine hohe Auflösung, z. B. 600 Punkte pro Zoll, während Bildschirme oft zwischen 72 und 100 Punkte pro Zoll aufweisen.
| Beispiel „Analoge Uhr“ | |
|---|---|
![]() | Das Beispiel „Analoge Uhr“ zeigt, wie der Inhalt eines benutzerdefinierten Widgets mithilfe der Transformationsmatrix von „ QPainter “ gezeichnet wird. Wir empfehlen, dieses Beispiel zu kompilieren und auszuführen, bevor Sie weiterlesen. Versuchen Sie insbesondere, die Größe des Fensters zu ändern. |
Wir verschieben das Koordinatensystem so, dass der Punkt (0, 0) in der Mitte des Widgets liegt und nicht in der oberen linken Ecke. Außerdem skalieren wir das System mit dem Faktor „ Dadurch erhalten wir einen quadratischen Bereich von 200 × 200 mit dem Ursprung (0, 0) in der Mitte, auf dem wir zeichnen können. Was wir zeichnen, wird in dem größtmöglichen Quadrat angezeigt, das in das Widget passt. Siehe auch den Abschnitt „Umrechnung von Fenster zu Ansichtsbereich “. Wir zeichnen den Stundenzeiger der Uhr, indem wir das Koordinatensystem drehen und ` QPainter::drawConvexPolygon()` aufrufen. Dank der Drehung wird er in die richtige Richtung zeigend gezeichnet. Das Polygon wird als Array abwechselnder x- und y-Werte angegeben, die in der statischen Variablen ` Die Aufrufe von ` QPainter::save()` und ` QPainter::restore()`, die den Code umschließen, stellen sicher, dass der nachfolgende Code nicht durch die von uns verwendeten Transformationen beeinträchtigt wird. Danach zeichnen wir die Stundenmarkierungen für das Zifferblatt, das aus zwölf kurzen Linien in 30-Grad-Abständen besteht. Wenn diese Schleife beendet ist, hat sich der „Painter“ um eine volle Umdrehung zurück in seinen ursprünglichen Zustand gedreht, sodass wir den Zustand nicht speichern und wiederherstellen müssen. Das Gleiche tun wir für den Minutenzeiger der Uhr, der durch die drei Punkte (7, 8), (-7, 8) und (0, -70) definiert ist. Diese Koordinaten legen einen Zeiger fest, der dünner und länger ist als der Minutenzeiger. Schließlich zeichnen wir die Minutenmarkierungen für das Zifferblatt, das aus sechzig kurzen Linien in Abständen von 6 Grad besteht. Wir lassen jede fünfte Minutenmarkierung aus, da wir die Stundenmarkierungen nicht übermalen wollen. Am Ende wird der „Painter“ auf eine Weise gedreht, die nicht besonders sinnvoll ist, aber da wir mit dem Zeichnen fertig sind, spielt das keine Rolle. | |
Weitere Informationen zur Transformationsmatrix finden Sie in der Dokumentation zu „ QTransform “.
Konvertierung von Fenster zu Viewport
Beim Zeichnen mit „ QPainter “ geben wir Punkte anhand logischer Koordinaten an, die dann in die physikalischen Koordinaten des Zeichen-Geräts umgewandelt werden.
Die Zuordnung der logischen Koordinaten zu den physikalischen Koordinaten erfolgt über die Welt-Transformations worldTransform() von „ QPainter “ (beschrieben im Abschnitt „Transformationen“ ) sowie über die Funktionen „ viewport()“ und „ window()“ von „ QPainter “. Der Viewport repräsentiert die physikalischen Koordinaten, die ein beliebiges Rechteck angeben. Das „Fenster“ beschreibt dasselbe Rechteck in logischen Koordinaten. Standardmäßig stimmen das logische und das physikalische Koordinatensystem überein und entsprechen dem Rechteck des Zeichenbereichs.
Mithilfe der Fenster-Viewport-Konvertierung können Sie das logische Koordinatensystem an Ihre Bedürfnisse anpassen. Dieser Mechanismus kann auch genutzt werden, um den Zeichencode unabhängig vom Zeichen-Device zu machen. Sie können beispielsweise die logischen Koordinaten so festlegen, dass sie sich von (-50, -50) bis (50, 50) erstrecken, wobei (0, 0) im Zentrum liegt, indem Sie die Funktion „ QPainter::setWindow()“ aufrufen:
Nun entsprechen die logischen Koordinaten (-50, -50) den physikalischen Koordinaten (0, 0) des Zeichen-Geräts. Unabhängig vom Zeichen-Gerät arbeitet Ihr Zeichencode immer mit den angegebenen logischen Koordinaten.
Durch das Festlegen des „Fensters“ oder des Viewport-Rechtecks führen Sie eine lineare Transformation der Koordinaten durch. Beachten Sie, dass jede Ecke des „Fensters“ der entsprechenden Ecke des Viewports zugeordnet ist und umgekehrt. Aus diesem Grund ist es normalerweise ratsam, das Seitenverhältnis von Viewport und „Fenster“ identisch zu halten, um Verzerrungen zu vermeiden:
int side = qMin(width(), height());
int x = (width() - side / 2);
int y = (height() - side / 2);
painter.setViewport(x, y, side, side);Wenn wir das logische Koordinatensystem als Quadrat definieren, sollten wir auch den Ansichtsbereich mithilfe der Funktion ` QPainter::setViewport()` als Quadrat festlegen. Im obigen Beispiel machen wir es gleich groß wie das größte Quadrat, das in das Rechteck des Zeichen-Devices passt. Indem man die Größe des Zeichen-Devices bei der Festlegung des Fensters oder des Ansichtsbereichs berücksichtigt, ist es möglich, den Zeichencode unabhängig vom Zeichen-Device zu halten.
Beachten Sie, dass die Umwandlung von Fenster zu Ansichtsbereich lediglich eine lineare Transformation ist, d. h., es findet kein Clipping statt. Das bedeutet: Wenn Sie außerhalb des aktuell festgelegten „Fensters“ zeichnen, wird Ihre Zeichnung dennoch mit demselben linearen algebraischen Ansatz in den Ansichtsbereich transformiert.
Der Viewport, das „Fenster“ und die Transformationsmatrix legen fest, wie die logischen Koordinaten von QPainter auf die physikalischen Koordinaten des Zeichen-Geräts abgebildet werden. Standardmäßig ist die Welttransformationsmatrix die Identitätsmatrix, und die Einstellungen für „Fenster“ und Viewport entsprechen den Einstellungen des Zeichen-Geräts, d. h., das Welt-, das „Fenster“- und das Gerätekoordinatensystem sind identisch. Wie wir jedoch gesehen haben, lassen sich diese Systeme mithilfe von Transformationsoperationen und der Fenster-Viewport-Konvertierung manipulieren. Die obige Abbildung veranschaulicht diesen Vorgang.
Siehe auch „Analoge Uhr“.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.








