[556] | 1 | /****************************************************************************
|
---|
| 2 | **
|
---|
| 3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
| 4 | ** All rights reserved.
|
---|
| 5 | ** Contact: Nokia Corporation ([email protected])
|
---|
| 6 | **
|
---|
| 7 | ** This file is part of the documentation of the Qt Toolkit.
|
---|
| 8 | **
|
---|
| 9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
| 10 | ** Commercial Usage
|
---|
| 11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
| 12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
| 13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
| 14 | ** a written agreement between you and Nokia.
|
---|
| 15 | **
|
---|
| 16 | ** GNU Lesser General Public License Usage
|
---|
| 17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
| 18 | ** General Public License version 2.1 as published by the Free Software
|
---|
| 19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
| 20 | ** packaging of this file. Please review the following information to
|
---|
| 21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
| 22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
| 23 | **
|
---|
| 24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
| 25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
| 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
| 27 | **
|
---|
| 28 | ** GNU General Public License Usage
|
---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
| 30 | ** General Public License version 3.0 as published by the Free Software
|
---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
| 32 | ** packaging of this file. Please review the following information to
|
---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
| 35 | **
|
---|
| 36 | ** If you have questions regarding the use of this file, please contact
|
---|
| 37 | ** Nokia at [email protected].
|
---|
| 38 | ** $QT_END_LICENSE$
|
---|
| 39 | **
|
---|
| 40 | ****************************************************************************/
|
---|
| 41 |
|
---|
| 42 | /*!
|
---|
| 43 | \group graphicsview-api
|
---|
| 44 | \title Graphics View Classes
|
---|
| 45 | */
|
---|
| 46 |
|
---|
| 47 | /*!
|
---|
| 48 | \page graphicsview.html
|
---|
| 49 | \title The Graphics View Framework
|
---|
| 50 | \brief An overview of the Graphics View framework for interactive 2D
|
---|
| 51 | graphics.
|
---|
| 52 |
|
---|
| 53 | \ingroup frameworks-technologies
|
---|
| 54 |
|
---|
| 55 | \keyword Graphics View
|
---|
| 56 | \keyword GraphicsView
|
---|
| 57 | \keyword Graphics
|
---|
| 58 | \keyword Canvas
|
---|
| 59 | \since 4.2
|
---|
| 60 |
|
---|
| 61 | Graphics View provides a surface for managing and interacting with a large
|
---|
| 62 | number of custom-made 2D graphical items, and a view widget for
|
---|
| 63 | visualizing the items, with support for zooming and rotation.
|
---|
| 64 |
|
---|
| 65 | The framework includes an event propagation architecture that allows
|
---|
| 66 | precise double-precision interaction capabilities for the items on the
|
---|
| 67 | scene. Items can handle key events, mouse press, move, release and
|
---|
| 68 | double click events, and they can also track mouse movement.
|
---|
| 69 |
|
---|
| 70 | Graphics View uses a BSP (Binary Space Partitioning) tree to provide very
|
---|
| 71 | fast item discovery, and as a result of this, it can visualize large
|
---|
| 72 | scenes in real-time, even with millions of items.
|
---|
| 73 |
|
---|
| 74 | Graphics View was introduced in Qt 4.2, replacing its predecessor,
|
---|
| 75 | QCanvas. If you are porting from QCanvas, see \l{Porting to Graphics
|
---|
| 76 | View}.
|
---|
| 77 |
|
---|
| 78 | Topics:
|
---|
| 79 |
|
---|
| 80 | \tableofcontents
|
---|
| 81 |
|
---|
| 82 | \section1 The Graphics View Architecture
|
---|
| 83 |
|
---|
| 84 | Graphics View provides an item-based approach to model-view programming,
|
---|
| 85 | much like InterView's convenience classes QTableView, QTreeView and
|
---|
| 86 | QListView. Several views can observe a single scene, and the scene
|
---|
| 87 | contains items of varying geometric shapes.
|
---|
| 88 |
|
---|
| 89 | \section2 The Scene
|
---|
| 90 |
|
---|
| 91 | QGraphicsScene provides the Graphics View scene. The scene has the
|
---|
| 92 | following responsibilities:
|
---|
| 93 |
|
---|
| 94 | \list
|
---|
| 95 | \o Providing a fast interface for managing a large number of items
|
---|
| 96 | \o Propagating events to each item
|
---|
| 97 | \o Managing item state, such as selection and focus handling
|
---|
| 98 | \o Providing untransformed rendering functionality; mainly for printing
|
---|
| 99 | \endlist
|
---|
| 100 |
|
---|
| 101 | The scene serves as a container for QGraphicsItem objects. Items are
|
---|
| 102 | added to the scene by calling QGraphicsScene::addItem(), and then
|
---|
| 103 | retrieved by calling one of the many item discovery functions.
|
---|
| 104 | QGraphicsScene::items() and its overloads return all items contained
|
---|
| 105 | by or intersecting with a point, a rectangle, a polygon or a general
|
---|
| 106 | vector path. QGraphicsScene::itemAt() returns the topmost item at a
|
---|
| 107 | particular point. All item discovery functions return the items in
|
---|
| 108 | descending stacking order (i.e., the first returned item is topmost,
|
---|
| 109 | and the last item is bottom-most).
|
---|
| 110 |
|
---|
| 111 | \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 0
|
---|
| 112 |
|
---|
| 113 | QGraphicsScene's event propagation architecture schedules scene events
|
---|
| 114 | for delivery to items, and also manages propagation between items. If
|
---|
| 115 | the scene receives a mouse press event at a certain position, the
|
---|
| 116 | scene passes the event on to whichever item is at that position.
|
---|
| 117 |
|
---|
| 118 | QGraphicsScene also manages certain item states, such as item
|
---|
| 119 | selection and focus. You can select items on the scene by calling
|
---|
| 120 | QGraphicsScene::setSelectionArea(), passing an arbitrary shape. This
|
---|
| 121 | functionality is also used as a basis for rubberband selection in
|
---|
| 122 | QGraphicsView. To get the list of all currently selected items, call
|
---|
| 123 | QGraphicsScene::selectedItems(). Another state handled by
|
---|
| 124 | QGraphicsScene is whether or not an item has keyboard input focus. You
|
---|
| 125 | can set focus on an item by calling QGraphicsScene::setFocusItem() or
|
---|
| 126 | QGraphicsItem::setFocus(), or get the current focus item by calling
|
---|
| 127 | QGraphicsScene::focusItem().
|
---|
| 128 |
|
---|
| 129 | Finally, QGraphicsScene allows you to render parts of the scene into a
|
---|
| 130 | paint device through the QGraphicsScene::render() function. You can
|
---|
| 131 | read more about this in the Printing section later in this document.
|
---|
| 132 |
|
---|
| 133 | \section2 The View
|
---|
| 134 |
|
---|
| 135 | QGraphicsView provides the view widget, which visualizes the contents
|
---|
| 136 | of a scene. You can attach several views to the same scene, to provide
|
---|
| 137 | several viewports into the same data set. The view widget is a scroll
|
---|
| 138 | area, and provides scroll bars for navigating through large scenes. To
|
---|
| 139 | enable OpenGL support, you can set a QGLWidget as the viewport by
|
---|
| 140 | calling QGraphicsView::setViewport().
|
---|
| 141 |
|
---|
| 142 | \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 1
|
---|
| 143 |
|
---|
| 144 | The view receives input events from the keyboard and mouse, and
|
---|
| 145 | translates these to scene events (converting the coordinates used
|
---|
| 146 | to scene coordinates where appropriate), before sending the events
|
---|
| 147 | to the visualized scene.
|
---|
| 148 |
|
---|
| 149 | Using its transformation matrix, QGraphicsView::transform(), the view can
|
---|
| 150 | \e transform the scene's coordinate system. This allows advanced
|
---|
| 151 | navigation features such as zooming and rotation. For convenience,
|
---|
| 152 | QGraphicsView also provides functions for translating between view and
|
---|
| 153 | scene coordinates: QGraphicsView::mapToScene() and
|
---|
| 154 | QGraphicsView::mapFromScene().
|
---|
| 155 |
|
---|
| 156 | \img graphicsview-view.png
|
---|
| 157 |
|
---|
| 158 | \section2 The Item
|
---|
| 159 |
|
---|
| 160 | QGraphicsItem is the base class for graphical items in a
|
---|
| 161 | scene. Graphics View provides several standard items for typical
|
---|
| 162 | shapes, such as rectangles (QGraphicsRectItem), ellipses
|
---|
| 163 | (QGraphicsEllipseItem) and text items (QGraphicsTextItem), but the
|
---|
| 164 | most powerful QGraphicsItem features are available when you write a
|
---|
| 165 | custom item. Among other things, QGraphicsItem supports the following
|
---|
| 166 | features:
|
---|
| 167 |
|
---|
| 168 | \list
|
---|
| 169 | \o Mouse press, move, release and double click events, as well as mouse
|
---|
| 170 | hover events, wheel events, and context menu events.
|
---|
| 171 | \o Keyboard input focus, and key events
|
---|
| 172 | \o Drag and drop
|
---|
| 173 | \o Grouping, both through parent-child relationships, and with
|
---|
| 174 | QGraphicsItemGroup
|
---|
| 175 | \o Collision detection
|
---|
| 176 | \endlist
|
---|
| 177 |
|
---|
| 178 | Items live in a local coordinate system, and like QGraphicsView, it
|
---|
| 179 | also provides many functions for mapping coordinates between the item
|
---|
| 180 | and the scene, and from item to item. Also, like QGraphicsView, it can
|
---|
| 181 | transform its coordinate system using a matrix:
|
---|
| 182 | QGraphicsItem::transform(). This is useful for rotating and scaling
|
---|
| 183 | individual items.
|
---|
| 184 |
|
---|
| 185 | Items can contain other items (children). Parent items'
|
---|
| 186 | transformations are inherited by all its children. Regardless of an
|
---|
| 187 | item's accumulated transformation, though, all its functions (e.g.,
|
---|
| 188 | QGraphicsItem::contains(), QGraphicsItem::boundingRect(),
|
---|
| 189 | QGraphicsItem::collidesWith()) still operate in local coordinates.
|
---|
| 190 |
|
---|
| 191 | QGraphicsItem supports collision detection through the
|
---|
| 192 | QGraphicsItem::shape() function, and QGraphicsItem::collidesWith(),
|
---|
| 193 | which are both virtual functions. By returning your item's shape as a
|
---|
| 194 | local coordinate QPainterPath from QGraphicsItem::shape(),
|
---|
| 195 | QGraphicsItem will handle all collision detection for you. If you want
|
---|
| 196 | to provide your own collision detection, however, you can reimplement
|
---|
| 197 | QGraphicsItem::collidesWith().
|
---|
| 198 |
|
---|
| 199 | \img graphicsview-items.png
|
---|
| 200 |
|
---|
| 201 | \section1 Classes in the Graphics View Framework
|
---|
| 202 |
|
---|
| 203 | These classes provide a framework for creating interactive applications.
|
---|
| 204 |
|
---|
| 205 | \annotatedlist graphicsview-api
|
---|
| 206 |
|
---|
| 207 | \section1 The Graphics View Coordinate System
|
---|
| 208 |
|
---|
| 209 | Graphics View is based on the Cartesian coordinate system; items'
|
---|
| 210 | position and geometry on the scene are represented by sets of two
|
---|
| 211 | numbers: the x-coordinate, and the y-coordinate. When observing a scene
|
---|
| 212 | using an untransformed view, one unit on the scene is represented by
|
---|
| 213 | one pixel on the screen.
|
---|
| 214 |
|
---|
| 215 | \note The inverted Y-axis coordinate system (where \c y grows upwards)
|
---|
| 216 | is unsupported as Graphics Views uses Qt's coordinate system.
|
---|
| 217 |
|
---|
| 218 | There are three effective coordinate systems in play in Graphics View:
|
---|
| 219 | Item coordinates, scene coordinates, and view coordinates. To simplify
|
---|
| 220 | your implementation, Graphics View provides convenience functions that
|
---|
| 221 | allow you to map between the three coordinate systems.
|
---|
| 222 |
|
---|
| 223 | When rendering, Graphics View's scene coordinates correspond to
|
---|
| 224 | QPainter's \e logical coordinates, and view coordinates are the same as
|
---|
| 225 | \e device coordinates. In \l{The Coordinate System}, you can read about
|
---|
| 226 | the relationship between logical coordinates and device coordinates.
|
---|
| 227 |
|
---|
| 228 | \img graphicsview-parentchild.png
|
---|
| 229 |
|
---|
| 230 | \section2 Item Coordinates
|
---|
| 231 |
|
---|
| 232 | Items live in their own local coordinate system. Their coordinates
|
---|
| 233 | are usually centered around its center point (0, 0), and this is
|
---|
| 234 | also the center for all transformations. Geometric primitives in the
|
---|
| 235 | item coordinate system are often referred to as item points, item
|
---|
| 236 | lines, or item rectangles.
|
---|
| 237 |
|
---|
| 238 | When creating a custom item, item coordinates are all you need to
|
---|
| 239 | worry about; QGraphicsScene and QGraphicsView will perform all
|
---|
| 240 | transformations for you. This makes it very easy to implement custom
|
---|
| 241 | items. For example, if you receive a mouse press or a drag enter
|
---|
| 242 | event, the event position is given in item coordinates. The
|
---|
| 243 | QGraphicsItem::contains() virtual function, which returns true if a
|
---|
| 244 | certain point is inside your item, and false otherwise, takes a
|
---|
| 245 | point argument in item coordinates. Similarly, an item's bounding
|
---|
| 246 | rect and shape are in item coordinates.
|
---|
| 247 |
|
---|
| 248 | At item's \e position is the coordinate of the item's center point
|
---|
| 249 | in its parent's coordinate system; sometimes referred to as \e
|
---|
| 250 | parent coordinates. The scene is in this sense regarded as all
|
---|
| 251 | parent-less items' "parent". Top level items' position are in scene
|
---|
| 252 | coordinates.
|
---|
| 253 |
|
---|
| 254 | Child coordinates are relative to the parent's coordinates. If the
|
---|
| 255 | child is untransformed, the difference between a child coordinate
|
---|
| 256 | and a parent coordinate is the same as the distance between the
|
---|
| 257 | items in parent coordinates. For example: If an untransformed child
|
---|
| 258 | item is positioned precisely in its parent's center point, then the
|
---|
| 259 | two items' coordinate systems will be identical. If the child's
|
---|
| 260 | position is (10, 0), however, the child's (0, 10) point will
|
---|
| 261 | correspond to its parent's (10, 10) point.
|
---|
| 262 |
|
---|
| 263 | Because items' position and transformation are relative to the
|
---|
| 264 | parent, child items' coordinates are unaffected by the parent's
|
---|
| 265 | transformation, although the parent's transformation implicitly
|
---|
| 266 | transforms the child. In the above example, even if the parent is
|
---|
| 267 | rotated and scaled, the child's (0, 10) point will still correspond
|
---|
| 268 | to the parent's (10, 10) point. Relative to the scene, however, the
|
---|
| 269 | child will follow the parent's transformation and position. If the
|
---|
| 270 | parent is scaled (2x, 2x), the child's position will be at scene
|
---|
| 271 | coordinate (20, 0), and its (10, 0) point will correspond to the
|
---|
| 272 | point (40, 0) on the scene.
|
---|
| 273 |
|
---|
| 274 | With QGraphicsItem::pos() being one of the few exceptions,
|
---|
| 275 | QGraphicsItem's functions operate in item coordinates, regardless of
|
---|
| 276 | the item, or any of its parents' transformation. For example, an
|
---|
| 277 | item's bounding rect (i.e. QGraphicsItem::boundingRect()) is always
|
---|
| 278 | given in item coordinates.
|
---|
| 279 |
|
---|
| 280 | \section2 Scene Coordinates
|
---|
| 281 |
|
---|
| 282 | The scene represents the base coordinate system for all its items.
|
---|
| 283 | The scene coordinate system describes the position of each top-level
|
---|
| 284 | item, and also forms the basis for all scene events delivered to the
|
---|
| 285 | scene from the view. Each item on the scene has a scene position
|
---|
| 286 | and bounding rectangle (QGraphicsItem::scenePos(),
|
---|
| 287 | QGraphicsItem::sceneBoundingRect()), in addition to its local item
|
---|
| 288 | pos and bounding rectangle. The scene position describes the item's
|
---|
| 289 | position in scene coordinates, and its scene bounding rect forms the
|
---|
| 290 | basis for how QGraphicsScene determines what areas of the scene have
|
---|
| 291 | changed. Changes in the scene are communicated through the
|
---|
| 292 | QGraphicsScene::changed() signal, and the argument is a list of
|
---|
| 293 | scene rectangles.
|
---|
| 294 |
|
---|
| 295 | \section2 View Coordinates
|
---|
| 296 |
|
---|
| 297 | View coordinates are the coordinates of the widget. Each unit in
|
---|
| 298 | view coordinates corresponds to one pixel. What's special about this
|
---|
| 299 | coordinate system is that it is relative to the widget, or viewport,
|
---|
| 300 | and unaffected by the observed scene. The top left corner of
|
---|
| 301 | QGraphicsView's viewport is always (0, 0), and the bottom right
|
---|
| 302 | corner is always (viewport width, viewport height). All mouse events
|
---|
| 303 | and drag and drop events are originally received as view
|
---|
| 304 | coordinates, and you need to map these coordinates to the scene in
|
---|
| 305 | order to interact with items.
|
---|
| 306 |
|
---|
| 307 | \section2 Coordinate Mapping
|
---|
| 308 |
|
---|
| 309 | Often when dealing with items in a scene, it can be useful to map
|
---|
| 310 | coordinates and arbitrary shapes from the scene to an item, from
|
---|
| 311 | item to item, or from the view to the scene. For example, when you
|
---|
| 312 | click your mouse in QGraphicsView's viewport, you can ask the scene
|
---|
| 313 | what item is under the cursor by calling
|
---|
| 314 | QGraphicsView::mapToScene(), followed by
|
---|
| 315 | QGraphicsScene::itemAt(). If you want to know where in the viewport
|
---|
| 316 | an item is located, you can call QGraphicsItem::mapToScene() on the
|
---|
| 317 | item, then QGraphicsView::mapFromScene() on the view. Finally, if
|
---|
| 318 | you use want to find what items are inside a view ellipse, you can
|
---|
| 319 | pass a QPainterPath to mapToScene(), and then pass the mapped path
|
---|
| 320 | to QGraphicsScene::items().
|
---|
| 321 |
|
---|
| 322 | You can map coordinates and shapes to and from and item's scene by
|
---|
| 323 | calling QGraphicsItem::mapToScene() and
|
---|
| 324 | QGraphicsItem::mapFromScene(). You can also map to an item's parent
|
---|
| 325 | item by calling QGraphicsItem::mapToParent() and
|
---|
| 326 | QGraphicsItem::mapFromParent(), or between items by calling
|
---|
| 327 | QGraphicsItem::mapToItem() and QGraphicsItem::mapFromItem(). All
|
---|
| |
---|