这是用户在 2024-5-7 22:20 为 https://doc.qt.io/qt-5/graphicsview.html#the-scene 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?

Graphics View Framework 图形视图框架

Graphics View provides a surface for managing and interacting with a large number of custom-made 2D graphical items, and a view widget for visualizing the items, with support for zooming and rotation.
图形视图提供了一个表面,用于管理和与大量自定义的 2D 图形项交互,并提供了一个视图小部件用于可视化这些项,支持缩放和旋转。

The framework includes an event propagation architecture that allows precise double-precision interaction capabilities for the items on the scene. Items can handle key events, mouse press, move, release and double click events, and they can also track mouse movement.
该框架包括一个事件传播架构,允许对场景上的项目进行精确的双精度交互。项目可以处理键事件、鼠标按下、移动、释放和双击事件,它们还可以跟踪鼠标移动。

Graphics View uses a BSP (Binary Space Partitioning) tree to provide very fast item discovery, and as a result of this, it can visualize large scenes in real-time, even with millions of items.
图形视图使用 BSP(二进制空间划分)树提供非常快速的项目发现,并且由于此,它可以实时可视化大型场景,即使有数百万个项目也可以。

Graphics View was introduced in Qt 4.2, replacing its predecessor, QCanvas.
图形视图在 Qt 4.2 中引入,取代了它的前身 QCanvas。

Topics: 主题:

The Graphics View Architecture
图形视图架构

Graphics View provides an item-based approach to model-view programming, much like InterView's convenience classes QTableView, QTreeView and QListView. Several views can observe a single scene, and the scene contains items of varying geometric shapes.
图形视图提供了一种基于项的模型视图编程方法,类似于 InterView 的便利类 QTableView、QTreeView 和 QListView。几个视图可以观察单个场景,并且场景包含各种几何形状的项。

The Scene 场景

QGraphicsScene provides the Graphics View scene. The scene has the following responsibilities:
QGraphicsScene 提供了图形视图场景。场景具有以下职责:

  • Providing a fast interface for managing a large number of items
    提供一个快速接口来管理大量项目
  • Propagating events to each item
    将事件传播到每个项目
  • Managing item state, such as selection and focus handling
    管理项目状态,如选择和焦点处理
  • Providing untransformed rendering functionality; mainly for printing
    提供未转换的渲染功能;主要用于打印

The scene serves as a container for QGraphicsItem objects. Items are added to the scene by calling QGraphicsScene::addItem(), and then retrieved by calling one of the many item discovery functions. QGraphicsScene::items() and its overloads return all items contained by or intersecting with a point, a rectangle, a polygon or a general vector path. QGraphicsScene::itemAt() returns the topmost item at a particular point. All item discovery functions return the items in descending stacking order (i.e., the first returned item is topmost, and the last item is bottom-most).
场景用作 QGraphicsItem 对象的容器。通过调用 QGraphicsScene::addItem() 将项目添加到场景中,然后通过调用许多项目发现功能之一来检索它们。QGraphicsScene::items() 及其重载返回由点、矩形、多边形或一般向量路径包含或相交的所有项目。QGraphicsScene::itemAt() 返回特定点的顶部项目。所有项目发现功能以降序堆叠顺序返回项目(即,第一个返回的项目最上面,最后一个项目最下面)。

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

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

QGraphicsScene's event propagation architecture schedules scene events for delivery to items, and also manages propagation between items. If the scene receives a mouse press event at a certain position, the scene passes the event on to whichever item is at that position.
QGraphicsScene 的事件传播架构安排场景事件以传递给项目,并管理项目之间的传播。如果场景在某个位置收到鼠标按下事件,则将事件传递给该位置的项目。

QGraphicsScene also manages certain item states, such as item selection and focus. You can select items on the scene by calling QGraphicsScene::setSelectionArea(), passing an arbitrary shape. This functionality is also used as a basis for rubberband selection in QGraphicsView. To get the list of all currently selected items, call QGraphicsScene::selectedItems(). Another state handled by QGraphicsScene is whether or not an item has keyboard input focus. You can set focus on an item by calling QGraphicsScene::setFocusItem() or QGraphicsItem::setFocus(), or get the current focus item by calling QGraphicsScene::focusItem().
QGraphicsScene 还管理某些项状态,如项选择和焦点。您可以通过调用 QGraphicsScene::setSelectionArea() 并传递任意形状来选择场景中的项。这个功能也被用作 QGraphicsView 中的拉伸选择的基础。要获取当前所有选定项的列表,请调用 QGraphicsScene::selectedItems()。QGraphicsScene 处理的另一个状态是一个项是否具有键盘输入焦点。您可以通过调用 QGraphicsScene::setFocusItem() 或 QGraphicsItem::setFocus() 来设置项目焦点,或者通过调用 QGraphicsScene::focusItem() 来获取当前焦点项。

Finally, QGraphicsScene allows you to render parts of the scene into a paint device through the QGraphicsScene::render() function. You can read more about this in the Printing section later in this document.
最后,QGraphicsScene 允许您通过 QGraphicsScene::render() 函数将场景的部分呈现到绘图设备中。您可以在本文档后面的打印部分中了解更多信息。

The View 视图

