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

Last change on this file since 568 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 28.1 KB
Line 
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
328 mapping functions can map both points, rectangles, polygons and
329 paths.
330
331 The same mapping functions are available in the view, for mapping to
332 and from the scene. QGraphicsView::mapFromScene() and
333 QGraphicsView::mapToScene(). To map from a view to an item, you
334 first map to the scene, and then map from the scene to the item.
335
336 \section1 Key Features
337
338 \section2 Zooming and rotating
339
340 QGraphicsView supports the same affine transformations as QPainter
341 does through QGraphicsView::setMatrix(). By applying a transformation
342 to the view, you can easily add support for common navigation features
343 such as zooming and rotating.
344
345 Here is an example of how to implement zoom and rotate slots in a
346 subclass of QGraphicsView:
347
348 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 2
349
350 The slots could be connected to \l{QToolButton}{QToolButtons} with
351 \l{QAbstractButton::autoRepeat}{autoRepeat} enabled.
352
353 QGraphicsView keeps the center of the view aligned when you transform
354 the view.
355
356 See also the \l{Elastic Nodes Example}{Elastic Nodes} example for
357 code that shows how to implement basic zooming features.
358
359 \section2 Printing
360
361 Graphics View provides single-line printing through its rendering
362 functions, QGraphicsScene::render() and QGraphicsView::render(). The
363 functions provide the same API: You can have the scene or the view
364 render all or parts of their contents into any paint device by passing
365 a QPainter to either of the rendering functions. This example shows
366 how to print the whole scene into a full page, using QPrinter.
367
368 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 3
369
370 The difference between the scene and view rendering functions is that
371 one operates in scene coordinates, and the other in view coordinates.
372 QGraphicsScene::render() is often preferred for printing whole
373 segments of a scene untransformed, such as for plotting geometrical
374 data, or for printing a text document. QGraphicsView::render(), on the
375 other hand, is suitable for taking screenshots; its default behavior
376 is to render the exact contents of the viewport using the provided
377 painter.
378
379 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 4
380
381 When the source and target areas' sizes do not match, the source
382 contents are stretched to fit into the target area. By passing a
383 Qt::AspectRatioMode to the rendering function you are using, you can
384 choose to maintain or ignore the aspect ratio of the scene when the
385 contents are stretched.
386
387 \section2 Drag and Drop
388
389 Because QGraphicsView inherits QWidget indirectly, it already provides
390 the same drag and drop functionality that QWidget provides. In
391 addition, as a convenience, the Graphics View framework provides drag
392 and drop support for the scene, and for each and every item. As the
393 view receives a drag, it translates the drag and drop events into a
394 QGraphicsSceneDragDropEvent, which is then forwarded to the scene. The
395 scene takes over scheduling of this event, and sends it to the first
396 item under the mouse cursor that accepts drops.
397
398 To start a drag from an item, create a QDrag object, passing a pointer
399 to the widget that starts the drag. Items can be observed by many
400 views at the same time, but only one view can start the drag. Drags
401 are in most cases started as a result of pressing or moving the mouse,
402 so in mousePressEvent() or mouseMoveEvent(), you can get the
403 originating widget pointer from the event. For example:
404
405 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 5
406
407 To intercept drag and drop events for the scene, you reimplement
408 QGraphicsScene::dragEnterEvent() and whichever event handlers your
409 particular scene needs, in a QGraphicsItem subclass. You can read more
410 about drag and drop in Graphics View in the documentation for each of
411 QGraphicsScene's event handlers.
412
413 Items can enable drag and drop support by calling
414 QGraphicsItem::setAcceptDrops(). To handle the incoming drag,
415 reimplement QGraphicsItem::dragEnterEvent(),
416 QGraphicsItem::dragMoveEvent(), QGraphicsItem::dragLeaveEvent(), and
417 QGraphicsItem::dropEvent().
418
419 See also the \l{Drag and Drop Robot Example}{Drag and Drop Robot} example
420 for a demonstration of Graphics View's support for drag and drop
421 operations.
422
423 \section2 Cursors and Tooltips
424
425 Like QWidget, QGraphicsItem also supports cursors
426 (QGraphicsItem::setCursor()), and tooltips
427 (QGraphicsItem::setToolTip()). The cursors and tooltips are activated
428 by QGraphicsView as the mouse cursor enters the item's area (detected
429 by calling QGraphicsItem::contains()).
430
431 You can also set a default cursor directly on the view by calling
432 QGraphicsView::setCursor().
433
434 See also the \l{Drag and Drop Robot Example}{Drag and Drop Robot}
435 example for code that implements tooltips and cursor shape handling.
436
437 \section2 Animation
438
439 Graphics View supports animation at several levels. You can easily
440 assemble animation by using the Animation Framework. For that you'll
441 need your items to inherit from QGraphicsObject and associate
442 QPropertyAnimation with them. QPropertyAnimation allows to animate any
443 QObject property.
444
445 Another option is to create a custom item that inherits from QObject
446 and QGraphicsItem. The item can the set up its own timers, and control
447 animations with incremental steps in QObject::timerEvent().
448
449 A third option, which is mostly available for compatibility with
450 QCanvas in Qt 3, is to \e advance the scene by calling
451 QGraphicsScene::advance(), which in turn calls
452 QGraphicsItem::advance().
453
454 \section2 OpenGL Rendering
455
456 To enable OpenGL rendering, you simply set a new QGLWidget as the
457 viewport of QGraphicsView by calling QGraphicsView::setViewport(). If
458 you want OpenGL with antialiasing, you need OpenGL sample buffer
459 support (see QGLFormat::sampleBuffers()).
460
461 Example:
462
463 \snippet doc/src/snippets/code/doc_src_graphicsview.qdoc 6
464
465 \section2 Item Groups
466
467 By making an item a child of another, you can achieve the most
468 essential feature of item grouping: the items will move together, and
469 all transformations are propagated from parent to child.
470
471 In addition, QGraphicsItemGroup is a special item that combines child
472 event handling with a useful interface for adding and removing items
473 to and from a group. Adding an item to a QGraphicsItemGroup will keep
474 the item's original position and transformation, whereas reparenting
475 items in general will cause the child to reposition itself relative to
476 its new parent. For convenience, you can create
477 \l{QGraphicsItemGroup}s through the scene by calling
478 QGraphicsScene::createItemGroup().
479
480 \section2 Widgets and Layouts
481
482 Qt 4.4 introduced support for geometry and layout-aware items through
483 QGraphicsWidget. This special base item is similar to QWidget, but
484 unlike QWidget, it doesn't inherit from QPaintDevice; rather from
485 QGraphicsItem instead. This allows you to write complete widgets with
486 events, signals & slots, size hints and policies, and you can also
487 manage your widgets geometries in layouts through
488 QGraphicsLinearLayout and QGraphicsGridLayout.
489
490 \section3 QGraphicsWidget
491
492 Building on top of QGraphicsItem's capabilities and lean footprint,
493 QGraphicsWidget provides the best of both worlds: extra
494 functionality from QWidget, such as the style, font, palette, layout
495 direction, and its geometry, and resolution independence and
496 transformation support from QGraphicsItem. Because Graphics View
497 uses real coordinates instead of integers, QGraphicsWidget's
498 geometry functions also operate on QRectF and QPointF. This also
499 applies to frame rects, margins and spacing. With QGraphicsWidget
500 it's not uncommon to specify contents margins of (0.5, 0.5, 0.5,
501 0.5), for example. You can create both subwidgets and "top-level"
502 windows; in some cases you can now use Graphics View for advanced
503 MDI applications.
504
505 Some of QWidget's properties are supported, including window flags
506 and attributes, but not all. You should refer to QGraphicsWidget's
507 class documentation for a complete overview of what is and what is
508 not supported. For example, you can create decorated windows by
509 passing the Qt::Window window flag to QGraphicsWidget's constructor,
510 but Graphics View currently doesn't support the Qt::Sheet and
511 Qt::Drawer flags that are common on Mac OS X.
512
513 The capabilities of QGraphicsWidget are expected to grow depending
514 on community feedback.
515
516 \section3 QGraphicsLayout
517
518 QGraphicsLayout is part of a second-generation layout framework
519 designed specifically for QGraphicsWidget. Its API is very similar
520 to that of QLayout. You can manage widgets and sublayouts inside
521 either QGraphicsLinearLayout and QGraphicsGridLayout. You can also
522 easily write your own layout by subclassing QGraphicsLayout
523 yourself, or add your own QGraphicsItem items to the layout by
524 writing an adaptor subclass of QGraphicsLayoutItem.
525
526 \section2 Embedded Widget Support
527
528 Graphics View provides seamless support for embedding any widget
529 into the scene. You can embed simple widgets, such as QLineEdit or
530 QPushButton, complex widgets such as QTabWidget, and even complete
531 main windows. To embed your widget to the scene, simply call
532 QGraphicsScene::addWidget(), or create an instance of
533 QGraphicsProxyWidget to embed your widget manually.
534
535 Through QGraphicsProxyWidget, Graphics View is able to deeply
536 integrate the client widget features including its cursors,
537 tooltips, mouse, tablet and keyboard events, child widgets,
538 animations, pop-ups (e.g., QComboBox or QCompleter), and the widget's
539 input focus and activation. QGraphicsProxyWidget even integrates the
540 embedded widget's tab order so that you can tab in and out of
541 embedded widgets. You can even embed a new QGraphicsView into your
542 scene to provide complex nested scenes.
543
544 When transforming an embedded widget, Graphics View makes sure that
545 the widget is transformed resolution independently, allowing the
546 fonts and style to stay crisp when zoomed in. (Note that the effect
547 of resolution independence depends on the style.)
548
549 \section1 Performance
550
551 \section2 Floating Point Instructions
552
553 In order to accurately and quickly apply transformations and effects to
554 items, Graphics View is built with the assumption that the user's hardware
555 is able to provide reasonable performance for floating point instructions.
556
557 Many workstations and desktop computers are equipped with suitable hardware
558 to accelerate this kind of computation, but some embedded devices may only
559 provide libraries to handle mathematical operations or emulate floating
560 point instructions in software.
561
562 As a result, certain kinds of effects may be slower than expected on certain
563 devices. It may be possible to compensate for this performance hit by making
564 optimizations in other areas; for example, by using \l{#OpenGL Rendering}{OpenGL}
565 to render a scene. However, any such optimizations may themselves cause a
566 reduction in performance if they also rely on the presence of floating point
567 hardware.
568*/
Note: See TracBrowser for help on using the repository browser.