Graphics View Framework

Graphics View bietet eine Oberfläche für die Verwaltung und Interaktion mit einer großen Anzahl von benutzerdefinierten 2D-Grafikelementen und ein View-Widget für die Visualisierung der Elemente mit Unterstützung für Zoomen und Drehen.

Das Framework enthält eine Architektur für die Ereignisausbreitung, die präzise Interaktionsmöglichkeiten mit doppelter Genauigkeit für die Elemente in der Szene ermöglicht. Die Elemente können Tastenereignisse, Mausdruck-, Bewegungs-, Loslass- und Doppelklickereignisse verarbeiten und auch Mausbewegungen verfolgen.

Graphics View verwendet einen BSP-Baum (Binary Space Partitioning), um eine sehr schnelle Erkennung von Elementen zu ermöglichen, und kann dadurch große Szenen in Echtzeit visualisieren, selbst mit Millionen von Elementen.

Graphics View wurde in Qt 4.2 eingeführt und löste seinen Vorgänger QCanvas ab.

Die Architektur der Grafikansicht

Graphics View bietet einen Element-basierten Ansatz für die Programmierung von Model-Views, ähnlich wie die InterView-Klassen QTableView, QTreeView und QListView. Mehrere Ansichten können eine einzige Szene beobachten, und die Szene enthält Elemente mit unterschiedlichen geometrischen Formen.

Die Szene

QGraphicsScene stellt die Szene der Grafikansicht bereit. Die Szene hat die folgenden Aufgaben:

  • Bereitstellung einer schnellen Schnittstelle für die Verwaltung einer großen Anzahl von Elementen
  • Weitergabe von Ereignissen an jedes Element
  • Verwaltung des Elementstatus, wie z. B. Auswahl und Fokusbehandlung
  • Bereitstellung von Funktionen für das untransformierte Rendering, hauptsächlich für den Druck

Die Szene dient als Container für QGraphicsItem Objekte. Elemente werden der Szene durch den Aufruf von QGraphicsScene::addItem() hinzugefügt und dann durch den Aufruf einer der vielen Elementerkennungsfunktionen abgerufen. QGraphicsScene::items() und seine Überladungen geben alle Objekte zurück, die in einem Punkt, einem Rechteck, einem Polygon oder einem allgemeinen Vektorpfad enthalten sind oder sich damit schneiden. QGraphicsScene::itemAt() gibt das oberste Element an einem bestimmten Punkt zurück. Alle Funktionen zur Erkennung von Elementen geben die Elemente in absteigender Reihenfolge zurück (d. h. das erste zurückgegebene Element ist das oberste und das letzte Element das unterste).

QGraphicsScene scene;
QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100));

QGraphicsItem *item = scene.itemAt(50, 50, QTransform());

QGraphicsSceneDie Architektur der Ereignisausbreitung plant Szenenereignisse für die Zustellung an Elemente und verwaltet auch die Ausbreitung zwischen Elementen. Wenn die Szene ein Mausdruck-Ereignis an einer bestimmten Position empfängt, gibt sie das Ereignis an das Element weiter, das sich an dieser Position befindet.

QGraphicsScene Die Szene verwaltet auch bestimmte Elementzustände, wie z. B. die Elementauswahl und den Fokus. Sie können Elemente in der Szene auswählen, indem Sie QGraphicsScene::setSelectionArea() aufrufen und eine beliebige Form übergeben. Diese Funktionalität wird auch als Grundlage für die Gummibandauswahl in QGraphicsView verwendet. Um die Liste aller aktuell ausgewählten Elemente zu erhalten, rufen Sie QGraphicsScene::selectedItems() auf. Ein weiterer Zustand, der von QGraphicsScene behandelt wird, ist, ob ein Element den Fokus der Tastatureingabe hat oder nicht. Sie können den Fokus auf ein Element setzen, indem Sie QGraphicsScene::setFocusItem() oder QGraphicsItem::setFocus() aufrufen, oder das aktuelle Fokuselement erhalten, indem Sie QGraphicsScene::focusItem() aufrufen.

Schließlich können Sie mit QGraphicsScene Teile der Szene über die Funktion QGraphicsScene::render() in ein Malgerät rendern. Mehr dazu erfahren Sie im Abschnitt Drucken weiter unten in diesem Dokument.

Die Ansicht