QGraphicsView provides the view widget, which visualizes the contents of a scene. You can attach several views to the same scene, to provide several viewports into the same data set. The view widget is a scroll area, and provides scroll bars for navigating through large scenes. To enable OpenGL support, you can set a QOpenGLWidget as the viewport by calling QGraphicsView::setViewport().
QGraphicsView 提供视图部件,用于可视化场景的内容。您可以将多个视图附加到同一个场景,以提供对同一数据集的多个视口。视图部件是一个滚动区域,并提供滚动条以浏览大型场景。要启用 OpenGL 支持,您可以通过调用 QGraphicsView::setViewport()将 QOpenGLWidget 设置为视口。

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

The view receives input events from the keyboard and mouse, and translates these to scene events (converting the coordinates used to scene coordinates where appropriate), before sending the events to the visualized scene.
该视图从键盘和鼠标接收输入事件,并将它们转换为场景事件(在适当的情况下将使用的坐标转换为场景坐标),然后将事件发送到可视化场景。

Using its transformation matrix, QGraphicsView::transform(), the view can transform the scene's coordinate system. This allows advanced navigation features such as zooming and rotation. For convenience, QGraphicsView also provides functions for translating between view and scene coordinates: QGraphicsView::mapToScene() and QGraphicsView::mapFromScene().
利用其变换矩阵,QGraphicsView::transform(),视图可以转换场景的坐标系。这使得实现高级导航功能成为可能,例如缩放和旋转。为了方便起见,QGraphicsView 还提供了在视图和场景坐标之间进行转换的函数:QGraphicsView::mapToScene() 和 QGraphicsView::mapFromScene()。

The Item 项目

QGraphicsItem is the base class for graphical items in a scene. Graphics View provides several standard items for typical shapes, such as rectangles (QGraphicsRectItem), ellipses (QGraphicsEllipseItem) and text items (QGraphicsTextItem), but the most powerful QGraphicsItem features are available when you write a custom item. Among other things, QGraphicsItem supports the following features:
QGraphicsItem 是场景中图形项的基类。Graphics View 提供了几个标准项用于典型形状,例如矩形(QGraphicsRectItem)、椭圆(QGraphicsEllipseItem)和文本项(QGraphicsTextItem),但当您编写自定义项时,最强大的 QGraphicsItem 功能可用。除其他外,QGraphicsItem 支持以下功能:

  • Mouse press, move, release and double click events, as well as mouse hover events, wheel events, and context menu events.
    鼠标按下、移动、释放和双击事件,以及鼠标悬停事件、滚轮事件和上下文菜单事件。
  • Keyboard input focus, and key events
    键盘输入焦点和键盘事件
  • Drag and drop 拖放
  • Grouping, both through parent-child relationships, and with QGraphicsItemGroup
    分组,既通过父子关系,也通过 QGraphicsItemGroup 进行分组
  • Collision detection 碰撞检测

Items live in a local coordinate system, and like QGraphicsView, it also provides many functions for mapping coordinates between the item and the scene, and from item to item. Also, like QGraphicsView, it can transform its coordinate system using a matrix: QGraphicsItem::transform(). This is useful for rotating and scaling individual items.
项目位于本地坐标系中,与 QGraphicsView 类似,它还提供了许多函数,用于在项目和场景之间以及项目之间映射坐标。此外,与 QGraphicsView 一样,它可以使用矩阵转换其坐标系:QGraphicsItem::transform()。这对于旋转和缩放单个项目非常有用。

Items can contain other items (children). Parent items' transformations are inherited by all its children. Regardless of an item's accumulated transformation, though, all its functions (e.g., QGraphicsItem::contains(), QGraphicsItem::boundingRect(), QGraphicsItem::collidesWith()) still operate in local coordinates.
项目可以包含其他项目(子项)。父项目的变换会被所有子项目继承。尽管项目累积的变换不同,但其所有函数(例如,QGraphicsItem::contains(),QGraphicsItem::boundingRect(),QGraphicsItem::collidesWith())仍在本地坐标中运行。

QGraphicsItem supports collision detection through the QGraphicsItem::shape() function, and QGraphicsItem::collidesWith(), which are both virtual functions. By returning your item's shape as a local coordinate QPainterPath from QGraphicsItem::shape(), QGraphicsItem will handle all collision detection for you. If you want to provide your own collision detection, however, you can reimplement QGraphicsItem::collidesWith().
QGraphicsItem 通过 QGraphicsItem::shape()函数和 QGraphicsItem::collidesWith()函数支持碰撞检测,这两个函数都是虚函数。通过从 QGraphicsItem::shape()返回局部坐标 QPainterPath 作为您的项目形状,QGraphicsItem 将为您处理所有碰撞检测。但是,如果要提供自己的碰撞检测,可以重新实现 QGraphicsItem::collidesWith()。

Classes in the Graphics View Framework
图形视图框架中的类

These classes provide a framework for creating interactive applications.
这些类提供了创建交互式应用程序的框架。

QAbstractGraphicsShapeItem

Common base for all path items
所有路径项的通用基础

QGraphicsAnchor

Represents an anchor between two items in a QGraphicsAnchorLayout
代表 QGraphicsAnchorLayout 中两个项目之间的锚点

