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.

GraphicsView Framework提供了管理和交互大量的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.

该框架包含了一个事件传播机制,它提供了对scene中的图元的双精度的交互能力。这些图形元素可以处理键盘事件和鼠标事件,还可以跟踪鼠标的移动。


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树来提高图元的处理效率,因此,它可以同时处理大量的scene和图元。


Graphics View was introduced in Qt 4.2, replacing its predecessor, QCanvas. If you are porting from QCanvas, see Porting to Graphics View.

GraphicsView FrameworkQt4.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.

GraphicsViewFramework使用item-based方式来实现model-view模型,就像QTableViewQTreeViewQListView一样。多个视图可以同时使用同一个scene,而scene则可包含不同的图元。

The Scene

QGraphicsScene provides the Graphics View scene. The scene has the following responsibilities:

scene执行的工作有:


  • 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).

可将scene看做一个存放QGraphicsItem对象的容器。通过QGraphicsScene::addItem()添加图元,获取图元可以通过调用某个图元获取函数来获取:QGraphicsScene::items()的一系列重载函数返回所有被包含或跟point/rectange/polygon/vectorpath相交的所有图元。QGraphicsScene::itemAt()返回在某坐标处的顶层图元。所有的这些获取图元函数,返回的图元列表按照Z轴降序方向的栈为顺序(Z轴顶层图元在先,底层图元在尾)


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

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

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的事件传播机制可以调度scene事件,包括传递给图元和管理事件在图元之间的传播。如果scene接收到一个鼠标点击的事件,那么scene会将该事件传递给鼠标点击的坐标所属的顶层图元。


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::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.

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 QGLWidget as the viewport by calling QGraphicsView::setViewport().

QGraphicsView提供视图部件来显示scene的内容。你可以将多个视图关联同一个scene。这个视图部件包含有滚动条,可以滚动查看较大的scene。如果要启用OpenGL支持,你可以通过调用QgraphicsView::setViewport(),将一个QGLWidget设置为viewport


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.

view接收到来自键盘和鼠标的输入事件后,将它们转换成scene事件(view坐标转换到scene坐标),然后发送给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().

使用转换矩阵,view能够转换scene的坐标系统。这样就可以实现一些比如放缩和旋转的高级特性。另外,QGraphicsView也提供了在viewscene两种坐标之间的转换: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是图元的基类。GraphicsView Framework提供了几种标准图元,例如矩形,椭圆和文本,但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
  • 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一样,它也提供了多个函数来实现图元和scene之间,以及图元和图元之间的坐标映射。图元也可以通过一个转换矩阵来改变其坐标系统,这对单个图元的旋转和放缩很有用。


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 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

Layout where one can anchor widgets together in Graphics View

QGraphicsEffect

The base class for all graphics effects

QGraphicsEllipseItem

Ellipse item that you can add to a QGraphicsScene

QGraphicsGridLayout

Grid layout for managing widgets in Graphics View

QGraphicsItem

The base class for all graphical items in a QGraphicsScene

QGraphicsItemGroup

Container that treats a group of items as a single item

QGraphicsLayout

The base class for all layouts in 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

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

QGraphicsPixmapItem

Pixmap item that you can add to a QGraphicsScene

QGraphicsPolygonItem

Polygon item that you can add to a QGraphicsScene

QGraphicsProxyWidget

Proxy layer for embedding a QWidget in a QGraphicsScene

QGraphicsRectItem

Rectangle item that you can add to a QGraphicsScene

QGraphicsScene

Surface for managing a large number of 2D graphical items

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

QGraphicsSvgItem

QGraphicsItem that can be used to render the contents of SVG files

QGraphicsTextItem

Text item that you can add to a QGraphicsScene to display formatted text

QGraphicsTransform

Abstract base class for building advanced transformations on QGraphicsItems

QGraphicsView

Widget for displaying the contents of a QGraphicsScene

QGraphicsWidget

The base class for all widget items in a QGraphicsScene

QStyleOptionGraphicsItem

Used to describe the parameters needed to draw a 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.

GraphicsViewFramework基于笛卡尔坐标系;图元的图形位置通过x坐标值和y坐标值体现。如果一个scene使用未进行坐标转换的view,那么scene中的一个单位对应屏幕上的一个像素。


Note: The inverted Y-axis coordinate system (where y grows upwards) is unsupported as Graphics Views uses Qt's coordinate system.

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.

GraphicsView Framework有三种坐标系统:item坐标系,scene坐标系和view坐标系。为了简化你的实现,GraphicsView Framework提供了几个便利的函数,用来在这三种坐标系统中相互转换。


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.

在绘制时,scene坐标对应QPainter的逻辑坐标,view坐标同设备坐标一致。


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.