QGraphicsView stellt das View-Widget bereit, das den Inhalt einer Szene visualisiert. Sie können mehrere Ansichten an dieselbe Szene anhängen, um mehrere Ansichtsfenster für denselben Datensatz bereitzustellen. Das View-Widget ist ein Bildlaufbereich und bietet Bildlaufleisten zum Navigieren durch große Szenen. Um die OpenGL-Unterstützung zu aktivieren, können Sie ein QOpenGLWidget als Ansichtsfenster festlegen, indem Sie QGraphicsView::setViewport() aufrufen.

QGraphicsScene scene;
myPopulateScene(&scene);
QGraphicsView view(&scene);
view.show();

Die Ansicht empfängt Eingabeereignisse von der Tastatur und der Maus und übersetzt diese in Szenenereignisse (wobei die verwendeten Koordinaten gegebenenfalls in Szenenkoordinaten umgewandelt werden), bevor die Ereignisse an die visualisierte Szene gesendet werden.

Mit Hilfe seiner Transformationsmatrix QGraphicsView::transform() kann der View das Koordinatensystem der Szene transformieren. Dies ermöglicht erweiterte Navigationsfunktionen wie Zoomen und Drehen. Der Einfachheit halber bietet QGraphicsView auch Funktionen zum Umrechnen zwischen Ansichts- und Szenenkoordinaten: QGraphicsView::mapToScene() und QGraphicsView::mapFromScene().

Das Element

QGraphicsItem ist die Basisklasse für grafische Elemente in einer Szene. Graphics View bietet mehrere Standardelemente für typische Formen, wie Rechtecke (QGraphicsRectItem), Ellipsen (QGraphicsEllipseItem) und Textelemente (QGraphicsTextItem), aber die leistungsfähigsten Funktionen QGraphicsItem sind verfügbar, wenn Sie ein benutzerdefiniertes Element schreiben. Unter anderem unterstützt QGraphicsItem die folgenden Funktionen:

  • Ereignisse beim Drücken, Bewegen, Loslassen und Doppelklicken der Maus sowie Maus-Hover-Ereignisse, Rad-Ereignisse und Kontextmenü-Ereignisse.
  • Tastatur-Eingabefokus und Tastenereignisse
  • Ziehen und Ablegen
  • Gruppierung, sowohl durch Eltern-Kind-Beziehungen, als auch mit QGraphicsItemGroup
  • Kollisionserkennung

Elemente leben in einem lokalen Koordinatensystem, und wie QGraphicsView bietet es auch viele Funktionen zum Zuordnen von Koordinaten zwischen dem Element und der Szene sowie von Element zu Element. Außerdem kann es, wie QGraphicsView, sein Koordinatensystem mithilfe einer Matrix transformieren: QGraphicsItem::transform(). Dies ist nützlich, um einzelne Elemente zu drehen und zu skalieren.

Elemente können andere Elemente (Kinder) enthalten. Die Transformationen der übergeordneten Elemente werden an alle ihre Kinder vererbt. Unabhängig von der akkumulierten Transformation eines Elements arbeiten jedoch alle seine Funktionen (z. B. QGraphicsItem::contains(), QGraphicsItem::boundingRect(), QGraphicsItem::collidesWith()) weiterhin in lokalen Koordinaten.

QGraphicsItem QGraphicsItem::collidesWith() unterstützt die Kollisionserkennung durch die Funktionen QGraphicsItem::shape() und QGraphicsItem::collidesWith(), die beide virtuelle Funktionen sind. Indem Sie die Form Ihres Objekts als lokale Koordinate QPainterPath von QGraphicsItem::shape() zurückgeben, wird QGraphicsItem die gesamte Kollisionserkennung für Sie übernehmen. Wenn Sie jedoch Ihre eigene Kollisionserkennung bereitstellen möchten, können Sie QGraphicsItem::collidesWith() neu implementieren.

Klassen im Graphics View Framework

Diese Klassen bieten einen Rahmen für die Erstellung interaktiver Anwendungen.

QAbstractGraphicsShapeItem

Gemeinsame Basis für alle Pfadelemente

QGraphicsAnchor

Repräsentiert einen Anker zwischen zwei Elementen in einem QGraphicsAnchorLayout

QGraphicsAnchorLayout

Layout, in dem man Widgets in der Grafikansicht miteinander verankern kann

QGraphicsEffect

Die Basisklasse für alle Grafikeffekte

QGraphicsEllipseItem

Ellipsen-Element, das Sie zu einer QGraphicsScene hinzufügen können