QGraphicsAnchorLayout

Layout where one can anchor widgets together in Graphics View
一个可以在 Graphics View 中将小部件锚定在一起的布局

QGraphicsEffect

The base class for all graphics effects
所有图形效果的基类

QGraphicsEllipseItem

Ellipse item that you can add to a QGraphicsScene
椭圆项,您可以将其添加到 QGraphicsScene 中

QGraphicsGridLayout

Grid layout for managing widgets in Graphics View
用于在图形视图中管理小部件的网格布局

QGraphicsItem

The base class for all graphical items in a QGraphicsScene
QGraphicsScene 中所有图形项的基类

QGraphicsItemGroup

Container that treats a group of items as a single item
将一组项视为单个项的容器

QGraphicsLayout

The base class for all layouts in Graphics View
Graphics View 中所有布局的基类

QGraphicsLayoutItem

Can be inherited to allow your custom items to be managed by layouts
可以被继承,以允许您的自定义项由布局管理

QGraphicsLineItem

Line item that you can add to a QGraphicsScene
可以添加到 QGraphicsScene 的线条项

QGraphicsLinearLayout

Horizontal or vertical layout for managing widgets in Graphics View
在图形视图中管理小部件的水平或垂直布局

QGraphicsObject

Base class for all graphics items that require signals, slots and properties
所有需要信号、槽和属性的图形项的基类

QGraphicsPathItem

Path item that you can add to a QGraphicsScene
可以添加到 QGraphicsScene 中的路径项

QGraphicsPixmapItem

Pixmap item that you can add to a QGraphicsScene
您可以添加到 QGraphicsScene 的像素图项

QGraphicsPolygonItem

Polygon item that you can add to a QGraphicsScene
您可以添加到 QGraphicsScene 的多边形项

QGraphicsProxyWidget

Proxy layer for embedding a QWidget in a QGraphicsScene
用于在 QGraphicsScene 中嵌入 QWidget 的代理层

QGraphicsRectItem

Rectangle item that you can add to a QGraphicsScene
可添加到 QGraphicsScene 的矩形项

QGraphicsScene

Surface for managing a large number of 2D graphical items
用于管理大量 2D 图形项的表面

QGraphicsSceneContextMenuEvent

Context menu events in the graphics view framework
图形视图框架中的上下文菜单事件

QGraphicsSceneDragDropEvent

Events for drag and drop in the graphics view framework
图形视图框架中的拖放事件

QGraphicsSceneEvent

Base class for all graphics view related events
所有与图形视图相关的事件的基类

QGraphicsSceneHelpEvent

Events when a tooltip is requested
当请求工具提示时的事件

QGraphicsSceneHoverEvent

Hover events in the graphics view framework
图形视图框架中的悬停事件

QGraphicsSceneMouseEvent

Mouse events in the graphics view framework
图形视图框架中的鼠标事件

QGraphicsSceneMoveEvent

Events for widget moving in the graphics view framework
图形视图框架中小部件移动的事件

QGraphicsSceneResizeEvent

Events for widget resizing in the graphics view framework
在图形视图框架中用于调整小部件大小的事件

QGraphicsSceneWheelEvent

Wheel events in the graphics view framework
图形视图框架中的滚轮事件

QGraphicsSimpleTextItem

Simple text path item that you can add to a QGraphicsScene
简单文本路径项,可添加到 QGraphicsScene

QGraphicsSvgItem

QGraphicsItem that can be used to render the contents of SVG files
可用于渲染 SVG 文件内容的 QGraphicsItem

QGraphicsTextItem

Text item that you can add to a QGraphicsScene to display formatted text
您可以将其添加到 QGraphicsScene 以显示格式化文本的文本项

QGraphicsTransform

Abstract base class for building advanced transformations on QGraphicsItems
构建在 QGraphicsItems 上进行高级变换的抽象基类

QGraphicsView

Widget for displaying the contents of a QGraphicsScene
用于显示 QGraphicsScene 内容的小部件

QGraphicsWidget

The base class for all widget items in a QGraphicsScene
QGraphicsScene 中所有小部件项的基类

QStyleOptionGraphicsItem

Used to describe the parameters needed to draw a QGraphicsItem
用于描述绘制 QGraphicsItem 所需参数

The Graphics View Coordinate System
图形视图坐标系统

Graphics View is based on the Cartesian coordinate system; items' position and geometry on the scene are represented by sets of two numbers: the x-coordinate, and the y-coordinate. When observing a scene using an untransformed view, one unit on the scene is represented by one pixel on the screen.
图形视图基于笛卡尔坐标系;场景中项目的位置和几何形状由两个数字集表示:x 坐标和 y 坐标。当使用未转换的视图观察场景时,场景上的一个单位由屏幕上的一个像素表示。

Note: The inverted Y-axis coordinate system (where y grows upwards) is unsupported as Graphics Views uses Qt's coordinate system.
注意:不支持反转的 Y 轴坐标系(其中 y 向上增长),因为图形视图使用 Qt 的坐标系统。