当创建一个自定义图元时,你只需要关注坐标的处理就行了;QGraphicsSceneQGraphicsView会为你完成所有的坐标转换,这使得自定义图元变得容易。比如,如果你要处理一个鼠标点击事件或拖拽开始事件的时候,你收到的事件的坐标值已经是图元自己的坐标值了。QGraphicsItem::contains()也是使用图元坐标做为参数的。图元的边界区域和形状也都是使用图元坐标。


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.

图元的位置是该图元的中心在其父亲的坐标系中的坐标;有时候被当做父坐标。如果一个图元没有父亲,那么scene就是它的父亲。顶层的图元的位置指的是位于scene的坐标。


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)坐标。但对于scene,图元将受到其影响。如果scene放大2倍,那么孩子图元的位置会变成scene中的(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的函数都在图元自己的坐标系中操作,而不管图元还是父亲进行任何的坐标变换。例如,一个图元的边界区域总是使用图元局部坐标系。


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.

scene坐标系是其包含的所有图元的基础坐标系。scene坐标系描述了每个顶层图元的位置,也为传递来自于view的事件奠定了基础。每个位于scene中的图元都有一个scene位置和边界矩形(QGraphicsItem::scenePos(),QGraphicsItem::sceneBoundingRect()),另外图元也有自己的(在父亲中的)位置和边界区域。图元的scene位置描述了图元在scene坐标系下的位置,其边界区域是scene感知内容变化的基础。当scene内容变化时会发射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.

view坐标就是其部件中的坐标。view中的每个单位对应一个像素。view的坐标系不受scene的影响。QGraphicsViewviewport的左上角坐标永远是(0,0),右下角坐标永远是(viewport的宽度,viewport的高度)。所有的鼠标事件和拖拽事件起初使用view坐标,为了跟图元交互你需要将这些坐标映射到scene坐标。


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().

通常在操作scene中的图元时,坐标和形状的映射是非常有用的,包括从scene到图元的映射,从图元到图元的映射,或从viewscene的映射。举个例子,当你在viewviewport的某处点击鼠标时,你可以通过分别调用QGraphicsView::mapToScene()QGraphicsScene::itemAt()来获得鼠标点击的是哪个图元。如果你想知道一个图元位于viewport的什么位置,则可以通过分别调用QGraphicsItem::mapToScene()QGraphicsView::mapFromScene()最后,如果你想查询位于view中的一个椭圆区域内的所有图元,你可以把一个QPainterPath对象传递给mapToScene()然后将变换之后的path传递给QGraphicsScene::items()


You can map coordinates and shapes to and from and 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()在图元和scene之间相互映射坐标和图形。类似地,你可以通过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.

对于从sceneview之间的映射,view中同样存在这些函数。QGraphicsView::mapFromScene()QGraphicsView::mapToScene()。如果是要从view映射到图元,你必须先映射到scene,再从scene映射到图元。


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.

QGraphicsViewQPainter一样,通过QGraphicsView::setMatrix()来实现仿射变换,从而很容易地实现通常的导航特性如放缩和旋转。


Here is an example of how to implement zoom and rotate slots in a subclass of 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.

QGraphicsView keeps the center of the view aligned when you transform the view.

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.

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

QPrinter printer;
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 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.

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.

QGraphcisView间接继承QWidget,因此它从QWidget继承了同样的拖放的功能。另外,GraphicsViewFramework也支持scene和每个图元的拖拽操作。当view接收到一个拖拽动作后,它将事件转换为QGraphicsSceneDragDropEvent,并投递给scenescene接管该事件后,会继续将事件投递给光标下的顶层的图元。


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对象,同时要把发起拖拽操作的部件的指针传递给该对象。图元可以同时在多个view中查看,但同一时刻仅仅有一个view能够进行拖拽。拖拽操作通常在鼠标按下或鼠标移动的时候开始,因此你可以在mousePressEvent()mouseMoveEvent()中获取发起拖拽的部件指针。


void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    QMimeData *data = new QMimeData;
    data->setColor(Qt::green);

    QDrag *drag = new QDrag(event->widget());
    drag->setMimeData(data);
    drag->start();
}

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.

为了拦截拖拽scene的拖放事件,你需要重新实现QGraphicsScene::dragEnterEvent()以及QGraphicsItem子类中相应的事件处理函数。你可以通过QGraphicsSvene的事件处理函数文档中获得更多细节。


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.

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::contains()判断)QGraphicsView会激活该图元的光标图标和窗口提示。


You can also set a default cursor directly on the view by calling QGraphicsView::setCursor().

你也可以直接通过QGraphicsView::setCursor()view设置一个默认的光标。


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.