QGraphicsGridLayout

Grid-Layout zur Verwaltung von Widgets in der Grafikansicht

QGraphicsItem

Die Basisklasse für alle grafischen Elemente in einer QGraphicsScene

QGraphicsItemGroup

Container, der eine Gruppe von Elementen als ein einzelnes Element behandelt

QGraphicsLayout

Die Basisklasse für alle Layouts in der Grafikansicht

QGraphicsLayoutItem

Kann vererbt werden, damit Ihre eigenen Elemente von Layouts verwaltet werden können

QGraphicsLineItem

Zeilenelement, das Sie zu einer QGraphicsScene hinzufügen können

QGraphicsLinearLayout

Horizontales oder vertikales Layout zur Verwaltung von Widgets in der Grafikansicht

QGraphicsObject

Basisklasse für alle Grafikelemente, die Signale, Slots und Eigenschaften benötigen

QGraphicsPathItem

Pfad-Element, das Sie zu einer QGraphicsScene hinzufügen können

QGraphicsPixmapItem

Pixmap-Element, das Sie zu einer QGraphicsScene hinzufügen können

QGraphicsPolygonItem

Polygon-Element, das Sie einer QGraphicsScene hinzufügen können

QGraphicsProxyWidget

Proxy-Ebene zum Einbetten eines QWidget in eine QGraphicsScene

QGraphicsRectItem

Rechteck-Element, das Sie zu einer QGraphicsScene hinzufügen können

QGraphicsScene

Oberfläche für die Verwaltung einer großen Anzahl von 2D-Grafikelementen

QGraphicsSceneContextMenuEvent

Kontextmenü-Ereignisse im Rahmen der Grafikansicht

QGraphicsSceneDragDropEvent

Ereignisse für das Ziehen und Ablegen in der Grafikansicht

QGraphicsSceneEvent

Basisklasse für alle Ereignisse in der Grafikansicht

QGraphicsSceneHelpEvent

Ereignisse, wenn ein Tooltip angefordert wird

QGraphicsSceneHoverEvent

Hover-Ereignisse im Framework für die grafische Darstellung

QGraphicsSceneMouseEvent

Mausereignisse im Framework für die grafische Darstellung

QGraphicsSceneMoveEvent

Ereignisse für das Verschieben von Widgets im Framework für die Grafikansicht

QGraphicsSceneResizeEvent

Ereignisse für die Größenänderung von Widgets im Framework für die grafische Darstellung

QGraphicsSceneWheelEvent

Rad-Ereignisse im Framework für die grafische Darstellung

QGraphicsSimpleTextItem

Einfaches Textpfad-Element, das Sie zu einer QGraphicsScene hinzufügen können

QGraphicsSvgItem

QGraphicsItem, das zum Rendern des Inhalts von SVG-Dateien verwendet werden kann

QGraphicsTextItem

Textelement, das Sie einer QGraphicsScene hinzufügen können, um formatierten Text anzuzeigen

QGraphicsTransform

Abstrakte Basisklasse zur Erstellung von erweiterten Transformationen auf QGraphicsItems

QGraphicsView

Widget zur Anzeige des Inhalts einer QGraphicsScene

QGraphicsWidget

Die Basisklasse für alle Widgetelemente in einer QGraphicsScene

QStyleOptionGraphicsItem

Wird verwendet, um die Parameter zu beschreiben, die zum Zeichnen eines QGraphicsItems benötigt werden

Das Koordinatensystem der Grafikansicht

Die Grafikansicht basiert auf dem kartesischen Koordinatensystem; die Position und die Geometrie der Elemente in der Szene werden durch eine Menge von zwei Zahlen dargestellt: die x-Koordinate und die y-Koordinate. Bei der Betrachtung einer Szene mit einer untransformierten Ansicht wird eine Einheit der Szene durch ein Pixel auf dem Bildschirm dargestellt.

Hinweis: Das invertierte Y-Achsen-Koordinatensystem (bei dem y nach oben wächst) wird nicht unterstützt, da Graphics Views das Koordinatensystem von Qt verwendet.

Es gibt drei effektive Koordinatensysteme, die in der Grafikansicht zum Einsatz kommen: Objektkoordinaten, Szenenkoordinaten und Ansichtskoordinaten. Um Ihre Implementierung zu vereinfachen, bietet Graphics View Komfortfunktionen, die es Ihnen ermöglichen, zwischen den drei Koordinatensystemen zu mappen.