There are three effective coordinate systems in play in Graphics View: Item coordinates, scene coordinates, and view coordinates. To simplify your implementation, Graphics View provides convenience functions that allow you to map between the three coordinate systems.
图形视图中存在三种有效的坐标系:项目坐标、场景坐标和视图坐标。为了简化您的实现,图形视图提供了方便的功能,允许您在这三种坐标系之间进行映射。

When rendering, Graphics View's scene coordinates correspond to QPainter's logical coordinates, and view coordinates are the same as device coordinates. In the Coordinate System documentation, you can read about the relationship between logical coordinates and device coordinates.
在渲染时,图形视图的场景坐标对应于 QPainter 的逻辑坐标,视图坐标与设备坐标相同。在坐标系文档中,您可以了解逻辑坐标和设备坐标之间的关系。

Item Coordinates 项目坐标

Items live in their own local coordinate system. Their coordinates are usually centered around its center point (0, 0), and this is also the center for all transformations. Geometric primitives in the item coordinate system are often referred to as item points, item lines, or item rectangles.
物品位于其自己的本地坐标系统中。它们的坐标通常围绕其中心点(0,0)居中,并且这也是所有转换的中心。项目坐标系中的几何原语通常被称为项目点、项目线或项目矩形。

When creating a custom item, item coordinates are all you need to worry about; QGraphicsScene and QGraphicsView will perform all transformations for you. This makes it very easy to implement custom items. For example, if you receive a mouse press or a drag enter event, the event position is given in item coordinates. The QGraphicsItem::contains() virtual function, which returns true if a certain point is inside your item, and false otherwise, takes a point argument in item coordinates. Similarly, an item's bounding rect and shape are in item coordinates.
当创建自定义项目时,项目坐标是您唯一需要担心的事情;QGraphicsScene 和 QGraphicsView 将为您执行所有转换。这使得实现自定义项目非常容易。例如,如果您接收到鼠标按下或拖动输入事件,则事件位置以项目坐标给出。QGraphicsItem::contains() 虚拟函数返回如果某个点在您的项目内部,则返回 true ,否则返回 false,它以项目坐标为参数。类似地,项目的边界矩形和形状都是以项目坐标为单位的。

At item's position is the coordinate of the item's center point in its parent's coordinate system; sometimes referred to as parent coordinates. The scene is in this sense regarded as all parent-less items' "parent". Top level items' position are in scene coordinates.
在项目的位置是项目在其父级坐标系统中的中心点坐标;有时被称为父坐标。从这个意义上说,场景被视为所有无父项的项的“父项”。顶级项目的位置以场景坐标表示。

Child coordinates are relative to the parent's coordinates. If the child is untransformed, the difference between a child coordinate and a parent coordinate is the same as the distance between the items in parent coordinates. For example: If an untransformed child item is positioned precisely in its parent's center point, then the two items' coordinate systems will be identical. If the child's position is (10, 0), however, the child's (0, 10) point will correspond to its parent's (10, 10) point.
子坐标相对于父坐标。 如果子项未经转换,则子坐标与父坐标之间的差异与父坐标中项目之间的距离相同。 例如:如果未经转换的子项精确地位于其父项的中心点,则两个项的坐标系统将相同。 但是,如果子项的位置为(10,0),则子项的(0,10)点将对应于其父项的(10,10)点。

Because items' position and transformation are relative to the parent, child items' coordinates are unaffected by the parent's transformation, although the parent's transformation implicitly transforms the child. In the above example, even if the parent is rotated and scaled, the child's (0, 10) point will still correspond to the parent's (10, 10) point. Relative to the scene, however, the child will follow the parent's transformation and position. If the parent is scaled (2x, 2x), the child's position will be at scene coordinate (20, 0), and its (10, 0) point will correspond to the point (40, 0) on the scene.
因为项目的位置和变换是相对于父项的,所以子项的坐标不受父项变换的影响,尽管父项的变换隐式地转换了子项。 在上面的例子中,即使父项被旋转和缩放,子项的(0,10)点仍然会对应于父项的(10,10)点。 但是,相对于场景,子项将遵循父项的变换和位置。 如果父项被缩放(2x,2x),则子项的位置将位于场景坐标(20,0),其(10,0)点将对应于场景上点(40,0)。

With QGraphicsItem::pos() being one of the few exceptions, QGraphicsItem's functions operate in item coordinates, regardless of the item, or any of its parents' transformation. For example, an item's bounding rect (i.e. QGraphicsItem::boundingRect()) is always given in item coordinates.
使用 QGraphicsItem :: pos()作为为数不多的例外情况之一,QGraphicsItem 的函数在项目坐标中运行,而不考虑项目或其任何父级转换。例如,项目的边界矩形(即 QGraphicsItem :: boundingRect())总是以项目坐标给出。

Scene Coordinates 场景坐标

