source: trunk/doc/src/frameworks-technologies/graphicsview.qdoc

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 27.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:FDL$
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 a
14** written agreement between you and Nokia.
15**
16** GNU Free Documentation License
17** Alternatively, this file may be used under the terms of the GNU Free
18** Documentation License version 1.3 as published by the Free Software
19** Foundation and appearing in the file included in the packaging of this
20** file.
21**
22** If you have questions regarding the use of this file, please contact
23** Nokia at qt-info@nokia.com.
24** $QT_END_LICENSE$
25**
26****************************************************************************/
27
28/*!
29 \group graphicsview-api
30 \title Graphics View Classes
31*/
32
33/*!
34 \page graphicsview.html
35 \title Graphics View Framework
36 \ingroup qt-graphics
37 \ingroup qt-basic-concepts
38
39 \brief An overview of the Graphics View framework for interactive 2D
40 graphics.
41
42 \keyword Graphics View
43 \keyword GraphicsView
44 \keyword Graphics
45 \keyword Canvas
46 \since 4.2
47
48 Graphics View provides a surface for managing and interacting with a large
49 number of custom-made 2D graphical items, and a view widget for
50 visualizing the items, with support for zooming and rotation.
51
52 The framework includes an event propagation architecture that allows
53 precise double-precision interaction capabilities for the items on the
54 scene. Items can handle key events, mouse press, move, release and
55 double click events, and they can also track mouse movement.
56
57 Graphics View uses a BSP (Binary Space Partitioning) tree to provide very
58 fast item discovery, and as a result of this, it can visualize large
59 scenes in real-time, even with millions of items.
60
61 Graphics View was introduced in Qt 4.2, replacing its predecessor,
62 QCanvas. If you are porting from QCanvas, see \l{Porting to Graphics
63 View}.
64
65 Topics:
66
67 \tableofcontents
68
69 \section1 The Graphics View Architecture
70
71 Graphics View provides an item-based approach to model-view programming,
72 much like InterView's convenience classes QTableView, QTreeView and
73 QListView. Several views can observe a single scene, and the scene
74 contains items of varying geometric shapes.
75
76 \section2 The Scene
77
78 QGraphicsScene provides the Graphics View scene. The scene has the
79 following responsibilities:
80
81 \list
82 \o Providing a fast interface for managing a large number of items
83 \o Propagating events to each item
84 \o Managing item state, such as selection and focus handling
85 \o Providing untransformed rendering functionality; mainly for printing
86 \endlist
87
88 The scene serves as a container for QGraphicsItem objects. Items are
89 added to the scene by calling QGraphicsScene::addItem(), and then
90 retrieved by calling one of the many item discovery functions.
91 QGraphicsScene::items() and its overloads return all items contained
92 by or intersecting with a point, a rectangle, a polygon or a general
93 vector path. QGraphicsScene::itemAt() returns the topmost item at a
94 particular point. All item discovery functions return the items in
95 descending stacking order (i.e., the first returned item is topmost,
96 and the last item is bottom-most).
97
98 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 0
99
100 QGraphicsScene's event propagation architecture schedules scene events
101 for delivery to items, and also manages propagation between items. If
102 the scene receives a mouse press event at a certain position, the
103 scene passes the event on to whichever item is at that position.
104
105 QGraphicsScene also manages certain item states, such as item
106 selection and focus. You can select items on the scene by calling
107 QGraphicsScene::setSelectionArea(), passing an arbitrary shape. This
108 functionality is also used as a basis for rubberband selection in
109 QGraphicsView. To get the list of all currently selected items, call
110 QGraphicsScene::selectedItems(). Another state handled by
111 QGraphicsScene is whether or not an item has keyboard input focus. You
112 can set focus on an item by calling QGraphicsScene::setFocusItem() or
113 QGraphicsItem::setFocus(), or get the current focus item by calling
114 QGraphicsScene::focusItem().
115
116 Finally, QGraphicsScene allows you to render parts of the scene into a
117 paint device through the QGraphicsScene::render() function. You can
118 read more about this in the Printing section later in this document.
119
120 \section2 The View
121
122 QGraphicsView provides the view widget, which visualizes the contents
123 of a scene. You can attach several views to the same scene, to provide
124 several viewports into the same data set. The view widget is a scroll
125 area, and provides scroll bars for navigating through large scenes. To
126 enable OpenGL support, you can set a QGLWidget as the viewport by
127 calling QGraphicsView::setViewport().
128
129 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 1
130
131 The view receives input events from the keyboard and mouse, and
132 translates these to scene events (converting the coordinates used
133 to scene coordinates where appropriate), before sending the events
134 to the visualized scene.
135
136 Using its transformation matrix, QGraphicsView::transform(), the view can
137 \e transform the scene's coordinate system. This allows advanced
138 navigation features such as zooming and rotation. For convenience,
139 QGraphicsView also provides functions for translating between view and
140 scene coordinates: QGraphicsView::mapToScene() and
141 QGraphicsView::mapFromScene().
142
143 \img graphicsview-view.png
144
145 \section2 The Item
146
147 QGraphicsItem is the base class for graphical items in a
148 scene. Graphics View provides several standard items for typical
149 shapes, such as rectangles (QGraphicsRectItem), ellipses
150 (QGraphicsEllipseItem) and text items (QGraphicsTextItem), but the
151 most powerful QGraphicsItem features are available when you write a
152 custom item. Among other things, QGraphicsItem supports the following
153 features:
154
155 \list
156 \o Mouse press, move, release and double click events, as well as mouse
157 hover events, wheel events, and context menu events.
158 \o Keyboard input focus, and key events
159 \o Drag and drop
160 \o Grouping, both through parent-child relationships, and with
161 QGraphicsItemGroup
162 \o Collision detection
163 \endlist
164
165 Items live in a local coordinate system, and like QGraphicsView, it
166 also provides many functions for mapping coordinates between the item
167 and the scene, and from item to item. Also, like QGraphicsView, it can
168 transform its coordinate system using a matrix:
169 QGraphicsItem::transform(). This is useful for rotating and scaling
170 individual items.
171
172 Items can contain other items (children). Parent items'
173 transformations are inherited by all its children. Regardless of an
174 item's accumulated transformation, though, all its functions (e.g.,
175 QGraphicsItem::contains(), QGraphicsItem::boundingRect(),
176 QGraphicsItem::collidesWith()) still operate in local coordinates.
177
178 QGraphicsItem supports collision detection through the
179 QGraphicsItem::shape() function, and QGraphicsItem::collidesWith(),
180 which are both virtual functions. By returning your item's shape as a
181 local coordinate QPainterPath from QGraphicsItem::shape(),
182 QGraphicsItem will handle all collision detection for you. If you want
183 to provide your own collision detection, however, you can reimplement
184 QGraphicsItem::collidesWith().
185
186 \img graphicsview-items.png
187
188 \section1 Classes in the Graphics View Framework
189
190 These classes provide a framework for creating interactive applications.
191
192 \annotatedlist graphicsview-api
193
194 \section1 The Graphics View Coordinate System
195
196 Graphics View is based on the Cartesian coordinate system; items'
197 position and geometry on the scene are represented by sets of two
198 numbers: the x-coordinate, and the y-coordinate. When observing a scene
199 using an untransformed view, one unit on the scene is represented by
200 one pixel on the screen.
201
202 \note The inverted Y-axis coordinate system (where \c y grows upwards)
203 is unsupported as Graphics Views uses Qt's coordinate system.
204
205 There are three effective coordinate systems in play in Graphics View:
206 Item coordinates, scene coordinates, and view coordinates. To simplify
207 your implementation, Graphics View provides convenience functions that
208 allow you to map between the three coordinate systems.
209
210 When rendering, Graphics View's scene coordinates correspond to
211 QPainter's \e logical coordinates, and view coordinates are the
212 same as \e device coordinates. In the \l{Coordinate System}
213 documentation, you can read about the relationship between
214 logical coordinates and device coordinates.
215
216 \img graphicsview-parentchild.png
217
218 \section2 Item Coordinates
219
220 Items live in their own local coordinate system. Their coordinates
221 are usually centered around its center point (0, 0), and this is
222 also the center for all transformations. Geometric primitives in the
223 item coordinate system are often referred to as item points, item
224 lines, or item rectangles.
225
226 When creating a custom item, item coordinates are all you need to
227 worry about; QGraphicsScene and QGraphicsView will perform all
228 transformations for you. This makes it very easy to implement custom
229 items. For example, if you receive a mouse press or a drag enter
230 event, the event position is given in item coordinates. The
231 QGraphicsItem::contains() virtual function, which returns true if a
232 certain point is inside your item, and false otherwise, takes a
233 point argument in item coordinates. Similarly, an item's bounding
234 rect and shape are in item coordinates.
235
236 At item's \e position is the coordinate of the item's center point
237 in its parent's coordinate system; sometimes referred to as \e
238 parent coordinates. The scene is in this sense regarded as all
239 parent-less items' "parent". Top level items' position are in scene
240 coordinates.
241
242 Child coordinates are relative to the parent's coordinates. If the
243 child is untransformed, the difference between a child coordinate
244 and a parent coordinate is the same as the distance between the
245 items in parent coordinates. For example: If an untransformed child
246 item is positioned precisely in its parent's center point, then the
247 two items' coordinate systems will be identical. If the child's
248 position is (10, 0), however, the child's (0, 10) point will
249 correspond to its parent's (10, 10) point.
250
251 Because items' position and transformation are relative to the
252 parent, child items' coordinates are unaffected by the parent's
253 transformation, although the parent's transformation implicitly
254 transforms the child. In the above example, even if the parent is
255 rotated and scaled, the child's (0, 10) point will still correspond
256 to the parent's (10, 10) point. Relative to the scene, however, the
257 child will follow the parent's transformation and position. If the
258 parent is scaled (2x, 2x), the child's position will be at scene
259 coordinate (20, 0), and its (10, 0) point will correspond to the
260 point (40, 0) on the scene.
261
262 With QGraphicsItem::pos() being one of the few exceptions,
263 QGraphicsItem's functions operate in item coordinates, regardless of
264 the item, or any of its parents' transformation. For example, an
265 item's bounding rect (i.e. QGraphicsItem::boundingRect()) is always
266 given in item coordinates.
267
268 \section2 Scene Coordinates
269
270 The scene represents the base coordinate system for all its items.
271 The scene coordinate system describes the position of each top-level
272 item, and also forms the basis for all scene events delivered to the
273 scene from the view. Each item on the scene has a scene position
274 and bounding rectangle (QGraphicsItem::scenePos(),
275 QGraphicsItem::sceneBoundingRect()), in addition to its local item
276 pos and bounding rectangle. The scene position describes the item's
277 position in scene coordinates, and its scene bounding rect forms the
278 basis for how QGraphicsScene determines what areas of the scene have
279 changed. Changes in the scene are communicated through the
280 QGraphicsScene::changed() signal, and the argument is a list of
281 scene rectangles.
282
283 \section2 View Coordinates
284
285 View coordinates are the coordinates of the widget. Each unit in
286 view coordinates corresponds to one pixel. What's special about this
287 coordinate system is that it is relative to the widget, or viewport,
288 and unaffected by the observed scene. The top left corner of
289 QGraphicsView's viewport is always (0, 0), and the bottom right
290 corner is always (viewport width, viewport height). All mouse events
291 and drag and drop events are originally received as view
292 coordinates, and you need to map these coordinates to the scene in
293 order to interact with items.
294
295 \section2 Coordinate Mapping
296
297 Often when dealing with items in a scene, it can be useful to map
298 coordinates and arbitrary shapes from the scene to an item, from
299 item to item, or from the view to the scene. For example, when you
300 click your mouse in QGraphicsView's viewport, you can ask the scene
301 what item is under the cursor by calling
302 QGraphicsView::mapToScene(), followed by
303 QGraphicsScene::itemAt(). If you want to know where in the viewport
304 an item is located, you can call QGraphicsItem::mapToScene() on the
305 item, then QGraphicsView::mapFromScene() on the view. Finally, if
306 you use want to find what items are inside a view ellipse, you can
307 pass a QPainterPath to mapToScene(), and then pass the mapped path
308 to QGraphicsScene::items().
309
310 You can map coordinates and shapes to and from and item's scene by
311 calling QGraphicsItem::mapToScene() and
312 QGraphicsItem::mapFromScene(). You can also map to an item's parent
313 item by calling QGraphicsItem::mapToParent() and
314 QGraphicsItem::mapFromParent(), or between items by calling
315 QGraphicsItem::mapToItem() and QGraphicsItem::mapFromItem(). All
316 mapping functions can map both points, rectangles, polygons and
317 paths.
318
319 The same mapping functions are available in the view, for mapping to
320 and from the scene. QGraphicsView::mapFromScene() and
321 QGraphicsView::mapToScene(). To map from a view to an item, you
322 first map to the scene, and then map from the scene to the item.
323
324 \section1 Key Features
325
326 \section2 Zooming and rotating
327
328 QGraphicsView supports the same affine transformations as QPainter
329 does through QGraphicsView::setMatrix(). By applying a transformation
330 to the view, you can easily add support for common navigation features
331 such as zooming and rotating.
332
333 Here is an example of how to implement zoom and rotate slots in a
334 subclass of QGraphicsView:
335
336 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 2
337
338 The slots could be connected to \l{QToolButton}{QToolButtons} with
339 \l{QAbstractButton::autoRepeat}{autoRepeat} enabled.
340
341 QGraphicsView keeps the center of the view aligned when you transform
342 the view.
343
344 See also the \l{Elastic Nodes Example}{Elastic Nodes} example for
345 code that shows how to implement basic zooming features.
346
347 \section2 Printing
348
349 Graphics View provides single-line printing through its rendering
350 functions, QGraphicsScene::render() and QGraphicsView::render(). The
351 functions provide the same API: You can have the scene or the view
352 render all or parts of their contents into any paint device by passing
353 a QPainter to either of the rendering functions. This example shows
354 how to print the whole scene into a full page, using QPrinter.
355
356 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 3
357
358 The difference between the scene and view rendering functions is that
359 one operates in scene coordinates, and the other in view coordinates.
360 QGraphicsScene::render() is often preferred for printing whole
361 segments of a scene untransformed, such as for plotting geometrical
362 data, or for printing a text document. QGraphicsView::render(), on the
363 other hand, is suitable for taking screenshots; its default behavior
364 is to render the exact contents of the viewport using the provided
365 painter.
366
367 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 4
368
369 When the source and target areas' sizes do not match, the source
370 contents are stretched to fit into the target area. By passing a
371 Qt::AspectRatioMode to the rendering function you are using, you can
372 choose to maintain or ignore the aspect ratio of the scene when the
373 contents are stretched.
374
375 \section2 Drag and Drop
376
377 Because QGraphicsView inherits QWidget indirectly, it already provides
378 the same drag and drop functionality that QWidget provides. In
379 addition, as a convenience, the Graphics View framework provides drag
380 and drop support for the scene, and for each and every item. As the
381 view receives a drag, it translates the drag and drop events into a
382 QGraphicsSceneDragDropEvent, which is then forwarded to the scene. The
383 scene takes over scheduling of this event, and sends it to the first
384 item under the mouse cursor that accepts drops.
385
386 To start a drag from an item, create a QDrag object, passing a pointer
387 to the widget that starts the drag. Items can be observed by many
388 views at the same time, but only one view can start the drag. Drags
389 are in most cases started as a result of pressing or moving the mouse,
390 so in mousePressEvent() or mouseMoveEvent(), you can get the
391 originating widget pointer from the event. For example:
392
393 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 5
394
395 To intercept drag and drop events for the scene, you reimplement
396 QGraphicsScene::dragEnterEvent() and whichever event handlers your
397 particular scene needs, in a QGraphicsItem subclass. You can read more
398 about drag and drop in Graphics View in the documentation for each of
399 QGraphicsScene's event handlers.
400
401 Items can enable drag and drop support by calling
402 QGraphicsItem::setAcceptDrops(). To handle the incoming drag,
403 reimplement QGraphicsItem::dragEnterEvent(),
404 QGraphicsItem::dragMoveEvent(), QGraphicsItem::dragLeaveEvent(), and
405 QGraphicsItem::dropEvent().
406
407 See also the \l{Drag and Drop Robot Example}{Drag and Drop Robot} example
408 for a demonstration of Graphics View's support for drag and drop
409 operations.
410
411 \section2 Cursors and Tooltips
412
413 Like QWidget, QGraphicsItem also supports cursors
414 (QGraphicsItem::setCursor()), and tooltips
415 (QGraphicsItem::setToolTip()). The cursors and tooltips are activated
416 by QGraphicsView as the mouse cursor enters the item's area (detected
417 by calling QGraphicsItem::contains()).
418
419 You can also set a default cursor directly on the view by calling
420 QGraphicsView::setCursor().
421
422 See also the \l{Drag and Drop Robot Example}{Drag and Drop Robot}
423 example for code that implements tooltips and cursor shape handling.
424
425 \section2 Animation
426
427 Graphics View supports animation at several levels. You can
428 easily assemble animation by using the Animation Framework.
429 For that you'll need your items to inherit from
430 QGraphicsObject and associate QPropertyAnimation with
431 them. QPropertyAnimation allows to animate any QObject
432 property.
433
434 Another option is to create a custom item that inherits from QObject
435 and QGraphicsItem. The item can the set up its own timers, and control
436 animations with incremental steps in QObject::timerEvent().
437
438 A third option, which is mostly available for compatibility with
439 QCanvas in Qt 3, is to \e advance the scene by calling
440 QGraphicsScene::advance(), which in turn calls
441 QGraphicsItem::advance().
442
443 \section2 OpenGL Rendering
444
445 To enable OpenGL rendering, you simply set a new QGLWidget as the
446 viewport of QGraphicsView by calling QGraphicsView::setViewport(). If
447 you want OpenGL with antialiasing, you need OpenGL sample buffer
448 support (see QGLFormat::sampleBuffers()).
449
450 Example:
451
452 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 6
453
454 \section2 Item Groups
455
456 By making an item a child of another, you can achieve the most
457 essential feature of item grouping: the items will move together, and
458 all transformations are propagated from parent to child.
459
460 In addition, QGraphicsItemGroup is a special item that combines child
461 event handling with a useful interface for adding and removing items
462 to and from a group. Adding an item to a QGraphicsItemGroup will keep
463 the item's original position and transformation, whereas reparenting
464 items in general will cause the child to reposition itself relative to
465 its new parent. For convenience, you can create
466 \l{QGraphicsItemGroup}s through the scene by calling
467 QGraphicsScene::createItemGroup().
468
469 \section2 Widgets and Layouts
470
471 Qt 4.4 introduced support for geometry and layout-aware items through
472 QGraphicsWidget. This special base item is similar to QWidget, but
473 unlike QWidget, it doesn't inherit from QPaintDevice; rather from
474 QGraphicsItem instead. This allows you to write complete widgets with
475 events, signals & slots, size hints and policies, and you can also
476 manage your widgets geometries in layouts through
477 QGraphicsLinearLayout and QGraphicsGridLayout.
478
479 \section3 QGraphicsWidget
480
481 Building on top of QGraphicsItem's capabilities and lean footprint,
482 QGraphicsWidget provides the best of both worlds: extra
483 functionality from QWidget, such as the style, font, palette, layout
484 direction, and its geometry, and resolution independence and
485 transformation support from QGraphicsItem. Because Graphics View
486 uses real coordinates instead of integers, QGraphicsWidget's
487 geometry functions also operate on QRectF and QPointF. This also
488 applies to frame rects, margins and spacing. With QGraphicsWidget
489 it's not uncommon to specify contents margins of (0.5, 0.5, 0.5,
490 0.5), for example. You can create both subwidgets and "top-level"
491 windows; in some cases you can now use Graphics View for advanced
492 MDI applications.
493
494 Some of QWidget's properties are supported, including window flags
495 and attributes, but not all. You should refer to QGraphicsWidget's
496 class documentation for a complete overview of what is and what is
497 not supported. For example, you can create decorated windows by
498 passing the Qt::Window window flag to QGraphicsWidget's constructor,
499 but Graphics View currently doesn't support the Qt::Sheet and
500 Qt::Drawer flags that are common on Mac OS X.
501
502 The capabilities of QGraphicsWidget are expected to grow depending
503 on community feedback.
504
505 \section3 QGraphicsLayout
506
507 QGraphicsLayout is part of a second-generation layout framework
508 designed specifically for QGraphicsWidget. Its API is very similar
509 to that of QLayout. You can manage widgets and sublayouts inside
510 either QGraphicsLinearLayout and QGraphicsGridLayout. You can also
511 easily write your own layout by subclassing QGraphicsLayout
512 yourself, or add your own QGraphicsItem items to the layout by
513 writing an adaptor subclass of QGraphicsLayoutItem.
514
515 \section2 Embedded Widget Support
516
517 Graphics View provides seamless support for embedding any widget
518 into the scene. You can embed simple widgets, such as QLineEdit or
519 QPushButton, complex widgets such as QTabWidget, and even complete
520 main windows. To embed your widget to the scene, simply call
521 QGraphicsScene::addWidget(), or create an instance of
522 QGraphicsProxyWidget to embed your widget manually.
523
524 Through QGraphicsProxyWidget, Graphics View is able to deeply
525 integrate the client widget features including its cursors,
526 tooltips, mouse, tablet and keyboard events, child widgets,
527 animations, pop-ups (e.g., QComboBox or QCompleter), and the widget's
528 input focus and activation. QGraphicsProxyWidget even integrates the
529 embedded widget's tab order so that you can tab in and out of
530 embedded widgets. You can even embed a new QGraphicsView into your
531 scene to provide complex nested scenes.
532
533 When transforming an embedded widget, Graphics View makes sure that
534 the widget is transformed resolution independently, allowing the
535 fonts and style to stay crisp when zoomed in. (Note that the effect
536 of resolution independence depends on the style.)
537
538 \section1 Performance
539
540 \section2 Floating Point Instructions
541
542 In order to accurately and quickly apply transformations and effects to
543 items, Graphics View is built with the assumption that the user's hardware
544 is able to provide reasonable performance for floating point instructions.
545
546 Many workstations and desktop computers are equipped with suitable hardware
547 to accelerate this kind of computation, but some embedded devices may only
548 provide libraries to handle mathematical operations or emulate floating
549 point instructions in software.
550
551 As a result, certain kinds of effects may be slower than expected on certain
552 devices. It may be possible to compensate for this performance hit by making
553 optimizations in other areas; for example, by using \l{#OpenGL Rendering}{OpenGL}
554 to render a scene. However, any such optimizations may themselves cause a
555 reduction in performance if they also rely on the presence of floating point
556 hardware.
557*/
Note: See TracBrowser for help on using the repository browser.