Beim Rendern entsprechen die Szenenkoordinaten der Grafikansicht den logischen Koordinaten von QPainter, und die Ansichtskoordinaten entsprechen den Gerätekoordinaten. In der Dokumentation zum Koordinatensystem können Sie die Beziehung zwischen logischen Koordinaten und Gerätekoordinaten nachlesen.

Element-Koordinaten

Elemente leben in ihrem eigenen lokalen Koordinatensystem. Ihre Koordinaten sind in der Regel um ihren Mittelpunkt (0, 0) zentriert, und dieser ist auch der Mittelpunkt für alle Transformationen. Geometrische Primitive im Objektkoordinatensystem werden oft als Objektpunkte, Objektlinien oder Objektrechtecke bezeichnet.

Bei der Erstellung eines benutzerdefinierten Objekts müssen Sie sich nur um die Objektkoordinaten kümmern; QGraphicsScene und QGraphicsView führen alle Transformationen für Sie durch. Dies macht es sehr einfach, benutzerdefinierte Elemente zu implementieren. Wenn Sie z. B. ein Mausklick- oder ein Drag-Enter-Ereignis erhalten, wird die Ereignisposition in Elementkoordinaten angegeben. Die virtuelle Funktion QGraphicsItem::contains(), die true zurückgibt, wenn sich ein bestimmter Punkt innerhalb Ihres Elements befindet, und andernfalls false, benötigt ein Punktargument in Elementkoordinaten. In ähnlicher Weise sind das Begrenzungsrechteck und die Form eines Elements in Elementkoordinaten angegeben.

Die Position eines Objekts ist die Koordinate des Mittelpunkts des Objekts im Koordinatensystem des übergeordneten Objekts; manchmal auch als übergeordnete Koordinaten bezeichnet. Die Szene wird in diesem Sinne als das "Elternteil" aller elternlosen Elemente betrachtet. Die Position der Elemente der obersten Ebene wird in Szenenkoordinaten angegeben.

Die Koordinaten der Kinder sind relativ zu den Koordinaten der Eltern. Wenn das Kind nicht transformiert ist, ist der Unterschied zwischen einer Kindkoordinate und einer Elternkoordinate derselbe wie der Abstand zwischen den Elementen in Elternkoordinaten. Ein Beispiel: Wenn ein nicht transformiertes untergeordnetes Element genau im Mittelpunkt des übergeordneten Elements positioniert ist, sind die Koordinatensysteme der beiden Elemente identisch. Wenn die Position des untergeordneten Elements jedoch (10, 0) ist, entspricht der Punkt (0, 10) des untergeordneten Elements dem Punkt (10, 10) des übergeordneten Elements.

Da die Position und die Transformation der Elemente relativ zum übergeordneten Element sind, werden die Koordinaten der untergeordneten Elemente von der Transformation des übergeordneten Elements nicht beeinflusst, obwohl die Transformation des übergeordneten Elements implizit auch das untergeordnete Element transformiert. Im obigen Beispiel entspricht der Punkt (0, 10) des untergeordneten Elements immer noch dem Punkt (10, 10) des übergeordneten Elements, selbst wenn das übergeordnete Element gedreht und skaliert wird. In Bezug auf die Szene folgt das Kind jedoch der Transformation und Position des Elternteils. Wenn das Elternteil skaliert wird (2x, 2x), befindet sich die Position des Kinds an der Szenenkoordinate (20, 0), und sein (10, 0)-Punkt entspricht dem Punkt (40, 0) auf der Szene.

Mit QGraphicsItem::pos() als eine der wenigen Ausnahmen arbeiten die Funktionen von QGraphicsItem in Elementkoordinaten, unabhängig vom Element oder der Transformation seiner Eltern. So wird beispielsweise das Begrenzungsrechteck eines Gegenstands (d. h. QGraphicsItem::boundingRect()) immer in Gegenstandskoordinaten angegeben.

Szenenkoordinaten