The scene represents the base coordinate system for all its items. The scene coordinate system describes the position of each top-level item, and also forms the basis for all scene events delivered to the scene from the view. Each item on the scene has a scene position and bounding rectangle (QGraphicsItem::scenePos(), QGraphicsItem::sceneBoundingRect()), in addition to its local item pos and bounding rectangle. The scene position describes the item's position in scene coordinates, and its scene bounding rect forms the basis for how QGraphicsScene determines what areas of the scene have changed. Changes in the scene are communicated through the QGraphicsScene::changed() signal, and the argument is a list of scene rectangles.
场景表示所有项的基本坐标系统。场景坐标系统描述每个顶级项的位置,并且也构成从视图传递给场景的所有场景事件的基础。场景中的每个项都有一个场景位置和边界矩形(QGraphicsItem::scenePos(),QGraphicsItem::sceneBoundingRect()),以及其本地项位置和边界矩形。场景位置描述了项在场景坐标中的位置,其场景边界矩形构成了 QGraphicsScene 确定场景哪些区域发生了变化的依据。场景中的更改通过 QGraphicsScene::changed()信号进行通信,参数是场景矩形的列表。

View Coordinates 视图坐标

View coordinates are the coordinates of the widget. Each unit in view coordinates corresponds to one pixel. What's special about this coordinate system is that it is relative to the widget, or viewport, and unaffected by the observed scene. The top left corner of QGraphicsView's viewport is always (0, 0), and the bottom right corner is always (viewport width, viewport height). All mouse events and drag and drop events are originally received as view coordinates, and you need to map these coordinates to the scene in order to interact with items.
视图坐标是小部件的坐标。 视图坐标中的每个单位对应一个像素。 这个坐标系统的特殊之处在于它相对于小部件或视口,并且不受观察场景的影响。 QGraphicsView 视口的左上角始终是 (0, 0),右下角始终是 (视口宽度,视口高度)。 所有鼠标事件和拖放事件最初都以视图坐标接收,您需要将这些坐标映射到场景中以与项进行交互。

Coordinate Mapping 坐标映射

Often when dealing with items in a scene, it can be useful to map coordinates and arbitrary shapes from the scene to an item, from item to item, or from the view to the scene. For example, when you click your mouse in QGraphicsView's viewport, you can ask the scene what item is under the cursor by calling QGraphicsView::mapToScene(), followed by QGraphicsScene::itemAt(). If you want to know where in the viewport an item is located, you can call QGraphicsItem::mapToScene() on the item, then QGraphicsView::mapFromScene() on the view. Finally, if you use want to find what items are inside a view ellipse, you can pass a QPainterPath to mapToScene(), and then pass the mapped path to QGraphicsScene::items().
在处理场景中的项目时,通常可以将坐标和任意形状从场景映射到项目,从项目到项目,或从视图到场景都是很有用的。例如,当您在 QGraphicsView 的视口中单击鼠标时,您可以通过调用 QGraphicsView::mapToScene(),然后调用 QGraphicsScene::itemAt() 来询问场景在光标下的是哪个项目。如果您想知道项目在视口中的位置,您可以在项目上调用 QGraphicsItem::mapToScene(),然后在视图上调用 QGraphicsView::mapFromScene()。最后,如果您想要找出哪些项目在视图椭圆内,您可以将 QPainterPath 传递给 mapToScene(),然后将映射路径传递给 QGraphicsScene::items()。

You can map coordinates and shapes to and from an item's scene by calling QGraphicsItem::mapToScene() and QGraphicsItem::mapFromScene(). You can also map to an item's parent item by calling QGraphicsItem::mapToParent() and QGraphicsItem::mapFromParent(), or between items by calling QGraphicsItem::mapToItem() and QGraphicsItem::mapFromItem(). All mapping functions can map both points, rectangles, polygons and paths.
您可以通过调用 QGraphicsItem::mapToScene() 和 QGraphicsItem::mapFromScene() 将坐标和形状映射到项目的场景中。您还可以通过调用 QGraphicsItem::mapToParent() 和 QGraphicsItem::mapFromParent() 将映射到项目的父项目,或者通过调用 QGraphicsItem::mapToItem() 和 QGraphicsItem::mapFromItem() 在项目之间进行映射。所有映射函数都可以映射点、矩形、多边形和路径。

The same mapping functions are available in the view, for mapping to and from the scene. QGraphicsView::mapFromScene() and QGraphicsView::mapToScene(). To map from a view to an item, you first map to the scene, and then map from the scene to the item.
视图中提供了相同的映射功能,用于在场景之间进行映射。QGraphicsView::mapFromScene() 和 QGraphicsView::mapToScene()。要将视图映射到项,您首先要映射到场景,然后从场景映射到项。

Key Features 主要特点

Zooming and rotating 缩放和旋转

QGraphicsView supports the same affine transformations as QPainter does through QGraphicsView::setMatrix(). By applying a transformation to the view, you can easily add support for common navigation features such as zooming and rotating.
QGraphicsView 通过 QGraphicsView::setMatrix()支持与 QPainter 相同的仿射变换。通过对视图应用变换,您可以轻松添加对常见导航功能(如缩放和旋转)的支持。

Here is an example of how to implement zoom and rotate slots in a subclass of QGraphicsView:
以下是如何在 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); }
    ...
};

The slots could be connected to QToolButtons with autoRepeat enabled.
插槽可以连接到启用了自动重复的 QToolButtons。

QGraphicsView keeps the center of the view aligned when you transform the view.
QGraphicsView 在您转换视图时保持视图中心对齐。

See also the Elastic Nodes example for code that shows how to implement basic zooming features.
另请参阅弹性节点示例,了解如何实现基本缩放功能的代码。