GraphicsViewFramework支持几种级别的动画。通过AnimationFramework,你可以很容易地添加动画。你需要将图元继承于QGraphicsObject,并将其关联到QPropertyAnimationQPropertyAnimation能够通过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().

另一种方案是创建一个继承于QObjectQGraphicsItem的自定义图元。改图元通过内部的定时器来实现动画效果。


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().

第三种方案主要用来在Qt3中,跟QCanvas兼容。该方案通过移动scene和图元来实现动画效果。


OpenGL Rendering

To enable OpenGL rendering, you simply set a new QGLWidget as the viewport of QGraphicsView by calling QGraphicsView::setViewport(). If you want OpenGL with antialiasing, you need OpenGL sample buffer support (see QGLFormat::sampleBuffers()).

想要使用OpenGL来渲染,你只需要调用QGraphicsView::setViewport()设置一个QGLWidget对象做为新的viewport即可。要使用OpenGL的抗锯齿功能,你需要OpenGL samplebuffer的支持。


Example:

QGraphicsView view(&scene);
view.setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));

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是一个特殊的图元,它能够统一处理孩子图元的事件处理,它提供了添加和移除图元的接口。将一个图元添加到群组后,该图元的位置和坐标变换保持不变,而如果将一个图元设置新的父亲图元后,该图元的位置和坐标变换则会改变。通过调用 QGraphicsScene::createItemGroup()可以创建新的图元群组。


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.

Qt4.4开始引进QGraphicsWidget,通过它能够实现支持几何形状和适用于布局的图元。这个类跟QWideget类似,但跟它不同的是,QGraphcisWidget没有继承于QPaintDevice,而是QGraphicsItem。因此,你可以实现一个功能丰富的部件,你可以使用各种事件,信号槽,尺寸提示和尺寸策略,也可以通过QGraphicsLinearLayoutQGraphcisGridLayout来管理布局中的部件形状。


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.

QGraphicsWidget同时集成了两者的优点:从QWidget中集成的额外功能,如stylefontpalettelayoutdirection和几何图形;以及从QGraphicsItem继承的功能,如独立的分辨率和坐标变换。因为GraphicsViewFramework使用实数而非整数来表示坐标,因此QGraphicsWidget的几何图形函数使用的是QRectFQPointF,对于framerectmarginspacing也同样如此。举个例子,设置QGraphicsWidget的内容边界为(0.5,0.5,0.5,0.5)是非常常见的。你可以对其子类化,也可以创建“顶层”窗口;甚至有时你可以通过它来实现高级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 Mac OS X.

QGraphicsWidget支持一些QWidget的属性,包括窗口的标识和属性,但并不是支持所有属性,详情请参考QGraphicsWidget文档。比如,你可以通过Qt::Window标识创建一个窗口风格的部件,但GraphicsView Framework不支持在MacOS X中常见的Qt::SheetQt::Drawer标识。


The capabilities of QGraphicsWidget are expected to grow depending on community feedback.

根据社区的反馈,QGraphicsWidget的功能可能会逐步增强。


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.

QGraphcisLayout专门为QGraphicsWidget设计,是第二代布局体系中的一部分。它的APIQLayout差不多。你可以在QGraphicsLinearLayoutQGraphicsGridLayout中加入部件和子布局。你也可以很轻松地子类化QGraphcisLayout来实现自己的布局,或者通过子类化QGraphcisLayoutItem来添加自己的图元。


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.

GraphicsViewFramework能够使任何部件无缝地嵌入到scene当中。你可以嵌入像QLineEditQPushButton这样的简单的部件,和像QTabWidget这样的复杂部件,甚至整个主窗口。要把你的部件添加到scene中,你只需要调用QGraphicsScene::addWidget()即可,或者通过创建QGraphicesProxyWidget对象来手动加入你的部件。


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.

通过QGraphicesProxyWidgetGraphicsViewFramework可以深度整合部件的特性:光标,提示信息,鼠标事件,触摸平板和键盘事件,子部件,动画,弹出界面(例如QComboBoxQCompleter),输入焦点和激活等。QGraphicesProxyWidget甚至能够使用部件的tab顺序。更厉害的是,你甚至可以将一个QGraphicsView嵌入到你的scene中,从而提供复杂的嵌套的scene


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.)

当一个嵌入的部件进行坐标转换时,GraphicsView Framework能够确保其自己的分辨率,因此在缩小视图时,仍能够使它的字体和风格保持清晰。


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.

为了对图元的处理更加精确高效,GraphicsView Framework假设用户的硬件能够提供高性能的浮点运算。


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库来渲染scene。不过,如果优化措施自己也依赖于硬件的话,反而可能会降低性能。



  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值