Die Szene stellt das Basiskoordinatensystem für alle Elemente dar. Das Szenenkoordinatensystem beschreibt die Position jedes Elements der obersten Ebene und bildet auch die Grundlage für alle Szenenereignisse, die von der Ansicht an die Szene geliefert werden. Jedes Element in der Szene hat eine Szenenposition und ein Begrenzungsrechteck (QGraphicsItem::scenePos(), QGraphicsItem::sceneBoundingRect()), zusätzlich zu seiner lokalen Elementposition und seinem Begrenzungsrechteck. Die Szenenposition beschreibt die Position des Objekts in Szenenkoordinaten, und das Begrenzungsrechteck der Szene bildet die Grundlage dafür, wie QGraphicsScene feststellt, welche Bereiche der Szene sich geändert haben. Änderungen in der Szene werden durch das Signal QGraphicsScene::changed() mitgeteilt, und das Argument ist eine Liste von Szenerechtecken.

Ansichtskoordinaten

Ansichtskoordinaten sind die Koordinaten des Widgets. Jede Einheit in Ansichtskoordinaten entspricht einem Pixel. Das Besondere an diesem Koordinatensystem ist, dass es relativ zum Widget oder Viewport ist und nicht von der beobachteten Szene beeinflusst wird. Die obere linke Ecke des Ansichtsfensters von QGraphicsView ist immer (0, 0), und die untere rechte Ecke ist immer (Breite des Ansichtsfensters, Höhe des Ansichtsfensters). Alle Mausereignisse und Drag&Drop-Ereignisse werden ursprünglich als Ansichtskoordinaten empfangen, und Sie müssen diese Koordinaten auf die Szene abbilden, um mit den Elementen interagieren zu können.

Koordinaten-Mapping

Beim Umgang mit Objekten in einer Szene kann es oft nützlich sein, Koordinaten und beliebige Formen von der Szene auf ein Objekt, von Objekt zu Objekt oder von der Ansicht auf die Szene zu übertragen. Wenn Sie zum Beispiel mit der Maus in das Ansichtsfenster von QGraphicsView klicken, können Sie die Szene fragen, welches Element sich unter dem Cursor befindet, indem Sie QGraphicsView::mapToScene() aufrufen, gefolgt von QGraphicsScene::itemAt(). Wenn Sie wissen wollen, wo im Ansichtsfenster sich ein Element befindet, können Sie QGraphicsItem::mapToScene() für das Element und dann QGraphicsView::mapFromScene() für die Ansicht aufrufen. Wenn Sie herausfinden möchten, welche Elemente sich innerhalb einer Ansichtsellipse befinden, können Sie QPainterPath an mapToScene() übergeben und dann den zugeordneten Pfad an QGraphicsScene::items() übergeben.

Durch die Aufrufe QGraphicsItem::mapToScene() und QGraphicsItem::mapFromScene() können Sie Koordinaten und Formen auf die Szene eines Objekts abbilden. Sie können auch auf das übergeordnete Element eines Elements abbilden, indem Sie QGraphicsItem::mapToParent() und QGraphicsItem::mapFromParent() aufrufen, oder zwischen Elementen, indem Sie QGraphicsItem::mapToItem() und QGraphicsItem::mapFromItem() aufrufen. Alle Mapping-Funktionen können sowohl Punkte, Rechtecke, Polygone als auch Pfade abbilden.

Die gleichen Mapping-Funktionen stehen auch in der Ansicht für das Mapping in und aus der Szene zur Verfügung. QGraphicsView::mapFromScene() und QGraphicsView::mapToScene(). Um von einer Ansicht auf ein Element zu mappen, mappen Sie zuerst auf die Szene und dann von der Szene auf das Element.

Hauptmerkmale

Zoomen und Drehen

QGraphicsView unterstützt die gleichen affinen Transformationen wie QPainter durch QGraphicsView::setMatrix(). Indem Sie eine Transformation auf die Ansicht anwenden, können Sie einfach Unterstützung für gängige Navigationsfunktionen wie Zoomen und Drehen hinzufügen.

Hier ist ein Beispiel für die Implementierung von Zoom- und Rotationsslots in einer Unterklasse von QGraphicsView:

class View : public QGraphicsView
{
Q_OBJECT
    ...
public slots:
    void zoomIn() { scale(1.2, 1.2); }
    void zoomOut() { scale(1 / 1.2, 1 / 1.2); }
    void rotateLeft() { rotate(-10); }
    void rotateRight() { rotate(10); }
    ...
};

Die Slots könnten mit QToolButtons verbunden werden, wenn autoRepeat aktiviert ist.

QGraphicsView hält das Zentrum der Ansicht ausgerichtet, wenn Sie die Ansicht transformieren.

Siehe auch das Beispiel Elastic Nodes für Code, der zeigt, wie man grundlegende Zoomfunktionen implementiert.

Drucken