Printing 打印

Graphics View provides single-line printing through its rendering functions, QGraphicsScene::render() and QGraphicsView::render(). The functions provide the same API: You can have the scene or the view render all or parts of their contents into any paint device by passing a QPainter to either of the rendering functions. This example shows how to print the whole scene into a full page, using QPrinter.
Graphics View 通过其渲染函数提供单行打印,包括 QGraphicsScene::render()和 QGraphicsView::render()。这些函数提供相同的 API:通过将 QPainter 传递给任一渲染函数,您可以使场景或视图将其全部或部分内容渲染到任何绘图设备中。此示例显示了如何使用 QPrinter 将整个场景打印到整个页面。

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);
}

The difference between the scene and view rendering functions is that one operates in scene coordinates, and the other in view coordinates. QGraphicsScene::render() is often preferred for printing whole segments of a scene untransformed, such as for plotting geometrical data, or for printing a text document. QGraphicsView::render(), on the other hand, is suitable for taking screenshots; its default behavior is to render the exact contents of the viewport using the provided painter.
场景和视图渲染函数之间的区别在于,一个在场景坐标中操作,另一个在视图坐标中操作。QGraphicsScene::render()通常用于打印场景的整个部分而不经变换,例如用于绘制几何数据或打印文本文档。另一方面,QGraphicsView::render()适用于截图;其默认行为是使用提供的绘图器渲染视口的确切内容。

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");

When the source and target areas' sizes do not match, the source contents are stretched to fit into the target area. By passing a Qt::AspectRatioMode to the rendering function you are using, you can choose to maintain or ignore the aspect ratio of the scene when the contents are stretched.
当源和目标区域的大小不匹配时,源内容将被拉伸以适应目标区域。通过将 Qt::AspectRatioMode 传递给您正在使用的渲染函数,您可以选择在内容被拉伸时保持或忽略场景的宽高比。

Drag and Drop 拖放

Because QGraphicsView inherits QWidget indirectly, it already provides the same drag and drop functionality that QWidget provides. In addition, as a convenience, the Graphics View framework provides drag and drop support for the scene, and for each and every item. As the view receives a drag, it translates the drag and drop events into a QGraphicsSceneDragDropEvent, which is then forwarded to the scene. The scene takes over scheduling of this event, and sends it to the first item under the mouse cursor that accepts drops.
因为 QGraphicsView 间接继承自 QWidget,所以它已经提供了与 QWidget 相同的拖放功能。此外,作为便利,图形视图框架为场景和每个项目提供了拖放支持。当视图接收到拖放时,它将拖放事件转换为 QGraphicsSceneDragDropEvent,然后将其转发到场景。场景接管了此事件的调度,并将其发送到鼠标光标下接受拖放的第一个项目。

To start a drag from an item, create a QDrag object, passing a pointer to the widget that starts the drag. Items can be observed by many views at the same time, but only one view can start the drag. Drags are in most cases started as a result of pressing or moving the mouse, so in mousePressEvent() or mouseMoveEvent(), you can get the originating widget pointer from the event. For example:
要从项目开始拖动,创建一个 QDrag 对象,并传递一个指向开始拖动的小部件的指针。项目可以被多个视图同时观察,但是只有一个视图可以开始拖动。拖动通常是由于按下或移动鼠标而开始的,因此在 mousePressEvent() 或 mouseMoveEvent() 中,您可以从事件中获取原始小部件指针。例如:

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

To intercept drag and drop events for the scene, you reimplement QGraphicsScene::dragEnterEvent() and whichever event handlers your particular scene needs, in a QGraphicsItem subclass. You can read more about drag and drop in Graphics View in the documentation for each of QGraphicsScene's event handlers.
要拦截场景的拖放事件,您需要重新实现 QGraphicsItem 子类中的 QGraphicsScene::dragEnterEvent() 和特定场景需要的任何事件处理程序。您可以在每个 QGraphicsScene 的事件处理程序的文档中详细了解 Graphics View 中的拖放。

Items can enable drag and drop support by calling QGraphicsItem::setAcceptDrops(). To handle the incoming drag, reimplement QGraphicsItem::dragEnterEvent(), QGraphicsItem::dragMoveEvent(), QGraphicsItem::dragLeaveEvent(), and QGraphicsItem::dropEvent().
项目可以通过调用 QGraphicsItem::setAcceptDrops() 来启用拖放支持。要处理传入的拖放,需要重新实现 QGraphicsItem::dragEnterEvent()、QGraphicsItem::dragMoveEvent()、QGraphicsItem::dragLeaveEvent() 和 QGraphicsItem::dropEvent()。

See also the Drag and Drop Robot example for a demonstration of Graphics View's support for drag and drop operations.
另请参阅拖放机器人示例,以了解 Graphics View 对拖放操作的支持演示。

Cursors and Tooltips 光标和工具提示

Like QWidget, QGraphicsItem also supports cursors (QGraphicsItem::setCursor()), and tooltips (QGraphicsItem::setToolTip()). The cursors and tooltips are activated by QGraphicsView as the mouse cursor enters the item's area (detected by calling QGraphicsItem::contains()).
与 QWidget 类似,QGraphicsItem 也支持光标(QGraphicsItem::setCursor())和工具提示(QGraphicsItem::setToolTip())。当鼠标光标进入项目区域时(通过调用 QGraphicsItem::contains() 检测),由 QGraphicsView 激活光标和工具提示。

