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