source: trunk/doc/src/graphicsview.qdoc@ 342

Last change on this file since 342 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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