You can also set a default cursor directly on the view by calling QGraphicsView::setCursor().
您还可以通过调用 QGraphicsView::setCursor() 在视图上直接设置默认光标。

See also the Drag and Drop Robot example for code that implements tooltips and cursor shape handling.
参见拖放机器人示例,该示例实现了工具提示和光标形状处理的代码。

Animation 动画

Graphics View supports animation at several levels. You can easily assemble animation by using the Animation Framework. For that you'll need your items to inherit from QGraphicsObject and associate QPropertyAnimation with them. QPropertyAnimation allows to animate any QObject property.
图形视图支持多个级别的动画。您可以通过使用动画框架轻松组装动画。为此,您需要让您的项从 QGraphicsObject 继承,并将 QPropertyAnimation 与它们关联。QPropertyAnimation 允许对任何 QObject 属性进行动画处理。

Another option is to create a custom item that inherits from QObject and QGraphicsItem. The item can the set up its own timers, and control animations with incremental steps in QObject::timerEvent().
另一种选择是创建一个自定义项目,该项目继承自 QObject 和 QGraphicsItem。该项目可以使用自己的定时器设置,并使用 QObject::timerEvent() 中的增量步骤控制动画。

A third option, which is mostly available for compatibility with QCanvas in Qt 3, is to advance the scene by calling QGraphicsScene::advance(), which in turn calls QGraphicsItem::advance().
第三种选择,主要是为了与 Qt 3 中的 QCanvas 兼容而提供的,即通过调用 QGraphicsScene::advance() 推进场景,该调用反过来调用 QGraphicsItem::advance()。

OpenGL Rendering OpenGL 渲染

To enable OpenGL rendering, you simply set a new QOpenGLWidget as the viewport of QGraphicsView by calling QGraphicsView::setViewport(). If you want OpenGL with antialiasing, you need to set a QSurfaceFormat with the needed sample count (see QSurfaceFormat::setSamples()).
要启用 OpenGL 渲染,您只需通过调用 QGraphicsView::setViewport()将新的 QOpenGLWidget 设置为 QGraphicsView 的视口。如果您想要 OpenGL 和抗锯齿,您需要设置一个具有所需样本计数的 QSurfaceFormat(参见 QSurfaceFormat::setSamples())。

Example: 示例:

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

Item Groups 项目组

By making an item a child of another, you can achieve the most essential feature of item grouping: the items will move together, and all transformations are propagated from parent to child.
通过将一个项目设为另一个项目的子项,您可以实现项目分组的最基本功能:项目将一起移动,并且所有变换都从父项传播到子项。

In addition, QGraphicsItemGroup is a special item that combines child event handling with a useful interface for adding and removing items to and from a group. Adding an item to a QGraphicsItemGroup will keep the item's original position and transformation, whereas reparenting items in general will cause the child to reposition itself relative to its new parent. For convenience, you can create QGraphicsItemGroups through the scene by calling QGraphicsScene::createItemGroup().
此外,QGraphicsItemGroup 是一个特殊的项目,它将子项事件处理与用于向组中添加和删除项目的有用接口结合在一起。将项目添加到 QGraphicsItemGroup 将保留项目的原始位置和变换,而一般情况下重新父项化项目将导致子项相对于其新父项重新定位。为了方便起见,您可以通过调用 QGraphicsScene::createItemGroup() 在场景中创建 QGraphicsItemGroups。

Widgets and Layouts 小部件和布局

Qt 4.4 introduced support for geometry and layout-aware items through QGraphicsWidget. This special base item is similar to QWidget, but unlike QWidget, it doesn't inherit from QPaintDevice; rather from QGraphicsItem instead. This allows you to write complete widgets with events, signals & slots, size hints and policies, and you can also manage your widgets geometries in layouts through QGraphicsLinearLayout and QGraphicsGridLayout.
Qt 4.4 通过 QGraphicsWidget 引入了对几何和布局感知项的支持。这个特殊的基础项类似于 QWidget,但与 QWidget 不同的是,它不继承自 QPaintDevice,而是继承自 QGraphicsItem。这使您可以编写完整的小部件,具有事件、信号和槽、大小提示和策略,并且您还可以通过 QGraphicsLinearLayout 和 QGraphicsGridLayout 在布局中管理小部件的几何形状。

QGraphicsWidget