Die Grafikansicht ermöglicht das einzeilige Drucken über die Rendering-Funktionen QGraphicsScene::render() und QGraphicsView::render(). Die Funktionen bieten die gleiche API: Sie können die Szene oder den View ganz oder teilweise auf ein beliebiges Zeichengerät rendern lassen, indem Sie eine QPainter an eine der Rendering-Funktionen übergeben. Dieses Beispiel zeigt, wie man die gesamte Szene mit QPrinter auf einer ganzen Seite ausgibt.

QGraphicsScene scene;
QPrinter printer;
scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green));

if (QPrintDialog(&printer).exec() == QDialog::Accepted) {
    QPainter painter(&printer);
    painter.setRenderHint(QPainter::Antialiasing);
    scene.render(&painter);
}

Der Unterschied zwischen den Rendering-Funktionen für Szenen und Ansichten besteht darin, dass die eine in Szenenkoordinaten und die andere in Ansichtskoordinaten arbeitet. QGraphicsScene::render() wird oft bevorzugt, um ganze Segmente einer Szene untransformiert zu drucken, z.B. zum Plotten geometrischer Daten oder zum Drucken eines Textdokuments. QGraphicsView::render() hingegen eignet sich für die Erstellung von Screenshots; standardmäßig wird der exakte Inhalt des Ansichtsfensters mit Hilfe des mitgelieferten Malers wiedergegeben.

QGraphicsScene scene;
scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green));

QPixmap pixmap;
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();

pixmap.save("scene.png");

Wenn die Größen von Quell- und Zielbereich nicht übereinstimmen, wird der Quellinhalt gestreckt, damit er in den Zielbereich passt. Durch die Übergabe einer Qt::AspectRatioMode an die verwendete Rendering-Funktion können Sie wählen, ob das Seitenverhältnis der Szene beibehalten oder ignoriert werden soll, wenn der Inhalt gestreckt wird.

Ziehen und Ablegen

Da QGraphicsView indirekt von QWidget erbt, bietet es bereits die gleichen Drag-and-Drop-Funktionen wie QWidget. Darüber hinaus bietet das Graphics View Framework Drag-and-Drop-Unterstützung für die Szene und für jedes einzelne Element. Wenn die Ansicht ein Ziehen empfängt, übersetzt sie die Ziehen-und-Ablegen-Ereignisse in ein QGraphicsSceneDragDropEvent, das dann an die Szene weitergeleitet wird. Die Szene übernimmt die Planung dieses Ereignisses und sendet es an das erste Element unter dem Mauszeiger, das das Ziehen akzeptiert.

Um ein Ziehen von einem Element aus zu starten, erstellen Sie ein QDrag -Objekt und übergeben einen Zeiger an das Widget, das das Ziehen startet. Elemente können von vielen Ansichten gleichzeitig beobachtet werden, aber nur eine Ansicht kann das Ziehen starten. Ziehvorgänge werden in den meisten Fällen durch Drücken oder Bewegen der Maus ausgelöst, so dass Sie in mousePressEvent() oder mouseMoveEvent() den Zeiger des verursachenden Widgets aus dem Ereignis erhalten können. Zum Beispiel:

void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    QMimeData *data = new QMimeData;
    QDrag *drag = new QDrag(event->widget());
    drag->setMimeData(data);
    drag->exec();
}

Um Drag&Drop-Ereignisse für die Szene abzufangen, implementieren Sie QGraphicsScene::dragEnterEvent() und die Ereignisbehandler, die Ihre spezielle Szene benötigt, in einer QGraphicsItem Unterklasse. Weitere Informationen zum Ziehen und Ablegen in der Grafikansicht finden Sie in der Dokumentation zu den einzelnen Ereignishandlern von QGraphicsScene.

Elemente können die Unterstützung von Drag & Drop durch den Aufruf von QGraphicsItem::setAcceptDrops() aktivieren. Um das eingehende Ziehen zu behandeln, implementieren Sie QGraphicsItem::dragEnterEvent(), QGraphicsItem::dragMoveEvent(), QGraphicsItem::dragLeaveEvent() und QGraphicsItem::dropEvent() neu.

Siehe auch das Drag and Drop Robot-Beispiel für eine Demonstration der Unterstützung von Drag and Drop-Operationen durch die Grafikansicht.

Cursor und Tooltips