Building on top of QGraphicsItem's capabilities and lean footprint, QGraphicsWidget provides the best of both worlds: extra functionality from QWidget, such as the style, font, palette, layout direction, and its geometry, and resolution independence and transformation support from QGraphicsItem. Because Graphics View uses real coordinates instead of integers, QGraphicsWidget's geometry functions also operate on QRectF and QPointF. This also applies to frame rects, margins and spacing. With QGraphicsWidget it's not uncommon to specify contents margins of (0.5, 0.5, 0.5, 0.5), for example. You can create both subwidgets and "top-level" windows; in some cases you can now use Graphics View for advanced MDI applications.
在 QGraphicsItem 的功能和精简占用的基础上构建,QGraphicsWidget 提供了 QWidget 的额外功能,如样式、字体、调色板、布局方向和其几何形状,以及来自 QGraphicsItem 的分辨率独立性和变换支持。由于 Graphics View 使用实数坐标而不是整数,QGraphicsWidget 的几何函数也适用于 QRectF 和 QPointF。这也适用于框架矩形、边距和间距。使用 QGraphicsWidget,指定内容边距为 (0.5, 0.5, 0.5, 0.5) 并不罕见。您可以创建子小部件和“顶级”窗口;在某些情况下,您现在可以使用 Graphics View 创建高级 MDI 应用程序。

Some of QWidget's properties are supported, including window flags and attributes, but not all. You should refer to QGraphicsWidget's class documentation for a complete overview of what is and what is not supported. For example, you can create decorated windows by passing the Qt::Window window flag to QGraphicsWidget's constructor, but Graphics View currently doesn't support the Qt::Sheet and Qt::Drawer flags that are common on macOS.
一些 QWidget 的属性得到支持,包括窗口标志和属性,但不是全部。您应该参考 QGraphicsWidget 的类文档,以获得完整的支持和不支持内容概述。例如,您可以通过将 Qt::Window 窗口标志传递给 QGraphicsWidget 的构造函数来创建装饰窗口,但是 Graphics View 目前不支持 macOS 上常见的 Qt::Sheet 和 Qt::Drawer 标志。

QGraphicsLayout

QGraphicsLayout is part of a second-generation layout framework designed specifically for QGraphicsWidget. Its API is very similar to that of QLayout. You can manage widgets and sublayouts inside either QGraphicsLinearLayout and QGraphicsGridLayout. You can also easily write your own layout by subclassing QGraphicsLayout yourself, or add your own QGraphicsItem items to the layout by writing an adaptor subclass of QGraphicsLayoutItem.
QGraphicsLayout 是专门为 QGraphicsWidget 设计的第二代布局框架的一部分。它的 API 与 QLayout 非常相似。您可以在 QGraphicsLinearLayout 和 QGraphicsGridLayout 中管理小部件和子布局。您还可以通过自己的 QGraphicsLayout 子类轻松编写自己的布局,或者通过编写 QGraphicsLayoutItem 的适配器子类将自己的 QGraphicsItem 项目添加到布局中。

Embedded Widget Support 

Graphics View provides seamless support for embedding any widget into the scene. You can embed simple widgets, such as QLineEdit or QPushButton, complex widgets such as QTabWidget, and even complete main windows. To embed your widget to the scene, simply call QGraphicsScene::addWidget(), or create an instance of QGraphicsProxyWidget to embed your widget manually. 

Through QGraphicsProxyWidget, Graphics View is able to deeply integrate the client widget features including its cursors, tooltips, mouse, tablet and keyboard events, child widgets, animations, pop-ups (e.g., QComboBox or QCompleter), and the widget's input focus and activation. QGraphicsProxyWidget even integrates the embedded widget's tab order so that you can tab in and out of embedded widgets. You can even embed a new QGraphicsView into your scene to provide complex nested scenes. 

When transforming an embedded widget, Graphics View makes sure that the widget is transformed resolution independently, allowing the fonts and style to stay crisp when zoomed in. (Note that the effect of resolution independence depends on the style.)
在转换嵌入式小部件时,Graphics View 确保小部件以分辨率独立的方式进行转换,允许在放大时保持字体和样式清晰。(请注意,分辨率独立性的效果取决于样式。)

Performance 性能

Floating Point Instructions
浮点指令

In order to accurately and quickly apply transformations and effects to items, Graphics View is built with the assumption that the user's hardware is able to provide reasonable performance for floating point instructions.
为了准确快速地将变换和效果应用于项目,图形视图构建在这样一个假设基础上:用户的硬件能够为浮点指令提供合理的性能。

Many workstations and desktop computers are equipped with suitable hardware to accelerate this kind of computation, but some embedded devices may only provide libraries to handle mathematical operations or emulate floating point instructions in software.
许多工作站和台式计算机配备了适当的硬件来加速此类计算,但一些嵌入式设备可能只提供处理数学运算或在软件中模拟浮点指令的库。

As a result, certain kinds of effects may be slower than expected on certain devices. It may be possible to compensate for this performance hit by making optimizations in other areas; for example, by using OpenGL to render a scene. However, any such optimizations may themselves cause a reduction in performance if they also rely on the presence of floating point hardware.
因此,某些类型的效果可能在某些设备上比预期的慢。通过在其他领域进行优化可能会补偿这种性能损失;例如,通过使用 OpenGL 来渲染场景。然而,如果这些优化也依赖于浮点硬件的存在,则这些优化本身可能会导致性能降低。

© 2023 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.
© 2023 年 Qt 公司有限公司。此处包括的文档贡献属于其各自所有者的版权。此处提供的文档根据由自由软件基金会发布的 GNU 自由文档许可证版本 1.3 的条款许可。Qt 及其各自的标志是芬兰 Qt 公司在芬兰和/或其他国家/地区的商标。所有其他商标均为其各自所有者的财产。