Wie QWidget unterstützt auch QGraphicsItem Cursor (QGraphicsItem::setCursor()) und QuickInfos (QGraphicsItem::setToolTip()). Die Cursor und Tooltips werden von QGraphicsView aktiviert, sobald der Mauszeiger in den Bereich des Elements eintritt (dies wird durch den Aufruf von QGraphicsItem::contains() erkannt).

Sie können auch einen Standardcursor direkt in der Ansicht festlegen, indem Sie QGraphicsView::setCursor() aufrufen.

Siehe auch das Drag-and-Drop-Roboter-Beispiel für Code, der Tooltips und die Handhabung der Cursorform implementiert.

Animation

Die Grafikansicht unterstützt Animationen auf mehreren Ebenen. Mit Hilfe des Animation Frameworks können Sie Animationen einfach zusammenstellen. Dazu müssen Sie Ihre Elemente von QGraphicsObject erben und QPropertyAnimation mit ihnen verknüpfen. QPropertyAnimation ermöglicht die Animation jeder Eigenschaft von QObject.

Eine andere Möglichkeit besteht darin, ein benutzerdefiniertes Element zu erstellen, das von QObject und QGraphicsItem erbt. Das Element kann seine eigenen Zeitgeber einrichten und Animationen mit inkrementellen Schritten in QObject::timerEvent() steuern.

Eine dritte Möglichkeit, die vor allem aus Gründen der Kompatibilität mit QCanvas in Qt 3 zur Verfügung steht, besteht darin, die Szene durch den Aufruf von QGraphicsScene::advance() voranzutreiben, das wiederum QGraphicsItem::advance() aufruft.

OpenGL-Rendering

Um OpenGL-Rendering zu aktivieren, setzen Sie einfach ein neues QOpenGLWidget als Viewport von QGraphicsView durch Aufruf von QGraphicsView::setViewport(). Wenn Sie OpenGL mit Antialiasing wünschen, müssen Sie ein QSurfaceFormat mit der erforderlichen Anzahl von Samples setzen (siehe QSurfaceFormat::setSamples()).

Beispiel:

QGraphicsView view(&scene);
QOpenGLWidget *gl = new QOpenGLWidget();
QSurfaceFormat format;
format.setSamples(4);
gl->setFormat(format);
view.setViewport(gl);

Elementgruppen

Indem Sie ein Element zu einem Kind eines anderen machen, können Sie die wichtigste Eigenschaft der Elementgruppierung erreichen: Die Elemente bewegen sich gemeinsam, und alle Transformationen werden vom Elternteil zum Kind übertragen.

Darüber hinaus ist QGraphicsItemGroup ein spezielles Element, das die Behandlung von Kind-Ereignissen mit einer nützlichen Schnittstelle zum Hinzufügen und Entfernen von Elementen zu und aus einer Gruppe kombiniert. Das Hinzufügen eines Elements zu QGraphicsItemGroup behält die ursprüngliche Position und Transformation des Elements bei, während das Reparenting von Elementen im Allgemeinen dazu führt, dass sich das Child relativ zu seinem neuen Parent neu positioniert. Der Einfachheit halber können Sie QGraphicsItemGroupdurch die Szene erstellen, indem Sie QGraphicsScene::createItemGroup() aufrufen.

Widgets und Layouts

Mit Qt 4.4 wurde die Unterstützung für geometrie- und layoutfähige Elemente durch QGraphicsWidget eingeführt. Dieses spezielle Basiselement ist ähnlich wie QWidget, aber im Gegensatz zu QWidget erbt es nicht von QPaintDevice, sondern von QGraphicsItem. Dies erlaubt Ihnen, komplette Widgets mit Ereignissen, Signalen & Slots, Größenhinweisen und Richtlinien zu schreiben, und Sie können auch die Geometrien Ihrer Widgets in Layouts über QGraphicsLinearLayout und QGraphicsGridLayout verwalten.

QGraphicsWidget

Aufbauend auf den Fähigkeiten und dem schlanken Footprint von QGraphicsItem bietet QGraphicsWidget das Beste aus beiden Welten: zusätzliche Funktionalität von QWidget, wie z.B. Stil, Schriftart, Palette, Layoutrichtung und deren Geometrie, und Auflösungsunabhängigkeit und Transformationsunterstützung von QGraphicsItem. Da die Grafikansicht reelle Koordinaten anstelle von Ganzzahlen verwendet, arbeiten die Geometriefunktionen von QGraphicsWidget auch auf QRectF und QPointF. Dies gilt auch für Rahmenbereiche, Ränder und Abstände. Bei QGraphicsWidget ist es nicht unüblich, z. B. Inhaltsränder von (0,5, 0,5, 0,5, 0,5) anzugeben. Sie können sowohl Subwidgets als auch "Top-Level"-Fenster erstellen; in einigen Fällen können Sie jetzt die Grafikansicht für fortgeschrittene MDI-Anwendungen verwenden.

Einige der Eigenschaften von QWidget werden unterstützt, darunter Fensterflags und -attribute, aber nicht alle. Einen vollständigen Überblick darüber, was unterstützt wird und was nicht, finden Sie in der Klassendokumentation von QGraphicsWidget. Sie können zum Beispiel dekorierte Fenster erstellen, indem Sie das Fensterflag Qt::Window an den Konstruktor von QGraphicsWidget übergeben, aber Graphics View unterstützt derzeit nicht die Flags Qt::Sheet und Qt::Drawer, die unter macOS üblich sind.

QGraphicsLayout

QGraphicsLayout ist Teil eines Layout-Frameworks der zweiten Generation, das speziell für QGraphicsWidget entwickelt wurde. Seine API ist der von QLayout sehr ähnlich. Sie können Widgets und Sublayouts entweder innerhalb von QGraphicsLinearLayout oder QGraphicsGridLayout verwalten. Sie können auch einfach Ihr eigenes Layout schreiben, indem Sie QGraphicsLayout selbst unterklassifizieren oder Ihre eigenen QGraphicsItem Elemente zum Layout hinzufügen, indem Sie eine Adaptor-Unterklasse von QGraphicsLayoutItem schreiben.

Unterstützung für eingebettete Widgets

Graphics View bietet nahtlose Unterstützung für die Einbettung beliebiger Widgets in die Szene. Sie können einfache Widgets, wie z. B. QLineEdit oder QPushButton, komplexe Widgets, wie z. B. QTabWidget, und sogar komplette Hauptfenster einbetten. Um Ihr Widget in die Szene einzubetten, rufen Sie einfach QGraphicsScene::addWidget() auf, oder erstellen Sie eine Instanz von QGraphicsProxyWidget, um Ihr Widget manuell einzubetten.

Durch QGraphicsProxyWidget ist Graphics View in der Lage, die Funktionen des Client-Widgets tiefgreifend zu integrieren, einschließlich der Cursor, QuickInfos, Maus-, Tablett- und Tastaturereignisse, untergeordneter Widgets, Animationen, Popups (z. B. QComboBox oder QCompleter) sowie des Eingabefokus und der Aktivierung des Widgets. QGraphicsProxyWidget integriert sogar die Tabulatorreihenfolge des eingebetteten Widgets, so dass Sie mit der Tabulatortaste in eingebettete Widgets ein- und aussteigen können. Sie können sogar ein neues QGraphicsView in Ihre Szene einbetten, um komplexe verschachtelte Szenen zu erstellen.

Beim Transformieren eines eingebetteten Widgets stellt die Grafikansicht sicher, dass das Widget auflösungsunabhängig transformiert wird, so dass die Schriftarten und der Stil auch beim Vergrößern scharf bleiben. (Beachten Sie, dass der Effekt der Auflösungsunabhängigkeit vom Stil abhängt).

Leistung

Fließkomma-Anweisungen

Um Transformationen und Effekte präzise und schnell auf Elemente anwenden zu können, wird bei der Entwicklung von Graphics View davon ausgegangen, dass die Hardware des Benutzers eine angemessene Leistung für Fließkomma-Befehle erbringen kann.

Viele Workstations und Desktop-Computer sind mit geeigneter Hardware ausgestattet, um diese Art von Berechnungen zu beschleunigen, aber einige eingebettete Geräte bieten möglicherweise nur Bibliotheken zur Verarbeitung mathematischer Operationen oder emulieren Fließkommaanweisungen in Software.

Infolgedessen können bestimmte Arten von Effekten auf bestimmten Geräten langsamer sein als erwartet. Es kann möglich sein, diese Leistungseinbußen durch Optimierungen in anderen Bereichen auszugleichen, z. B. durch die Verwendung von OpenGL zum Rendern einer Szene. Derartige Optimierungen können jedoch selbst zu einer Leistungsverringerung führen, wenn sie sich auf das Vorhandensein von Fließkommahardware stützen.

© 2025 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.