1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 \brief The QGraphicsItem class is the base class for all graphical
45 items in a QGraphicsScene.
48 \ingroup graphicsview-api
51 It provides a light-weight foundation for writing your own custom items.
52 This includes defining the item's geometry, collision detection, its
53 painting implementation and item interaction through its event handlers.
54 QGraphicsItem is part of the \l{Graphics View Framework}
56 \image graphicsview-items.png
58 For convenience, Qt provides a set of standard graphics items for the most
59 common shapes. These are:
62 \li QGraphicsEllipseItem provides an ellipse item
63 \li QGraphicsLineItem provides a line item
64 \li QGraphicsPathItem provides an arbitrary path item
65 \li QGraphicsPixmapItem provides a pixmap item
66 \li QGraphicsPolygonItem provides a polygon item
67 \li QGraphicsRectItem provides a rectangular item
68 \li QGraphicsSimpleTextItem provides a simple text label item
69 \li QGraphicsTextItem provides an advanced text browser item
72 All of an item's geometric information is based on its local coordinate
73 system. The item's position, pos(), is the only function that does not
74 operate in local coordinates, as it returns a position in parent
75 coordinates. \l {The Graphics View Coordinate System} describes the coordinate
78 You can set whether an item should be visible (i.e., drawn, and accepting
79 events), by calling setVisible(). Hiding an item will also hide its
80 children. Similarly, you can enable or disable an item by calling
81 setEnabled(). If you disable an item, all its children will also be
82 disabled. By default, items are both visible and enabled. To toggle
83 whether an item is selected or not, first enable selection by setting
84 the ItemIsSelectable flag, and then call setSelected(). Normally,
85 selection is toggled by the scene, as a result of user interaction.
87 To write your own graphics item, you first create a subclass of
88 QGraphicsItem, and then start by implementing its two pure virtual public
89 functions: boundingRect(), which returns an estimate of the area painted
90 by the item, and paint(), which implements the actual painting. For
93 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 0
95 The boundingRect() function has many different purposes.
96 QGraphicsScene bases its item index on boundingRect(), and
97 QGraphicsView uses it both for culling invisible items, and for
98 determining the area that needs to be recomposed when drawing
99 overlapping items. In addition, QGraphicsItem's collision
100 detection mechanisms use boundingRect() to provide an efficient
101 cut-off. The fine grained collision algorithm in
102 collidesWithItem() is based on calling shape(), which returns an
103 accurate outline of the item's shape as a QPainterPath.
105 QGraphicsScene expects all items boundingRect() and shape() to
106 remain unchanged unless it is notified. If you want to change an
107 item's geometry in any way, you must first call
108 prepareGeometryChange() to allow QGraphicsScene to update its
111 Collision detection can be done in two ways:
115 \li Reimplement shape() to return an accurate shape for your item,
116 and rely on the default implementation of collidesWithItem() to do
117 shape-shape intersection. This can be rather expensive if the
120 \li Reimplement collidesWithItem() to provide your own custom item
121 and shape collision algorithm.
125 The contains() function can be called to determine whether the item \e
126 contains a point or not. This function can also be reimplemented by the
127 item. The default behavior of contains() is based on calling shape().
129 Items can contain other items, and also be contained by other items. All
130 items can have a parent item and a list of children. Unless the item has
131 no parent, its position is in \e parent coordinates (i.e., the parent's
132 local coordinates). Parent items propagate both their position and their
133 transformation to all children.
135 \img graphicsview-parentchild.png
137 \target Transformations
138 \section1 Transformations
140 QGraphicsItem supports projective transformations in addition to its base
141 position, pos(). There are several ways to change an item's transformation.
142 For simple transformations, you can call either of the convenience
143 functions setRotation() or setScale(), or you can pass any transformation
144 matrix to setTransform(). For advanced transformation control you also have
145 the option of setting several combined transformations by calling
146 setTransformations().
148 Item transformations accumulate from parent to child, so if both a parent
149 and child item are rotated 90 degrees, the child's total transformation
150 will be 180 degrees. Similarly, if the item's parent is scaled to 2x its
151 original size, its children will also be twice as large. An item's
152 transformation does not affect its own local geometry; all geometry
153 functions (e.g., contains(), update(), and all the mapping functions) still
154 operate in local coordinates. For convenience, QGraphicsItem provides the
155 functions sceneTransform(), which returns the item's total transformation
156 matrix (including its position and all parents' positions and
157 transformations), and scenePos(), which returns its position in scene
158 coordinates. To reset an item's matrix, call resetTransform().
160 Certain transformation operations produce a different outcome depending on
161 the order in which they are applied. For example, if you scale an
162 transform, and then rotate it, you may get a different result than if the
163 transform was rotated first. However, the order you set the transformation
164 properties on QGraphicsItem does not affect the resulting transformation;
165 QGraphicsItem always applies the properties in a fixed, defined order:
168 \li The item's base transform is applied (transform())
169 \li The item's transformations list is applied in order (transformations())
170 \li The item is rotated relative to its transform origin point (rotation(), transformOriginPoint())
171 \li The item is scaled relative to its transform origin point (scale(), transformOriginPoint())
176 The paint() function is called by QGraphicsView to paint the item's
177 contents. The item has no background or default fill of its own; whatever
178 is behind the item will shine through all areas that are not explicitly
179 painted in this function. You can call update() to schedule a repaint,
180 optionally passing the rectangle that needs a repaint. Depending on
181 whether or not the item is visible in a view, the item may or may not be
182 repainted; there is no equivalent to QWidget::repaint() in QGraphicsItem.
184 Items are painted by the view, starting with the parent items and then
185 drawing children, in ascending stacking order. You can set an item's
186 stacking order by calling setZValue(), and test it by calling
187 zValue(), where items with low z-values are painted before items with
188 high z-values. Stacking order applies to sibling items; parents are always
189 drawn before their children.
193 All items are drawn in a defined, stable order, and this same order decides
194 which items will receive mouse input first when you click on the scene.
195 Normally you don't have to worry about sorting, as the items follow a
196 "natural order", following the logical structure of the scene.
198 An item's children are stacked on top of the parent, and sibling items are
199 stacked by insertion order (i.e., in the same order that they were either
200 added to the scene, or added to the same parent). If you add item A, and
201 then B, then B will be on top of A. If you then add C, the items' stacking
202 order will be A, then B, then C.
204 \image graphicsview-zorder.png
206 This example shows the stacking order of all limbs of the robot from the
207 \l{graphicsview/dragdroprobot}{Drag and Drop Robot} example. The torso is
208 the root item (all other items are children or descendants of the torso),
209 so it is drawn first. Next, the head is drawn, as it is the first item in
210 the torso's list of children. Then the upper left arm is drawn. As the
211 lower arm is a child of the upper arm, the lower arm is then drawn,
212 followed by the upper arm's next sibling, which is the upper right arm, and
215 For advanced users, there are ways to alter how your items are sorted:
218 \li You can call setZValue() on an item to explicitly stack it on top of, or
219 under, other sibling items. The default Z value for an item is 0. Items
220 with the same Z value are stacked by insertion order.
222 \li You can call stackBefore() to reorder the list of children. This will
223 directly modify the insertion order.
225 \li You can set the ItemStacksBehindParent flag to stack a child item behind
229 The stacking order of two sibling items also counts for each item's
230 children and descendant items. So if one item is on top of another, then
231 all its children will also be on top of all the other item's children as
236 QGraphicsItem receives events from QGraphicsScene through the virtual
237 function sceneEvent(). This function distributes the most common events
238 to a set of convenience event handlers:
241 \li contextMenuEvent() handles context menu events
242 \li focusInEvent() and focusOutEvent() handle focus in and out events
243 \li hoverEnterEvent(), hoverMoveEvent(), and hoverLeaveEvent() handles
244 hover enter, move and leave events
245 \li inputMethodEvent() handles input events, for accessibility support
246 \li keyPressEvent() and keyReleaseEvent() handle key press and release events
247 \li mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), and
248 mouseDoubleClickEvent() handles mouse press, move, release, click and
252 You can filter events for any other item by installing event filters. This
253 functionality is separate from Qt's regular event filters (see
254 QObject::installEventFilter()), which only work on subclasses of QObject. After
255 installing your item as an event filter for another item by calling
256 installSceneEventFilter(), the filtered events will be received by the virtual
257 function sceneEventFilter(). You can remove item event filters by calling
258 removeSceneEventFilter().
260 \section1 Custom Data
262 Sometimes it's useful to register custom data with an item, be it a custom
263 item, or a standard item. You can call setData() on any item to store data
264 in it using a key-value pair (the key being an integer, and the value is a
265 QVariant). To get custom data from an item, call data(). This
266 functionality is completely untouched by Qt itself; it is provided for the
269 \sa QGraphicsScene, QGraphicsView, {Graphics View Framework}
273 \variable QGraphicsItem::Type
275 The type value returned by the virtual type() function in standard
276 graphics item classes in Qt. All such standard graphics item
277 classes in Qt are associated with a unique value for Type,
278 e.g. the value returned by QGraphicsPathItem::type() is 2.
280 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 18
284 \variable QGraphicsItem::UserType
286 The lowest permitted type value for custom items (subclasses
287 of QGraphicsItem or any of the standard items). This value is
288 used in conjunction with a reimplementation of QGraphicsItem::type()
289 and declaring a Type enum value. Example:
291 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 1
293 \note UserType = 65536
297 \enum QGraphicsItem::GraphicsItemFlag
299 This enum describes different flags that you can set on an item to
300 toggle different features in the item's behavior.
302 All flags are disabled by default.
304 \value ItemIsMovable The item supports interactive movement using
305 the mouse. By clicking on the item and then dragging, the item
306 will move together with the mouse cursor. If the item has
307 children, all children are also moved. If the item is part of a
308 selection, all selected items are also moved. This feature is
309 provided as a convenience through the base implementation of
310 QGraphicsItem's mouse event handlers.
312 \value ItemIsSelectable The item supports selection. Enabling this
313 feature will enable setSelected() to toggle selection for the
314 item. It will also let the item be selected automatically as a
315 result of calling QGraphicsScene::setSelectionArea(), by clicking
316 on an item, or by using rubber band selection in QGraphicsView.
318 \value ItemIsFocusable The item supports keyboard input focus (i.e., it is
319 an input item). Enabling this flag will allow the item to accept focus,
320 which again allows the delivery of key events to
321 QGraphicsItem::keyPressEvent() and QGraphicsItem::keyReleaseEvent().
323 \value ItemClipsToShape The item clips to its own shape. The item cannot
324 draw or receive mouse, tablet, drag and drop or hover events outside its
325 shape. It is disabled by default. This behavior is enforced by
326 QGraphicsView::drawItems() or QGraphicsScene::drawItems(). This flag was
327 introduced in Qt 4.3.
329 \value ItemClipsChildrenToShape The item clips the painting of all its
330 descendants to its own shape. Items that are either direct or indirect
331 children of this item cannot draw outside this item's shape. By default,
332 this flag is disabled; children can draw anywhere. This behavior is
333 enforced by QGraphicsView::drawItems() or
334 QGraphicsScene::drawItems(). This flag was introduced in Qt 4.3.
336 \value ItemIgnoresTransformations The item ignores inherited
337 transformations (i.e., its position is still anchored to its parent, but
338 the parent or view rotation, zoom or shear transformations are ignored).
339 This flag is useful for keeping text label items horizontal and unscaled,
340 so they will still be readable if the view is transformed. When set, the
341 item's view geometry and scene geometry will be maintained separately. You
342 must call deviceTransform() to map coordinates and detect collisions in
343 the view. By default, this flag is disabled. This flag was introduced in
344 Qt 4.3. \note With this flag set you can still scale the item itself, and
345 that scale transformation will influence the item's children.
347 \value ItemIgnoresParentOpacity The item ignores its parent's opacity. The
348 item's effective opacity is the same as its own; it does not combine with
349 the parent's opacity. This flags allows your item to keep its absolute
350 opacity even if the parent is semitransparent. This flag was introduced in
353 \value ItemDoesntPropagateOpacityToChildren The item doesn't propagate its
354 opacity to its children. This flag allows you to create a semitransparent
355 item that does not affect the opacity of its children. This flag was
356 introduced in Qt 4.5.
358 \value ItemStacksBehindParent The item is stacked behind its parent. By
359 default, child items are stacked on top of the parent item. But setting
360 this flag, the child will be stacked behind it. This flag is useful for
361 drop shadow effects and for decoration objects that follow the parent
362 item's geometry without drawing on top of it. This flag was introduced
365 \value ItemUsesExtendedStyleOption The item makes use of either
366 \l{QStyleOptionGraphicsItem::} {exposedRect} or
367 \l{QStyleOptionGraphicsItem::} {matrix} in
368 QStyleOptionGraphicsItem. By default, the
369 \l{QStyleOptionGraphicsItem::} {exposedRect} is initialized to the
370 item's boundingRect() and the
371 \l{QStyleOptionGraphicsItem::}{matrix} is untransformed. You can
372 enable this flag for the style options to be set up with more
373 fine-grained values. Note that
374 QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag
375 and always initialized to 1. Use
376 QStyleOptionGraphicsItem::levelOfDetailFromTransform() if you need
377 a higher value. This flag was introduced in Qt 4.6.
379 \value ItemHasNoContents The item does not paint anything (i.e., calling
380 paint() on the item has no effect). You should set this flag on items that
381 do not need to be painted to ensure that Graphics View avoids unnecessary
382 painting preparations. This flag was introduced in Qt 4.6.
384 \value ItemSendsGeometryChanges The item enables itemChange()
385 notifications for ItemPositionChange, ItemPositionHasChanged,
386 ItemMatrixChange, ItemTransformChange, ItemTransformHasChanged,
387 ItemRotationChange, ItemRotationHasChanged, ItemScaleChange, ItemScaleHasChanged,
388 ItemTransformOriginPointChange, and ItemTransformOriginPointHasChanged. For
389 performance reasons, these notifications are disabled by default. You must
390 enable this flag to receive notifications for position and transform
391 changes. This flag was introduced in Qt 4.6.
393 \value ItemAcceptsInputMethod The item supports input methods typically
394 used for Asian languages.
395 This flag was introduced in Qt 4.6.
397 \value ItemNegativeZStacksBehindParent The item automatically
398 stacks behind it's parent if it's z-value is negative. This flag
399 enables setZValue() to toggle ItemStacksBehindParent. This flag
400 was introduced in Qt 4.6.
402 \value ItemIsPanel The item is a panel. A panel provides activation and
403 contained focus handling. Only one panel can be active at a time (see
404 QGraphicsItem::isActive()). When no panel is active, QGraphicsScene
405 activates all non-panel items. Window items (i.e.,
406 QGraphicsItem::isWindow() returns true) are panels. This flag was
407 introduced in Qt 4.6.
409 \omitvalue ItemIsFocusScope \omit Internal only (for now). \endomit
411 \value ItemSendsScenePositionChanges The item enables itemChange()
412 notifications for ItemScenePositionHasChanged. For performance reasons,
413 these notifications are disabled by default. You must enable this flag
414 to receive notifications for scene position changes. This flag was
415 introduced in Qt 4.6.
417 \omitvalue ItemStopsClickFocusPropagation \omit The item stops propagating
418 click focus to items underneath when being clicked on. This flag
419 allows you create a non-focusable item that can be clicked on without
420 changing the focus. \endomit
422 \omitvalue ItemStopsFocusHandling \omit Same as
423 ItemStopsClickFocusPropagation, but also suppresses focus-out. This flag
424 allows you to completely take over focus handling.
425 This flag was introduced in Qt 4.7. \endomit
429 \enum QGraphicsItem::GraphicsItemChange
431 This enum describes the state changes that are notified by
432 QGraphicsItem::itemChange(). The notifications are sent as the state
433 changes, and in some cases, adjustments can be made (see the documentation
434 for each change for details).
436 Note: Be careful with calling functions on the QGraphicsItem itself inside
437 itemChange(), as certain function calls can lead to unwanted
438 recursion. For example, you cannot call setPos() in itemChange() on an
439 ItemPositionChange notification, as the setPos() function will again call
440 itemChange(ItemPositionChange). Instead, you can return the new, adjusted
441 position from itemChange().
443 \value ItemEnabledChange The item's enabled state changes. If the item is
444 presently enabled, it will become disabled, and vice verca. The value
445 argument is the new enabled state (i.e., true or false). Do not call
446 setEnabled() in itemChange() as this notification is delivered. Instead,
447 you can return the new state from itemChange().
449 \value ItemEnabledHasChanged The item's enabled state has changed. The
450 value argument is the new enabled state (i.e., true or false). Do not call
451 setEnabled() in itemChange() as this notification is delivered. The return
454 \value ItemMatrixChange The item's affine transformation matrix is
455 changing. This value is obsolete; you can use ItemTransformChange instead.
457 \value ItemPositionChange The item's position changes. This notification
458 is sent if the ItemSendsGeometryChanges flag is enabled, and when the
459 item's local position changes, relative to its parent (i.e., as a result
460 of calling setPos() or moveBy()). The value argument is the new position
461 (i.e., a QPointF). You can call pos() to get the original position. Do
462 not call setPos() or moveBy() in itemChange() as this notification is
463 delivered; instead, you can return the new, adjusted position from
464 itemChange(). After this notification, QGraphicsItem immediately sends the
465 ItemPositionHasChanged notification if the position changed.
467 \value ItemPositionHasChanged The item's position has changed. This
468 notification is sent if the ItemSendsGeometryChanges flag is enabled, and
469 after the item's local position, relative to its parent, has changed. The
470 value argument is the new position (the same as pos()), and QGraphicsItem
471 ignores the return value for this notification (i.e., a read-only
474 \value ItemTransformChange The item's transformation matrix changes. This
475 notification is send if the ItemSendsGeometryChanges flag is enabled, and
476 when the item's local transformation matrix changes (i.e., as a result of
477 calling setTransform(). The value argument is the new matrix (i.e., a
478 QTransform); to get the old matrix, call transform(). Do not call
479 setTransform() or set any of the transformation properties in itemChange()
480 as this notification is delivered; instead, you can return the new matrix
481 from itemChange(). This notification is not sent if you change the
482 transformation properties.
484 \value ItemTransformHasChanged The item's transformation matrix has
485 changed either because setTransform is called, or one of the
486 transformation properties is changed. This notification is sent if the
487 ItemSendsGeometryChanges flag is enabled, and after the item's local
488 transformation matrix has changed. The value argument is the new matrix
489 (same as transform()), and QGraphicsItem ignores the return value for this
490 notification (i.e., a read-only notification).
492 \value ItemRotationChange The item's rotation property changes. This
493 notification is sent if the ItemSendsGeometryChanges flag is enabled, and
494 when the item's rotation property changes (i.e., as a result of calling
495 setRotation()). The value argument is the new rotation (i.e., a double);
496 to get the old rotation, call rotation(). Do not call setRotation() in
497 itemChange() as this notification is delivered; instead, you can return
498 the new rotation from itemChange().
500 \value ItemRotationHasChanged The item's rotation property has changed.
501 This notification is sent if the ItemSendsGeometryChanges flag is enabled,
502 and after the item's rotation property has changed. The value argument is
503 the new rotation (i.e., a double), and QGraphicsItem ignores the return
504 value for this notification (i.e., a read-only notification). Do not call
505 setRotation() in itemChange() as this notification is delivered.
507 \value ItemScaleChange The item's scale property changes. This notification
508 is sent if the ItemSendsGeometryChanges flag is enabled, and when the item's
509 scale property changes (i.e., as a result of calling setScale()). The value
510 argument is the new scale (i.e., a double); to get the old scale, call
511 scale(). Do not call setScale() in itemChange() as this notification is
512 delivered; instead, you can return the new scale from itemChange().
514 \value ItemScaleHasChanged The item's scale property has changed. This
515 notification is sent if the ItemSendsGeometryChanges flag is enabled, and
516 after the item's scale property has changed. The value argument is the new
517 scale (i.e., a double), and QGraphicsItem ignores the return value for this
518 notification (i.e., a read-only notification). Do not call setScale() in
519 itemChange() as this notification is delivered.
521 \value ItemTransformOriginPointChange The item's transform origin point
522 property changes. This notification is sent if the ItemSendsGeometryChanges
523 flag is enabled, and when the item's transform origin point property changes
524 (i.e., as a result of calling setTransformOriginPoint()). The value argument
525 is the new origin point (i.e., a QPointF); to get the old origin point, call
526 transformOriginPoint(). Do not call setTransformOriginPoint() in itemChange()
527 as this notification is delivered; instead, you can return the new transform
528 origin point from itemChange().
530 \value ItemTransformOriginPointHasChanged The item's transform origin point
531 property has changed. This notification is sent if the ItemSendsGeometryChanges
532 flag is enabled, and after the item's transform origin point property has
533 changed. The value argument is the new origin point (i.e., a QPointF), and
534 QGraphicsItem ignores the return value for this notification (i.e., a read-only
535 notification). Do not call setTransformOriginPoint() in itemChange() as this
536 notification is delivered.
538 \value ItemSelectedChange The item's selected state changes. If the item is
539 presently selected, it will become unselected, and vice verca. The value
540 argument is the new selected state (i.e., true or false). Do not call
541 setSelected() in itemChange() as this notification is delivered; instead, you
542 can return the new selected state from itemChange().
544 \value ItemSelectedHasChanged The item's selected state has changed. The
545 value argument is the new selected state (i.e., true or false). Do not
546 call setSelected() in itemChange() as this notification is delivered. The
547 return value is ignored.
549 \value ItemVisibleChange The item's visible state changes. If the item is
550 presently visible, it will become invisible, and vice verca. The value
551 argument is the new visible state (i.e., true or false). Do not call
552 setVisible() in itemChange() as this notification is delivered; instead,
553 you can return the new visible state from itemChange().
555 \value ItemVisibleHasChanged The item's visible state has changed. The
556 value argument is the new visible state (i.e., true or false). Do not call
557 setVisible() in itemChange() as this notification is delivered. The return
560 \value ItemParentChange The item's parent changes. The value argument is
561 the new parent item (i.e., a QGraphicsItem pointer). Do not call
562 setParentItem() in itemChange() as this notification is delivered;
563 instead, you can return the new parent from itemChange().
565 \value ItemParentHasChanged The item's parent has changed. The value
566 argument is the new parent (i.e., a pointer to a QGraphicsItem). Do not
567 call setParentItem() in itemChange() as this notification is
568 delivered. The return value is ignored.
570 \value ItemChildAddedChange A child is added to this item. The value
571 argument is the new child item (i.e., a QGraphicsItem pointer). Do not
572 pass this item to any item's setParentItem() function as this notification
573 is delivered. The return value is unused; you cannot adjust anything in
574 this notification. Note that the new child might not be fully constructed
575 when this notification is sent; calling pure virtual functions on
576 the child can lead to a crash.
578 \value ItemChildRemovedChange A child is removed from this item. The value
579 argument is the child item that is about to be removed (i.e., a
580 QGraphicsItem pointer). The return value is unused; you cannot adjust
581 anything in this notification.
583 \value ItemSceneChange The item is moved to a new scene. This notification is
584 also sent when the item is added to its initial scene, and when it is removed.
585 The item's scene() is the old scene (or 0 if the item has not been added to a
586 scene yet). The value argument is the new scene (i.e., a QGraphicsScene
587 pointer), or a null pointer if the item is removed from a scene. Do not
588 override this change by passing this item to QGraphicsScene::addItem() as this
589 notification is delivered; instead, you can return the new scene from
590 itemChange(). Use this feature with caution; objecting to a scene change can
591 quickly lead to unwanted recursion.
593 \value ItemSceneHasChanged The item's scene has changed. The item's scene() is
594 the new scene. This notification is also sent when the item is added to its
595 initial scene, and when it is removed.The value argument is the new scene
596 (i.e., a pointer to a QGraphicsScene). Do not call setScene() in itemChange()
597 as this notification is delivered. The return value is ignored.
599 \value ItemCursorChange The item's cursor changes. The value argument is
600 the new cursor (i.e., a QCursor). Do not call setCursor() in itemChange()
601 as this notification is delivered. Instead, you can return a new cursor
604 \value ItemCursorHasChanged The item's cursor has changed. The value
605 argument is the new cursor (i.e., a QCursor). Do not call setCursor() as
606 this notification is delivered. The return value is ignored.
608 \value ItemToolTipChange The item's tooltip changes. The value argument is
609 the new tooltip (i.e., a QToolTip). Do not call setToolTip() in
610 itemChange() as this notification is delivered. Instead, you can return a
611 new tooltip from itemChange().
613 \value ItemToolTipHasChanged The item's tooltip has changed. The value
614 argument is the new tooltip (i.e., a QToolTip). Do not call setToolTip()
615 as this notification is delivered. The return value is ignored.
617 \value ItemFlagsChange The item's flags change. The value argument is the
618 new flags (i.e., a quint32). Do not call setFlags() in itemChange() as
619 this notification is delivered. Instead, you can return the new flags from
622 \value ItemFlagsHaveChanged The item's flags have changed. The value
623 argument is the new flags (i.e., a quint32). Do not call setFlags() in
624 itemChange() as this notification is delivered. The return value is
627 \value ItemZValueChange The item's Z-value changes. The value argument is
628 the new Z-value (i.e., a double). Do not call setZValue() in itemChange()
629 as this notification is delivered. Instead, you can return a new Z-value
632 \value ItemZValueHasChanged The item's Z-value has changed. The value
633 argument is the new Z-value (i.e., a double). Do not call setZValue() as
634 this notification is delivered. The return value is ignored.
636 \value ItemOpacityChange The item's opacity changes. The value argument is
637 the new opacity (i.e., a double). Do not call setOpacity() in itemChange()
638 as this notification is delivered. Instead, you can return a new opacity
641 \value ItemOpacityHasChanged The item's opacity has changed. The value
642 argument is the new opacity (i.e., a double). Do not call setOpacity() as
643 this notification is delivered. The return value is ignored.
645 \value ItemScenePositionHasChanged The item's scene position has changed.
646 This notification is sent if the ItemSendsScenePositionChanges flag is
647 enabled, and after the item's scene position has changed (i.e., the
648 position or transformation of the item itself or the position or
649 transformation of any ancestor has changed). The value argument is the
650 new scene position (the same as scenePos()), and QGraphicsItem ignores
651 the return value for this notification (i.e., a read-only notification).
655 \enum QGraphicsItem::CacheMode
658 This enum describes QGraphicsItem's cache modes. Caching is used to speed
659 up rendering by allocating and rendering to an off-screen pixel buffer,
660 which can be reused when the item requires redrawing. For some paint
661 devices, the cache is stored directly in graphics memory, which makes
662 rendering very quick.
664 \value NoCache The default; all item caching is
665 disabled. QGraphicsItem::paint() is called every time the item needs
668 \value ItemCoordinateCache Caching is enabled for the item's logical
669 (local) coordinate system. QGraphicsItem creates an off-screen pixel
670 buffer with a configurable size / resolution that you can pass to
671 QGraphicsItem::setCacheMode(). Rendering quality will typically degrade,
672 depending on the resolution of the cache and the item transformation. The
673 first time the item is redrawn, it will render itself into the cache, and
674 the cache is then reused for every subsequent expose. The cache is also
675 reused as the item is transformed. To adjust the resolution of the cache,
676 you can call setCacheMode() again.
678 \value DeviceCoordinateCache Caching is enabled at the paint device level,
679 in device coordinates. This mode is for items that can move, but are not
680 rotated, scaled or sheared. If the item is transformed directly or
681 indirectly, the cache will be regenerated automatically. Unlike
682 ItemCoordinateCacheMode, DeviceCoordinateCache always renders at maximum
685 \sa QGraphicsItem::setCacheMode()
689 \enum QGraphicsItem::Extension
692 Note: This is provided as a hook to avoid future problems related
693 to adding virtual functions. See also extension(),
694 supportsExtension() and setExtension().
698 \enum QGraphicsItem::PanelModality
701 This enum specifies the behavior of a modal panel. A modal panel
702 is one that blocks input to other panels. Note that items that
703 are children of a modal panel are not blocked.
707 \value NonModal The panel is not modal and does not block input to
708 other panels. This is the default value for panels.
710 \value PanelModal The panel is modal to a single item hierarchy
711 and blocks input to its parent pane, all grandparent panels, and
712 all siblings of its parent and grandparent panels.
714 \value SceneModal The window is modal to the entire scene and
715 blocks input to all panels.
717 \sa QGraphicsItem::setPanelModality(), QGraphicsItem::panelModality(), QGraphicsItem::ItemIsPanel
720 #include "qgraphicsitem.h"
722 #ifndef QT_NO_GRAPHICSVIEW
724 #include "qgraphicsscene.h"
725 #include "qgraphicsscene_p.h"
726 #include "qgraphicssceneevent.h"
727 #include "qgraphicsview.h"
728 #include "qgraphicswidget.h"
729 #include "qgraphicsproxywidget.h"
730 #include "qgraphicsscenebsptreeindex_p.h"
731 #include <QtCore/qbitarray.h>
732 #include <QtCore/qdebug.h>
733 #include <QtCore/qpoint.h>
734 #include <QtCore/qstack.h>
735 #include <QtCore/qtimer.h>
736 #include <QtCore/qvariant.h>
737 #include <QtCore/qvarlengtharray.h>
738 #include <QtCore/qnumeric.h>
739 #include <QtWidgets/qapplication.h>
740 #include <QtGui/qbitmap.h>
741 #include <QtGui/qpainter.h>
742 #include <QtGui/qpainterpath.h>
743 #include <QtGui/qpixmapcache.h>
744 #include <QtWidgets/qstyleoption.h>
745 #include <QtGui/qevent.h>
746 #include <QtGui/qinputmethod.h>
747 #include <QtWidgets/qgraphicseffect.h>
748 #ifndef QT_NO_ACCESSIBILITY
749 # include "qaccessible.h"
752 #include <private/qgraphicsitem_p.h>
753 #include <private/qgraphicswidget_p.h>
754 #include <private/qwidgettextcontrol_p.h>
755 #include <private/qtextdocumentlayout_p.h>
756 #include <private/qtextengine_p.h>
757 #include <private/qwidget_p.h>
758 #include <private/qapplication_p.h>
761 #include <private/qt_x11_p.h>
762 #include <private/qpixmap_x11_p.h>
765 #include <private/qgesturemanager_p.h>
771 static inline void _q_adjustRect(QRect *rect)
775 rect->adjust(0, 0, 1, 0);
777 rect->adjust(0, 0, 0, 1);
781 ### Move this into QGraphicsItemPrivate
783 class QGraphicsItemCustomDataStore
786 QHash<const QGraphicsItem *, QMap<int, QVariant> > data;
788 Q_GLOBAL_STATIC(QGraphicsItemCustomDataStore, qt_dataStore)
793 Returns a QPainterPath of \a path when stroked with the \a pen.
794 Ignoring dash pattern.
796 static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)
798 // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
799 // if we pass a value of 0.0 to QPainterPathStroker::setWidth()
800 const qreal penWidthZero = qreal(0.00000001);
802 if (path == QPainterPath())
804 QPainterPathStroker ps;
805 ps.setCapStyle(pen.capStyle());
806 if (pen.widthF() <= 0.0)
807 ps.setWidth(penWidthZero);
809 ps.setWidth(pen.widthF());
810 ps.setJoinStyle(pen.joinStyle());
811 ps.setMiterLimit(pen.miterLimit());
812 QPainterPath p = ps.createStroke(path);
820 Propagates the ancestor flag \a flag with value \a enabled to all this
821 item's children. If \a root is false, the flag is also set on this item
824 void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
825 AncestorFlag flag, bool enabled, bool root)
829 // For root items only. This is the item that has either enabled or
830 // disabled \a childFlag, or has been reparented.
831 switch (int(childFlag)) {
833 flag = AncestorFiltersChildEvents;
834 enabled = q->filtersChildEvents();
837 flag = AncestorHandlesChildEvents;
838 enabled = q->handlesChildEvents();
840 case QGraphicsItem::ItemClipsChildrenToShape:
841 flag = AncestorClipsChildren;
842 enabled = flags & QGraphicsItem::ItemClipsChildrenToShape;
844 case QGraphicsItem::ItemIgnoresTransformations:
845 flag = AncestorIgnoresTransformations;
846 enabled = flags & QGraphicsItem::ItemIgnoresTransformations;
853 // Inherit the enabled-state from our parents.
854 if ((parent->d_ptr->ancestorFlags & flag)
855 || (int(parent->d_ptr->flags & childFlag) == childFlag)
856 || (childFlag == -1 && parent->d_ptr->handlesChildEvents)
857 || (childFlag == -2 && parent->d_ptr->filtersDescendantEvents)) {
859 ancestorFlags |= flag;
861 ancestorFlags &= ~flag;
864 // Top-level root items don't have any ancestors, so there are no
865 // ancestor flags either.
869 // Don't set or propagate the ancestor flag if it's already correct.
870 if (((ancestorFlags & flag) && enabled) || (!(ancestorFlags & flag) && !enabled))
875 ancestorFlags |= flag;
877 ancestorFlags &= ~flag;
879 // Don't process children if the item has the main flag set on itself.
880 if ((childFlag != -1 && int(flags & childFlag) == childFlag)
881 || (int(childFlag) == -1 && handlesChildEvents)
882 || (int(childFlag) == -2 && filtersDescendantEvents))
886 for (int i = 0; i < children.size(); ++i)
887 children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
890 void QGraphicsItemPrivate::updateAncestorFlags()
894 // Inherit the parent's ancestor flags.
895 QGraphicsItemPrivate *pd = parent->d_ptr.data();
896 flags = pd->ancestorFlags;
898 // Add in flags from the parent.
899 if (pd->filtersDescendantEvents)
900 flags |= AncestorFiltersChildEvents;
901 if (pd->handlesChildEvents)
902 flags |= AncestorHandlesChildEvents;
903 if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape)
904 flags |= AncestorClipsChildren;
905 if (pd->flags & QGraphicsItem::ItemIgnoresTransformations)
906 flags |= AncestorIgnoresTransformations;
909 if (ancestorFlags == flags)
910 return; // No change; stop propagation.
911 ancestorFlags = flags;
913 // Propagate to children recursively.
914 for (int i = 0; i < children.size(); ++i)
915 children.at(i)->d_ptr->updateAncestorFlags();
921 Propagates item group membership.
923 void QGraphicsItemPrivate::setIsMemberOfGroup(bool enabled)
926 isMemberOfGroup = enabled;
927 if (!qgraphicsitem_cast<QGraphicsItemGroup *>(q)) {
928 foreach (QGraphicsItem *child, children)
929 child->d_func()->setIsMemberOfGroup(enabled);
936 Maps any item pos properties of \a event to \a item's coordinate system.
938 void QGraphicsItemPrivate::remapItemPos(QEvent *event, QGraphicsItem *item)
941 switch (event->type()) {
942 case QEvent::GraphicsSceneMouseMove:
943 case QEvent::GraphicsSceneMousePress:
944 case QEvent::GraphicsSceneMouseRelease:
945 case QEvent::GraphicsSceneMouseDoubleClick: {
946 QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
947 mouseEvent->setPos(item->mapFromItem(q, mouseEvent->pos()));
948 mouseEvent->setLastPos(item->mapFromItem(q, mouseEvent->pos()));
949 for (int i = 0x1; i <= 0x10; i <<= 1) {
950 if (mouseEvent->buttons() & i) {
951 Qt::MouseButton button = Qt::MouseButton(i);
952 mouseEvent->setButtonDownPos(button, item->mapFromItem(q, mouseEvent->buttonDownPos(button)));
957 case QEvent::GraphicsSceneWheel: {
958 QGraphicsSceneWheelEvent *wheelEvent = static_cast<QGraphicsSceneWheelEvent *>(event);
959 wheelEvent->setPos(item->mapFromItem(q, wheelEvent->pos()));
962 case QEvent::GraphicsSceneContextMenu: {
963 QGraphicsSceneContextMenuEvent *contextEvent = static_cast<QGraphicsSceneContextMenuEvent *>(event);
964 contextEvent->setPos(item->mapFromItem(q, contextEvent->pos()));
967 case QEvent::GraphicsSceneHoverMove: {
968 QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
969 hoverEvent->setPos(item->mapFromItem(q, hoverEvent->pos()));
980 Maps the point \a pos from scene to item coordinates. If \a view is passed and the item
981 is untransformable, this function will correctly map \a pos from the scene using the
982 view's transformation.
984 QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos,
985 const QWidget *viewport) const
987 Q_Q(const QGraphicsItem);
988 if (!itemIsUntransformable())
989 return q->mapFromScene(pos);
990 QGraphicsView *view = 0;
992 view = qobject_cast<QGraphicsView *>(viewport->parentWidget());
994 return q->mapFromScene(pos);
995 // ### More ping pong than needed.
996 return q->deviceTransform(view->viewportTransform()).inverted().map(view->mapFromScene(pos));
1002 Combines this item's position and transform onto \a transform.
1004 If you need to change this function (e.g., adding more transformation
1005 modes / options), make sure to change all places marked with COMBINE.
1007 void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransform *viewTransform) const
1010 if (viewTransform && itemIsUntransformable()) {
1011 *x = q_ptr->deviceTransform(*viewTransform);
1014 *x *= transformData->computedFullTransform();
1016 *x *= QTransform::fromTranslate(pos.x(), pos.y());
1023 Combines this item's position and transform onto \a transform.
1025 If you need to change this function (e.g., adding more transformation
1026 modes / options), make sure to change QGraphicsItem::deviceTransform() as
1029 void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTransform *viewTransform) const
1032 if (viewTransform && itemIsUntransformable()) {
1033 *x = q_ptr->deviceTransform(*viewTransform);
1035 x->translate(pos.x(), pos.y());
1037 *x = transformData->computedFullTransform(x);
1041 void QGraphicsItemPrivate::updateSceneTransformFromParent()
1044 Q_ASSERT(!parent->d_ptr->dirtySceneTransform);
1045 if (parent->d_ptr->sceneTransformTranslateOnly) {
1046 sceneTransform = QTransform::fromTranslate(parent->d_ptr->sceneTransform.dx() + pos.x(),
1047 parent->d_ptr->sceneTransform.dy() + pos.y());
1049 sceneTransform = parent->d_ptr->sceneTransform;
1050 sceneTransform.translate(pos.x(), pos.y());
1052 if (transformData) {
1053 sceneTransform = transformData->computedFullTransform(&sceneTransform);
1054 sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1056 sceneTransformTranslateOnly = parent->d_ptr->sceneTransformTranslateOnly;
1058 } else if (!transformData) {
1059 sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
1060 sceneTransformTranslateOnly = 1;
1061 } else if (transformData->onlyTransform) {
1062 sceneTransform = transformData->transform;
1064 sceneTransform *= QTransform::fromTranslate(pos.x(), pos.y());
1065 sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1066 } else if (pos.isNull()) {
1067 sceneTransform = transformData->computedFullTransform();
1068 sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1070 sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
1071 sceneTransform = transformData->computedFullTransform(&sceneTransform);
1072 sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1074 dirtySceneTransform = 0;
1080 This helper function helped us add input method query support in
1081 Qt 4.4.1 without having to reimplement the inputMethodQuery()
1082 function in QGraphicsProxyWidget. ### Qt 5: Remove. We cannot
1083 remove it in 4.5+ even if we do reimplement the function properly,
1084 because apps compiled with 4.4 will not be able to call the
1087 QVariant QGraphicsItemPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query) const
1096 Make sure not to trigger any pure virtual function calls (e.g.,
1097 prepareGeometryChange) if the item is in its destructor, i.e.
1100 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant,
1101 const QVariant *thisPointerVariant)
1104 if (newParent == parent)
1108 static_cast<QGraphicsWidgetPrivate *>(this)->fixFocusChainBeforeReparenting((newParent &&
1109 newParent->isWidget()) ? static_cast<QGraphicsWidget *>(newParent) : 0,
1112 // Deliver the change to the index
1113 if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
1114 scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
1116 // Disable scene pos notifications for old ancestors
1117 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
1118 scene->d_func()->setScenePosItemEnabled(q, false);
1121 if (subFocusItem && parent) {
1122 // Make sure none of the old parents point to this guy.
1123 subFocusItem->d_ptr->clearSubFocus(parent);
1126 // We anticipate geometry changes. If the item is deleted, it will be
1127 // removed from the index at a later stage, and the whole scene will be
1130 q_ptr->prepareGeometryChange();
1133 // Remove from current parent
1134 parent->d_ptr->removeChild(q);
1135 if (thisPointerVariant)
1136 parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant);
1139 // Update toplevelitem list. If this item is being deleted, its parent
1140 // will be 0 but we don't want to register/unregister it in the TLI list.
1141 if (scene && !inDestructor) {
1142 if (parent && !newParent) {
1143 scene->d_func()->registerTopLevelItem(q);
1144 } else if (!parent && newParent) {
1145 scene->d_func()->unregisterTopLevelItem(q);
1149 // Ensure any last parent focus scope does not point to this item or any of
1151 QGraphicsItem *p = parent;
1152 QGraphicsItem *parentFocusScopeItem = 0;
1154 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
1155 // If this item's focus scope's focus scope item points
1156 // to this item or a descendent, then clear it.
1157 QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
1158 if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
1159 parentFocusScopeItem = fsi;
1160 p->d_ptr->focusScopeItem = 0;
1161 fsi->d_ptr->focusScopeItemChange(false);
1165 p = p->d_ptr->parent;
1168 // Update graphics effect optimization flag
1169 if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect))
1170 newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
1172 // Update focus scope item ptr in new scope.
1173 QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
1174 if (newFocusScopeItem && newParent) {
1175 QGraphicsItem *p = newParent;
1177 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
1178 if (subFocusItem && subFocusItem != q_ptr) {
1179 // Find the subFocusItem's topmost focus scope within the new parent's focusscope
1180 QGraphicsItem *ancestorScope = 0;
1181 QGraphicsItem *p2 = subFocusItem->d_ptr->parent;
1182 while (p2 && p2 != p) {
1183 if (p2->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
1185 if (p2->d_ptr->flags & QGraphicsItem::ItemIsPanel)
1189 p2 = p2->d_ptr->parent;
1192 newFocusScopeItem = ancestorScope;
1195 p->d_ptr->focusScopeItem = newFocusScopeItem;
1196 newFocusScopeItem->d_ptr->focusScopeItemChange(true);
1197 // Ensure the new item is no longer the subFocusItem. The
1198 // only way to set focus on a child of a focus scope is
1199 // by setting focus on the scope itself.
1200 if (subFocusItem && !p->focusItem())
1201 subFocusItem->d_ptr->clearSubFocus();
1204 p = p->d_ptr->parent;
1209 invalidateDepthRecursively();
1211 if ((parent = newParent)) {
1212 if (parent->d_func()->scene && parent->d_func()->scene != scene) {
1213 // Move this item to its new parent's scene
1214 parent->d_func()->scene->addItem(q);
1215 } else if (!parent->d_func()->scene && scene) {
1216 // Remove this item from its former scene
1217 scene->removeItem(q);
1220 parent->d_ptr->addChild(q);
1221 if (thisPointerVariant)
1222 parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant);
1224 // Re-enable scene pos notifications for new ancestors
1225 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
1226 scene->d_func()->setScenePosItemEnabled(q, true);
1229 // Propagate dirty flags to the new parent
1230 markParentDirty(/*updateBoundingRect=*/true);
1232 // Inherit ancestor flags from the new parent.
1233 updateAncestorFlags();
1235 // Update item visible / enabled.
1236 if (parent->d_ptr->visible != visible) {
1237 if (!parent->d_ptr->visible || !explicitlyHidden)
1238 setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false);
1240 if (parent->isEnabled() != enabled) {
1241 if (!parent->d_ptr->enabled || !explicitlyDisabled)
1242 setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false);
1245 // Auto-activate if visible and the parent is active.
1246 if (visible && parent->isActive())
1249 // Inherit ancestor flags from the new parent.
1250 updateAncestorFlags();
1252 if (!inDestructor) {
1253 // Update item visible / enabled.
1254 if (!visible && !explicitlyHidden)
1255 setVisibleHelper(true, /* explicit = */ false);
1256 if (!enabled && !explicitlyDisabled)
1257 setEnabledHelper(true, /* explicit = */ false);
1261 dirtySceneTransform = 1;
1262 if (!inDestructor && (transformData || (newParent && newParent->d_ptr->transformData)))
1265 // Restore the sub focus chain.
1267 subFocusItem->d_ptr->setSubFocus(newParent);
1268 if (parent && parent->isActive())
1269 subFocusItem->setFocus();
1272 // Deliver post-change notification
1273 if (newParentVariant)
1274 q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant);
1277 emit static_cast<QGraphicsObject *>(q)->parentChanged();
1283 Returns the bounding rect of this item's children (excluding itself).
1285 void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem)
1289 QRectF childrenRect;
1290 QRectF *result = rect;
1291 rect = &childrenRect;
1292 const bool setTopMostEffectItem = !topMostEffectItem;
1294 for (int i = 0; i < children.size(); ++i) {
1295 QGraphicsItem *child = children.at(i);
1296 QGraphicsItemPrivate *childd = child->d_ptr.data();
1297 if (setTopMostEffectItem)
1298 topMostEffectItem = child;
1299 bool hasPos = !childd->pos.isNull();
1300 if (hasPos || childd->transformData) {
1302 QTransform matrix = childd->transformToParent();
1305 *rect |= matrix.mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
1306 if (!childd->children.isEmpty())
1307 childd->childrenBoundingRectHelper(&matrix, rect, topMostEffectItem);
1310 *rect |= x->mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
1312 *rect |= child->d_ptr->effectiveBoundingRect(topMostEffectItem);
1313 if (!childd->children.isEmpty())
1314 childd->childrenBoundingRectHelper(x, rect, topMostEffectItem);
1318 if (flags & QGraphicsItem::ItemClipsChildrenToShape){
1320 *rect &= x->mapRect(q->boundingRect());
1322 *rect &= q->boundingRect();
1328 void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
1329 const QRegion &exposedRegion, bool allItems) const
1332 Q_Q(const QGraphicsItem);
1334 // Initialize standard QStyleOption values.
1335 const QRectF brect = q->boundingRect();
1336 option->state = QStyle::State_None;
1337 option->rect = brect.toRect();
1338 option->levelOfDetail = 1;
1339 option->exposedRect = brect;
1341 option->state |= QStyle::State_Selected;
1343 option->state |= QStyle::State_Enabled;
1345 option->state |= QStyle::State_HasFocus;
1347 if (scene->d_func()->hoverItems.contains(q_ptr))
1348 option->state |= QStyle::State_MouseOver;
1349 if (q == scene->mouseGrabberItem())
1350 option->state |= QStyle::State_Sunken;
1353 if (!(flags & QGraphicsItem::ItemUsesExtendedStyleOption))
1356 // Initialize QStyleOptionGraphicsItem specific values (matrix, exposedRect).
1357 option->matrix = worldTransform.toAffine(); //### discards perspective
1360 // Determine the item's exposed area
1361 option->exposedRect = QRectF();
1362 const QTransform reverseMap = worldTransform.inverted();
1363 const QVector<QRect> exposedRects(exposedRegion.rects());
1364 for (int i = 0; i < exposedRects.size(); ++i) {
1365 option->exposedRect |= reverseMap.mapRect(QRectF(exposedRects.at(i)));
1366 if (option->exposedRect.contains(brect))
1369 option->exposedRect &= brect;
1376 Empty all cached pixmaps from the pixmap cache.
1378 void QGraphicsItemCache::purge()
1380 QPixmapCache::remove(key);
1381 key = QPixmapCache::Key();
1382 QMutableHashIterator<QPaintDevice *, DeviceData> it(deviceData);
1383 while (it.hasNext()) {
1384 DeviceData &data = it.next().value();
1385 QPixmapCache::remove(data.key);
1386 data.cacheIndent = QPoint();
1394 Constructs a QGraphicsItem with the given \a parent item.
1395 It does not modify the parent object returned by QObject::parent().
1397 If \a parent is 0, you can add the item to a scene by calling
1398 QGraphicsScene::addItem(). The item will then become a top-level item.
1400 \sa QGraphicsScene::addItem(), setParentItem()
1402 QGraphicsItem::QGraphicsItem(QGraphicsItem *parent
1404 // obsolete argument
1405 , QGraphicsScene *scene
1408 : d_ptr(new QGraphicsItemPrivate)
1410 d_ptr->q_ptr = this;
1411 setParentItem(parent);
1413 if (scene && parent && parent->scene() != scene) {
1414 qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
1415 " different from parent's scene (%p)",
1416 scene, parent->scene());
1419 if (scene && !parent)
1420 scene->addItem(this);
1426 QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent,
1427 QGraphicsScene *scene)
1430 d_ptr->q_ptr = this;
1431 setParentItem(parent);
1433 if (scene && parent && parent->scene() != scene) {
1434 qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
1435 " different from parent's scene (%p)",
1436 scene, parent->scene());
1439 if (scene && !parent)
1440 scene->addItem(this);
1444 Destroys the QGraphicsItem and all its children. If this item is currently
1445 associated with a scene, the item will be removed from the scene before it
1448 \note It is more efficient to remove the item from the QGraphicsScene before
1449 destroying the item.
1451 QGraphicsItem::~QGraphicsItem()
1453 if (d_ptr->isObject) {
1454 QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
1455 QObjectPrivate *p = QObjectPrivate::get(o);
1456 p->wasDeleted = true;
1457 if (p->declarativeData) {
1458 QAbstractDeclarativeData::destroyed(p->declarativeData, o);
1459 p->declarativeData = 0;
1463 d_ptr->inDestructor = 1;
1464 d_ptr->removeExtraItemCache();
1466 #ifndef QT_NO_GESTURES
1467 if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) {
1468 QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
1469 if (QGestureManager *manager = QGestureManager::instance()) {
1470 foreach (Qt::GestureType type, d_ptr->gestureContext.keys())
1471 manager->cleanupCachedGestures(o, type);
1478 // Update focus scope item ptr.
1479 QGraphicsItem *p = d_ptr->parent;
1481 if (p->flags() & ItemIsFocusScope) {
1482 if (p->d_ptr->focusScopeItem == this)
1483 p->d_ptr->focusScopeItem = 0;
1486 p = p->d_ptr->parent;
1489 if (!d_ptr->children.isEmpty()) {
1490 while (!d_ptr->children.isEmpty())
1491 delete d_ptr->children.first();
1492 Q_ASSERT(d_ptr->children.isEmpty());
1496 d_ptr->scene->d_func()->removeItemHelper(this);
1498 d_ptr->resetFocusProxy();
1502 #ifndef QT_NO_GRAPHICSEFFECT
1503 delete d_ptr->graphicsEffect;
1504 #endif //QT_NO_GRAPHICSEFFECT
1505 if (d_ptr->transformData) {
1506 for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) {
1507 QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i);
1508 static_cast<QGraphicsTransformPrivate *>(t->d_ptr.data())->item = 0;
1512 delete d_ptr->transformData;
1514 if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore())
1515 dataStore->data.remove(this);
1519 Returns the current scene for the item, or 0 if the item is not stored in
1522 To add or move an item to a scene, call QGraphicsScene::addItem().
1524 QGraphicsScene *QGraphicsItem::scene() const
1526 return d_ptr->scene;
1530 Returns a pointer to this item's item group, or 0 if this item is not
1533 \sa QGraphicsItemGroup, QGraphicsScene::createItemGroup()
1535 QGraphicsItemGroup *QGraphicsItem::group() const
1537 if (!d_ptr->isMemberOfGroup)
1539 QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
1540 while ((parent = parent->d_ptr->parent)) {
1541 if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(parent))
1544 // Unreachable; if d_ptr->isMemberOfGroup is != 0, then one parent of this
1545 // item is a group item.
1550 Adds this item to the item group \a group. If \a group is 0, this item is
1551 removed from any current group and added as a child of the previous
1554 \sa group(), QGraphicsScene::createItemGroup()
1556 void QGraphicsItem::setGroup(QGraphicsItemGroup *group)
1559 if (QGraphicsItemGroup *group = this->group())
1560 group->removeFromGroup(this);
1562 group->addToGroup(this);
1567 Returns a pointer to this item's parent item. If this item does not have a
1568 parent, 0 is returned.
1570 \sa setParentItem(), childItems()
1572 QGraphicsItem *QGraphicsItem::parentItem() const
1574 return d_ptr->parent;
1578 Returns this item's top-level item. The top-level item is the item's
1579 topmost ancestor item whose parent is 0. If an item has no parent, its own
1580 pointer is returned (i.e., a top-level item is its own top-level item).
1584 QGraphicsItem *QGraphicsItem::topLevelItem() const
1586 QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
1587 while (QGraphicsItem *grandPa = parent->parentItem())
1595 Returns a pointer to the item's parent, cast to a QGraphicsObject. returns 0 if the parent item
1596 is not a QGraphicsObject.
1598 \sa parentItem(), childItems()
1600 QGraphicsObject *QGraphicsItem::parentObject() const
1602 QGraphicsItem *p = d_ptr->parent;
1603 return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : 0;
1609 Returns a pointer to the item's parent widget. The item's parent widget is
1610 the closest parent item that is a widget.
1612 \sa parentItem(), childItems()
1614 QGraphicsWidget *QGraphicsItem::parentWidget() const
1616 QGraphicsItem *p = parentItem();
1617 while (p && !p->isWidget())
1618 p = p->parentItem();
1619 return (p && p->isWidget()) ? static_cast<QGraphicsWidget *>(p) : 0;
1625 Returns a pointer to the item's top level widget (i.e., the item's
1626 ancestor whose parent is 0, or whose parent is not a widget), or 0 if this
1627 item does not have a top level widget. If the item is its own top level
1628 widget, this function returns a pointer to the item itself.
1630 QGraphicsWidget *QGraphicsItem::topLevelWidget() const
1632 if (const QGraphicsWidget *p = parentWidget())
1633 return p->topLevelWidget();
1634 return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : 0;
1640 Returns the item's window, or 0 if this item does not have a window. If
1641 the item is a window, it will return itself. Otherwise it will return the
1642 closest ancestor that is a window.
1644 \sa QGraphicsWidget::isWindow()
1646 QGraphicsWidget *QGraphicsItem::window() const
1648 QGraphicsItem *p = panel();
1649 if (p && p->isWindow())
1650 return static_cast<QGraphicsWidget *>(p);
1657 Returns the item's panel, or 0 if this item does not have a panel. If the
1658 item is a panel, it will return itself. Otherwise it will return the
1659 closest ancestor that is a panel.
1661 \sa isPanel(), ItemIsPanel
1663 QGraphicsItem *QGraphicsItem::panel() const
1665 if (d_ptr->flags & ItemIsPanel)
1666 return const_cast<QGraphicsItem *>(this);
1667 return d_ptr->parent ? d_ptr->parent->panel() : 0;
1673 Return the graphics item cast to a QGraphicsObject, if the class is actually a
1674 graphics object, 0 otherwise.
1676 QGraphicsObject *QGraphicsItem::toGraphicsObject()
1678 return d_ptr->isObject ? static_cast<QGraphicsObject *>(this) : 0;
1684 Return the graphics item cast to a QGraphicsObject, if the class is actually a
1685 graphics object, 0 otherwise.
1687 const QGraphicsObject *QGraphicsItem::toGraphicsObject() const
1689 return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0;
1693 Sets this item's parent item to \a newParent. If this item already
1694 has a parent, it is first removed from the previous parent. If \a
1695 newParent is 0, this item will become a top-level item.
1697 Note that this implicitly adds this graphics item to the scene of
1698 the parent. You should not \l{QGraphicsScene::addItem()}{add} the
1699 item to the scene yourself.
1701 Calling this function on an item that is an ancestor of \a newParent
1702 have undefined behaviour.
1704 \sa parentItem(), childItems()
1706 void QGraphicsItem::setParentItem(QGraphicsItem *newParent)
1708 if (newParent == this) {
1709 qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
1712 if (newParent == d_ptr->parent)
1715 const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange,
1716 QVariant::fromValue<QGraphicsItem *>(newParent)));
1717 newParent = qvariant_cast<QGraphicsItem *>(newParentVariant);
1718 if (newParent == d_ptr->parent)
1721 const QVariant thisPointerVariant(QVariant::fromValue<QGraphicsItem *>(this));
1722 d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant);
1728 Use childItems() instead.
1732 QList<QGraphicsItem *> QGraphicsItem::children() const
1734 return childItems();
1740 Returns a list of this item's children.
1742 The items are sorted by stacking order. This takes into account both the
1743 items' insertion order and their Z-values.
1745 \sa setParentItem(), zValue(), {QGraphicsItem#Sorting}{Sorting}
1747 QList<QGraphicsItem *> QGraphicsItem::childItems() const
1749 const_cast<QGraphicsItem *>(this)->d_ptr->ensureSortedChildren();
1750 return d_ptr->children;
1755 Returns true if this item is a widget (i.e., QGraphicsWidget); otherwise,
1758 bool QGraphicsItem::isWidget() const
1760 return d_ptr->isWidget;
1765 Returns true if the item is a QGraphicsWidget window, otherwise returns
1768 \sa QGraphicsWidget::windowFlags()
1770 bool QGraphicsItem::isWindow() const
1772 return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
1777 Returns true if the item is a panel; otherwise returns false.
1779 \sa QGraphicsItem::panel(), ItemIsPanel
1781 bool QGraphicsItem::isPanel() const
1783 return d_ptr->flags & ItemIsPanel;
1787 Returns this item's flags. The flags describe what configurable features
1788 of the item are enabled and not. For example, if the flags include
1789 ItemIsFocusable, the item can accept input focus.
1791 By default, no flags are enabled.
1793 \sa setFlags(), setFlag()
1795 QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const
1797 return GraphicsItemFlags(d_ptr->flags);
1801 If \a enabled is true, the item flag \a flag is enabled; otherwise, it is
1804 \sa flags(), setFlags()
1806 void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled)
1809 setFlags(GraphicsItemFlags(d_ptr->flags) | flag);
1811 setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag);
1817 Sets the flag \a flag on \a item and all its children, to \a enabled.
1819 static void _q_qgraphicsItemSetFlag(QGraphicsItem *item, QGraphicsItem::GraphicsItemFlag flag,
1822 if (item->flags() & flag) {
1823 // If this item already has the correct flag set, we don't have to
1827 item->setFlag(flag, enabled);
1828 foreach (QGraphicsItem *child, item->children())
1829 _q_qgraphicsItemSetFlag(child, flag, enabled);
1833 Sets the item flags to \a flags. All flags in \a flags are enabled; all
1834 flags not in \a flags are disabled.
1836 If the item had focus and \a flags does not enable ItemIsFocusable, the
1837 item loses focus as a result of calling this function. Similarly, if the
1838 item was selected, and \a flags does not enabled ItemIsSelectable, the
1839 item is automatically unselected.
1841 By default, no flags are enabled. (QGraphicsWidget enables the
1842 ItemSendsGeometryChanges flag by default in order to track position
1845 \sa flags(), setFlag()
1847 void QGraphicsItem::setFlags(GraphicsItemFlags flags)
1849 // Notify change and check for adjustment.
1850 if (quint32(d_ptr->flags) == quint32(flags))
1852 flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
1853 if (quint32(d_ptr->flags) == quint32(flags))
1855 if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
1856 d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags);
1858 // Flags that alter the geometry of the item (or its children).
1859 const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
1860 bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
1862 d_ptr->updatePaintedViewBoundingRects(/*children=*/true);
1864 // Keep the old flags to compare the diff.
1865 GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
1868 d_ptr->flags = flags;
1870 if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
1871 // Clear focus on the item if it has focus when the focusable flag
1876 if (!(d_ptr->flags & ItemIsSelectable) && isSelected()) {
1877 // Unselect the item if it is selected when the selectable flag is
1882 if ((flags & ItemClipsChildrenToShape) != (oldFlags & ItemClipsChildrenToShape)) {
1883 // Item children clipping changes. Propagate the ancestor flag to
1885 d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
1886 // The childrenBoundingRect is clipped to the boundingRect in case of ItemClipsChildrenToShape,
1887 // which means we have to invalidate the cached childrenBoundingRect whenever this flag changes.
1888 d_ptr->dirtyChildrenBoundingRect = 1;
1889 d_ptr->markParentDirty(true);
1892 if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
1893 // Item children clipping changes. Propagate the ancestor flag to
1895 d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
1898 if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
1899 // NB! We change the flags directly here, so we must also update d_ptr->flags.
1900 // Note that this has do be done before the ItemStacksBehindParent check
1901 // below; otherwise we will loose the change.
1903 // Update stack-behind.
1904 if (d_ptr->z < qreal(0.0))
1905 flags |= ItemStacksBehindParent;
1907 flags &= ~ItemStacksBehindParent;
1908 d_ptr->flags = flags;
1911 if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
1912 // NB! This check has to come after the ItemNegativeZStacksBehindParent
1913 // check above. Be careful.
1915 // Ensure child item sorting is up to date when toggling this flag.
1917 d_ptr->parent->d_ptr->needSortChildren = 1;
1918 else if (d_ptr->scene)
1919 d_ptr->scene->d_func()->needSortTopLevelItems = 1;
1922 if ((flags & ItemAcceptsInputMethod) != (oldFlags & ItemAcceptsInputMethod)) {
1923 // Update input method sensitivity in any views.
1925 d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
1929 if ((d_ptr->panelModality != NonModal)
1931 && (flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
1932 // update the panel's modal state
1933 if (flags & ItemIsPanel)
1934 d_ptr->scene->d_func()->enterModal(this);
1936 d_ptr->scene->d_func()->leaveModal(this);
1940 if ((flags & ItemSendsScenePositionChanges) != (oldFlags & ItemSendsScenePositionChanges)) {
1941 if (flags & ItemSendsScenePositionChanges)
1942 d_ptr->scene->d_func()->registerScenePosItem(this);
1944 d_ptr->scene->d_func()->unregisterScenePosItem(this);
1946 d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
1950 itemChange(ItemFlagsHaveChanged, quint32(flags));
1955 Returns the cache mode for this item. The default mode is NoCache (i.e.,
1956 cache is disabled and all painting is immediate).
1960 QGraphicsItem::CacheMode QGraphicsItem::cacheMode() const
1962 return QGraphicsItem::CacheMode(d_ptr->cacheMode);
1967 Sets the item's cache mode to \a mode.
1969 The optional \a logicalCacheSize argument is used only by
1970 ItemCoordinateCache mode, and describes the resolution of the cache
1971 buffer; if \a logicalCacheSize is (100, 100), QGraphicsItem will fit the
1972 item into 100x100 pixels in graphics memory, regardless of the logical
1973 size of the item itself. By default QGraphicsItem uses the size of
1974 boundingRect(). For all other cache modes than ItemCoordinateCache, \a
1975 logicalCacheSize is ignored.
1977 Caching can speed up rendering if your item spends a significant time
1978 redrawing itself. In some cases the cache can also slow down rendering, in
1979 particular when the item spends less time redrawing than QGraphicsItem
1980 spends redrawing from the cache. When enabled, the item's paint() function
1981 will be called only once for each call to update(); for any subsequent
1982 repaint requests, the Graphics View framework will redraw from the
1983 cache. This approach works particularly well with QGLWidget, which stores
1984 all the cache as OpenGL textures.
1986 Be aware that QPixmapCache's cache limit may need to be changed to obtain
1987 optimal performance.
1989 You can read more about the different cache modes in the CacheMode
1992 \sa CacheMode, QPixmapCache::setCacheLimit()
1994 void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize)
1996 CacheMode lastMode = CacheMode(d_ptr->cacheMode);
1997 d_ptr->cacheMode = mode;
1998 bool noVisualChange = (mode == NoCache && lastMode == NoCache)
1999 || (mode == NoCache && lastMode == DeviceCoordinateCache)
2000 || (mode == DeviceCoordinateCache && lastMode == NoCache)
2001 || (mode == DeviceCoordinateCache && lastMode == DeviceCoordinateCache);
2002 if (mode == NoCache) {
2003 d_ptr->removeExtraItemCache();
2005 QGraphicsItemCache *cache = d_ptr->extraItemCache();
2010 if (mode == ItemCoordinateCache) {
2011 if (lastMode == mode && cache->fixedSize == logicalCacheSize)
2012 noVisualChange = true;
2013 cache->fixedSize = logicalCacheSize;
2016 if (!noVisualChange)
2023 Returns the modality for this item.
2025 QGraphicsItem::PanelModality QGraphicsItem::panelModality() const
2027 return d_ptr->panelModality;
2033 Sets the modality for this item to \a panelModality.
2035 Changing the modality of a visible item takes effect immediately.
2037 void QGraphicsItem::setPanelModality(PanelModality panelModality)
2039 if (d_ptr->panelModality == panelModality)
2042 PanelModality previousModality = d_ptr->panelModality;
2043 bool enterLeaveModal = (isPanel() && d_ptr->scene && isVisible());
2044 if (enterLeaveModal && panelModality == NonModal)
2045 d_ptr->scene->d_func()->leaveModal(this);
2046 d_ptr->panelModality = panelModality;
2047 if (enterLeaveModal && d_ptr->panelModality != NonModal)
2048 d_ptr->scene->d_func()->enterModal(this, previousModality);
2054 Returns true if this item is blocked by a modal panel, false otherwise. If \a blockingPanel is
2055 non-zero, \a blockingPanel will be set to the modal panel that is blocking this item. If this
2056 item is not blocked, \a blockingPanel will not be set by this function.
2058 This function always returns false for items not in a scene.
2060 \sa panelModality(), setPanelModality(), PanelModality
2062 bool QGraphicsItem::isBlockedByModalPanel(QGraphicsItem **blockingPanel) const
2068 QGraphicsItem *dummy = 0;
2070 blockingPanel = &dummy;
2072 QGraphicsScenePrivate *scene_d = d_ptr->scene->d_func();
2073 if (scene_d->modalPanels.isEmpty())
2077 if (!scene_d->popupWidgets.isEmpty() && scene_d->popupWidgets.first() == this)
2080 for (int i = 0; i < scene_d->modalPanels.count(); ++i) {
2081 QGraphicsItem *modalPanel = scene_d->modalPanels.at(i);
2082 if (modalPanel->panelModality() == QGraphicsItem::SceneModal) {
2083 // Scene modal panels block all non-descendents.
2084 if (modalPanel != this && !modalPanel->isAncestorOf(this)) {
2085 *blockingPanel = modalPanel;
2089 // Window modal panels block ancestors and siblings/cousins.
2090 if (modalPanel != this
2091 && !modalPanel->isAncestorOf(this)
2092 && commonAncestorItem(modalPanel)) {
2093 *blockingPanel = modalPanel;
2101 #ifndef QT_NO_TOOLTIP
2103 Returns the item's tool tip, or an empty QString if no tool tip has been
2106 \sa setToolTip(), QToolTip
2108 QString QGraphicsItem::toolTip() const
2110 return d_ptr->extra(QGraphicsItemPrivate::ExtraToolTip).toString();
2114 Sets the item's tool tip to \a toolTip. If \a toolTip is empty, the item's
2115 tool tip is cleared.
2117 \sa toolTip(), QToolTip
2119 void QGraphicsItem::setToolTip(const QString &toolTip)
2121 const QVariant toolTipVariant(itemChange(ItemToolTipChange, toolTip));
2122 d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTipVariant.toString());
2123 itemChange(ItemToolTipHasChanged, toolTipVariant);
2125 #endif // QT_NO_TOOLTIP
2127 #ifndef QT_NO_CURSOR
2129 Returns the current cursor shape for the item. The mouse cursor
2130 will assume this shape when it's over this item. See the \link
2131 Qt::CursorShape list of predefined cursor objects\endlink for a
2132 range of useful shapes.
2134 An editor item might want to use an I-beam cursor:
2136 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 2
2138 If no cursor has been set, the cursor of the item beneath is used.
2140 \sa setCursor(), hasCursor(), unsetCursor(), QWidget::cursor,
2141 QApplication::overrideCursor()
2143 QCursor QGraphicsItem::cursor() const
2145 return qvariant_cast<QCursor>(d_ptr->extra(QGraphicsItemPrivate::ExtraCursor));
2149 Sets the current cursor shape for the item to \a cursor. The mouse cursor
2150 will assume this shape when it's over this item. See the \link
2151 Qt::CursorShape list of predefined cursor objects\endlink for a range of
2154 An editor item might want to use an I-beam cursor:
2156 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 3
2158 If no cursor has been set, the cursor of the item beneath is used.
2160 \sa cursor(), hasCursor(), unsetCursor(), QWidget::cursor,
2161 QApplication::overrideCursor()
2163 void QGraphicsItem::setCursor(const QCursor &cursor)
2165 const QVariant cursorVariant(itemChange(ItemCursorChange, QVariant::fromValue<QCursor>(cursor)));
2166 d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qvariant_cast<QCursor>(cursorVariant));
2167 d_ptr->hasCursor = 1;
2169 d_ptr->scene->d_func()->allItemsUseDefaultCursor = false;
2170 foreach (QGraphicsView *view, d_ptr->scene->views()) {
2171 view->viewport()->setMouseTracking(true);
2172 // Note: Some of this logic is duplicated in QGraphicsView's mouse events.
2173 if (view->underMouse()) {
2174 foreach (QGraphicsItem *itemUnderCursor, view->items(view->mapFromGlobal(QCursor::pos()))) {
2175 if (itemUnderCursor->hasCursor()) {
2176 QMetaObject::invokeMethod(view, "_q_setViewportCursor",
2177 Q_ARG(QCursor, itemUnderCursor->cursor()));
2185 itemChange(ItemCursorHasChanged, cursorVariant);
2189 Returns true if this item has a cursor set; otherwise, false is returned.
2191 By default, items don't have any cursor set. cursor() will return a
2192 standard pointing arrow cursor.
2196 bool QGraphicsItem::hasCursor() const
2198 return d_ptr->hasCursor;
2202 Clears the cursor from this item.
2204 \sa hasCursor(), setCursor()
2206 void QGraphicsItem::unsetCursor()
2208 d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraCursor);
2209 d_ptr->hasCursor = 0;
2211 foreach (QGraphicsView *view, d_ptr->scene->views()) {
2212 if (view->underMouse() && view->itemAt(view->mapFromGlobal(QCursor::pos())) == this) {
2213 QMetaObject::invokeMethod(view, "_q_unsetViewportCursor");
2220 #endif // QT_NO_CURSOR
2223 Returns true if the item is visible; otherwise, false is returned.
2225 Note that the item's general visibility is unrelated to whether or not it
2226 is actually being visualized by a QGraphicsView.
2230 bool QGraphicsItem::isVisible() const
2232 return d_ptr->visible;
2237 Returns true if the item is visible to \a parent; otherwise, false is
2238 returned. \a parent can be 0, in which case this function will return
2239 whether the item is visible to the scene or not.
2241 An item may not be visible to its ancestors even if isVisible() is true. It
2242 may also be visible to its ancestors even if isVisible() is false. If
2243 any ancestor is hidden, the item itself will be implicitly hidden, in which
2244 case this function will return false.
2246 \sa isVisible(), setVisible()
2248 bool QGraphicsItem::isVisibleTo(const QGraphicsItem *parent) const
2250 const QGraphicsItem *p = this;
2251 if (d_ptr->explicitlyHidden)
2256 if (p->d_ptr->explicitlyHidden)
2258 } while ((p = p->d_ptr->parent));
2265 Sets this item's visibility to \a newVisible. If \a explicitly is true,
2266 this item will be "explicitly" \a newVisible; otherwise, it.. will not be.
2268 void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bool update)
2272 // Update explicit bit.
2274 explicitlyHidden = newVisible ? 0 : 1;
2276 // Check if there's nothing to do.
2277 if (visible == quint32(newVisible))
2280 // Don't show child if parent is not visible
2281 if (parent && newVisible && !parent->d_ptr->visible)
2284 // Modify the property.
2285 const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange,
2286 quint32(newVisible)));
2287 newVisible = newVisibleVariant.toBool();
2288 if (visible == quint32(newVisible))
2290 visible = newVisible;
2292 // Schedule redrawing
2294 QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
2298 #ifndef QT_NO_GRAPHICSEFFECT
2299 invalidateParentGraphicsEffectsRecursively();
2300 #endif //QT_NO_GRAPHICSEFFECT
2301 scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
2305 // Certain properties are dropped as an item becomes invisible.
2306 bool hasFocus = q_ptr->hasFocus();
2309 if (scene->d_func()->mouseGrabberItems.contains(q))
2311 if (scene->d_func()->keyboardGrabberItems.contains(q))
2312 q->ungrabKeyboard();
2313 if (q->isPanel() && panelModality != QGraphicsItem::NonModal)
2314 scene->d_func()->leaveModal(q_ptr);
2316 if (hasFocus && scene) {
2317 // Hiding the closest non-panel ancestor of the focus item
2318 QGraphicsItem *focusItem = scene->focusItem();
2320 if (isWidget && !focusItem->isPanel()) {
2322 if (focusItem == q_ptr) {
2323 clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
2326 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
2329 clearFocusHelper(/* giveFocusToParent = */ false);
2331 if (q_ptr->isSelected())
2332 q_ptr->setSelected(false);
2334 geometryChanged = 1;
2335 paintedViewBoundingRectsNeedRepaint = 1;
2338 QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
2339 if (widget->windowType() == Qt::Popup)
2340 scene->d_func()->addPopup(widget);
2342 if (q->isPanel() && panelModality != QGraphicsItem::NonModal) {
2343 scene->d_func()->enterModal(q_ptr);
2348 // Update children with explicitly = false.
2349 const bool updateChildren = update && !(flags & QGraphicsItem::ItemClipsChildrenToShape);
2350 foreach (QGraphicsItem *child, children) {
2351 if (!newVisible || !child->d_ptr->explicitlyHidden)
2352 child->d_ptr->setVisibleHelper(newVisible, false, updateChildren);
2355 // Update activation
2356 if (scene && q->isPanel()) {
2358 if (parent && parent->isActive())
2362 scene->setActivePanel(parent);
2370 QGraphicsItem *p = parent;
2373 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
2374 QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
2375 if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
2377 while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
2378 fsi = fsi->d_ptr->focusScopeItem;
2379 fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
2380 /* focusFromHide = */ false);
2384 p = p->d_ptr->parent;
2387 QGraphicsItem *fi = subFocusItem;
2388 if (fi && fi != scene->focusItem()) {
2389 scene->setFocusItem(fi);
2390 } else if (flags & QGraphicsItem::ItemIsFocusScope &&
2391 !scene->focusItem() &&
2392 q->isAncestorOf(scene->d_func()->lastFocusItem)) {
2399 QGraphicsItem *p = parent;
2401 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
2402 if (p->d_ptr->visible) {
2403 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
2404 /* focusFromHide = */ true);
2408 p = p->d_ptr->parent;
2414 // Deliver post-change notification.
2415 q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, newVisibleVariant);
2418 emit static_cast<QGraphicsObject *>(q_ptr)->visibleChanged();
2422 If \a visible is true, the item is made visible. Otherwise, the item is
2423 made invisible. Invisible items are not painted, nor do they receive any
2424 events. In particular, mouse events pass right through invisible items,
2425 and are delivered to any item that may be behind. Invisible items are also
2426 unselectable, they cannot take input focus, and are not detected by
2427 QGraphicsScene's item location functions.
2429 If an item becomes invisible while grabbing the mouse, (i.e., while it is
2430 receiving mouse events,) it will automatically lose the mouse grab, and
2431 the grab is not regained by making the item visible again; it must receive
2432 a new mouse press to regain the mouse grab.
2434 Similarly, an invisible item cannot have focus, so if the item has focus
2435 when it becomes invisible, it will lose focus, and the focus is not
2436 regained by simply making the item visible again.
2438 If you hide a parent item, all its children will also be hidden. If you
2439 show a parent item, all children will be shown, unless they have been
2440 explicitly hidden (i.e., if you call setVisible(false) on a child, it will
2441 not be reshown even if its parent is hidden, and then shown again).
2443 Items are visible by default; it is unnecessary to call
2444 setVisible() on a new item.
2446 \sa isVisible(), show(), hide()
2448 void QGraphicsItem::setVisible(bool visible)
2450 d_ptr->setVisibleHelper(visible, /* explicit = */ true);
2454 \fn void QGraphicsItem::hide()
2456 Hides the item. (Items are visible by default.)
2458 This convenience function is equivalent to calling \c setVisible(false).
2460 \sa show(), setVisible()
2464 \fn void QGraphicsItem::show()
2466 Shows the item. (Items are visible by default.)
2468 This convenience function is equivalent to calling \c setVisible(true).
2470 \sa hide(), setVisible()
2474 Returns true if the item is enabled; otherwise, false is returned.
2478 bool QGraphicsItem::isEnabled() const
2480 return d_ptr->enabled;
2486 Sets this item's visibility to \a newEnabled. If \a explicitly is true,
2487 this item will be "explicitly" \a newEnabled; otherwise, it.. will not be.
2489 void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bool update)
2491 // Update explicit bit.
2493 explicitlyDisabled = newEnabled ? 0 : 1;
2495 // Check if there's nothing to do.
2496 if (enabled == quint32(newEnabled))
2499 // Certain properties are dropped when an item is disabled.
2501 if (scene && scene->mouseGrabberItem() == q_ptr)
2502 q_ptr->ungrabMouse();
2503 if (q_ptr->hasFocus()) {
2504 // Disabling the closest non-panel ancestor of the focus item
2505 // causes focus to pop to the next item, otherwise it's cleared.
2506 QGraphicsItem *focusItem = scene->focusItem();
2508 if (isWidget && !focusItem->isPanel() && q_ptr->isAncestorOf(focusItem)) {
2510 if (focusItem == q_ptr) {
2511 clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
2514 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
2517 q_ptr->clearFocus();
2519 if (q_ptr->isSelected())
2520 q_ptr->setSelected(false);
2523 // Modify the property.
2524 const QVariant newEnabledVariant(q_ptr->itemChange(QGraphicsItem::ItemEnabledChange,
2525 quint32(newEnabled)));
2526 enabled = newEnabledVariant.toBool();
2532 foreach (QGraphicsItem *child, children) {
2533 if (!newEnabled || !child->d_ptr->explicitlyDisabled)
2534 child->d_ptr->setEnabledHelper(newEnabled, /* explicitly = */ false);
2537 // Deliver post-change notification.
2538 q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, newEnabledVariant);
2541 emit static_cast<QGraphicsObject *>(q_ptr)->enabledChanged();
2545 If \a enabled is true, the item is enabled; otherwise, it is disabled.
2547 Disabled items are visible, but they do not receive any events, and cannot
2548 take focus nor be selected. Mouse events are discarded; they are not
2549 propagated unless the item is also invisible, or if it does not accept
2550 mouse events (see acceptedMouseButtons()). A disabled item cannot become the
2551 mouse grabber, and as a result of this, an item loses the grab if it
2552 becomes disabled when grabbing the mouse, just like it loses focus if it
2553 had focus when it was disabled.
2555 Disabled items are traditionally drawn using grayed-out colors (see \l
2556 QPalette::Disabled).
2558 If you disable a parent item, all its children will also be disabled. If
2559 you enable a parent item, all children will be enabled, unless they have
2560 been explicitly disabled (i.e., if you call setEnabled(false) on a child,
2561 it will not be reenabled if its parent is disabled, and then enabled
2564 Items are enabled by default.
2566 \note If you install an event filter, you can still intercept events
2567 before they are delivered to items; this mechanism disregards the item's
2572 void QGraphicsItem::setEnabled(bool enabled)
2574 d_ptr->setEnabledHelper(enabled, /* explicitly = */ true);
2578 Returns true if this item is selected; otherwise, false is returned.
2580 Items that are in a group inherit the group's selected state.
2582 Items are not selected by default.
2584 \sa setSelected(), QGraphicsScene::setSelectionArea()
2586 bool QGraphicsItem::isSelected() const
2588 if (QGraphicsItemGroup *group = this->group())
2589 return group->isSelected();
2590 return d_ptr->selected;
2594 If \a selected is true and this item is selectable, this item is selected;
2595 otherwise, it is unselected.
2597 If the item is in a group, the whole group's selected state is toggled by
2598 this function. If the group is selected, all items in the group are also
2599 selected, and if the group is not selected, no item in the group is
2602 Only visible, enabled, selectable items can be selected. If \a selected
2603 is true and this item is either invisible or disabled or unselectable,
2604 this function does nothing.
2606 By default, items cannot be selected. To enable selection, set the
2607 ItemIsSelectable flag.
2609 This function is provided for convenience, allowing individual toggling of
2610 the selected state of an item. However, a more common way of selecting
2611 items is to call QGraphicsScene::setSelectionArea(), which will call this
2612 function for all visible, enabled, and selectable items within a specified
2615 \sa isSelected(), QGraphicsScene::selectedItems()
2617 void QGraphicsItem::setSelected(bool selected)
2619 if (QGraphicsItemGroup *group = this->group()) {
2620 group->setSelected(selected);
2624 if (!(d_ptr->flags & ItemIsSelectable) || !d_ptr->enabled || !d_ptr->visible)
2626 if (d_ptr->selected == selected)
2628 const QVariant newSelectedVariant(itemChange(ItemSelectedChange, quint32(selected)));
2629 bool newSelected = newSelectedVariant.toBool();
2630 if (d_ptr->selected == newSelected)
2632 d_ptr->selected = newSelected;
2636 QGraphicsScenePrivate *sceneD = d_ptr->scene->d_func();
2638 sceneD->selectedItems << this;
2640 // QGraphicsScene::selectedItems() lazily pulls out all items that are
2641 // no longer selected.
2643 if (!sceneD->selectionChanging)
2644 emit d_ptr->scene->selectionChanged();
2647 // Deliver post-change notification.
2648 itemChange(QGraphicsItem::ItemSelectedHasChanged, newSelectedVariant);
2654 Returns this item's local opacity, which is between 0.0 (transparent) and
2655 1.0 (opaque). This value is combined with parent and ancestor values into
2656 the effectiveOpacity(). The effective opacity decides how the item is
2659 The opacity property decides the state of the painter passed to the
2660 paint() function. If the item is cached, i.e., ItemCoordinateCache or
2661 DeviceCoordinateCache, the effective property will be applied to the item's
2662 cache as it is rendered.
2664 The default opacity is 1.0; fully opaque.
2666 \sa setOpacity(), paint(), ItemIgnoresParentOpacity,
2667 ItemDoesntPropagateOpacityToChildren
2669 qreal QGraphicsItem::opacity() const
2671 return d_ptr->opacity;
2677 Returns this item's \e effective opacity, which is between 0.0
2678 (transparent) and 1.0 (opaque). This value is a combination of this item's
2679 local opacity, and its parent and ancestors' opacities. The effective
2680 opacity decides how the item is rendered.
2682 \sa opacity(), setOpacity(), paint(), ItemIgnoresParentOpacity,
2683 ItemDoesntPropagateOpacityToChildren
2685 qreal QGraphicsItem::effectiveOpacity() const
2687 return d_ptr->effectiveOpacity();
2693 Sets this item's local \a opacity, between 0.0 (transparent) and 1.0
2694 (opaque). The item's local opacity is combined with parent and ancestor
2695 opacities into the effectiveOpacity().
2697 By default, opacity propagates from parent to child, so if a parent's
2698 opacity is 0.5 and the child is also 0.5, the child's effective opacity
2701 The opacity property decides the state of the painter passed to the
2702 paint() function. If the item is cached, i.e., ItemCoordinateCache or
2703 DeviceCoordinateCache, the effective property will be applied to the
2704 item's cache as it is rendered.
2706 There are two item flags that affect how the item's opacity is combined
2707 with the parent: ItemIgnoresParentOpacity and
2708 ItemDoesntPropagateOpacityToChildren.
2710 \sa opacity(), effectiveOpacity()
2712 void QGraphicsItem::setOpacity(qreal opacity)
2715 const QVariant newOpacityVariant(itemChange(ItemOpacityChange, opacity));
2717 // Normalized opacity
2718 qreal newOpacity = qBound(qreal(0), newOpacityVariant.toReal(), qreal(1));
2721 if (newOpacity == d_ptr->opacity)
2724 bool wasFullyTransparent = d_ptr->isOpacityNull();
2725 d_ptr->opacity = newOpacity;
2728 itemChange(ItemOpacityHasChanged, newOpacityVariant);
2732 #ifndef QT_NO_GRAPHICSEFFECT
2733 d_ptr->invalidateParentGraphicsEffectsRecursively();
2734 if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren))
2735 d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged);
2736 #endif //QT_NO_GRAPHICSEFFECT
2737 d_ptr->scene->d_func()->markDirty(this, QRectF(),
2738 /*invalidateChildren=*/true,
2740 /*ignoreOpacity=*/d_ptr->isOpacityNull());
2741 if (wasFullyTransparent)
2742 d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
2745 if (d_ptr->isObject)
2746 emit static_cast<QGraphicsObject *>(this)->opacityChanged();
2750 Returns a pointer to this item's effect if it has one; otherwise 0.
2754 #ifndef QT_NO_GRAPHICSEFFECT
2755 QGraphicsEffect *QGraphicsItem::graphicsEffect() const
2757 return d_ptr->graphicsEffect;
2761 Sets \a effect as the item's effect. If there already is an effect installed
2762 on this item, QGraphicsItem will delete the existing effect before installing
2765 If \a effect is the installed on a different item, setGraphicsEffect() will remove
2766 the effect from the item and install it on this item.
2768 QGraphicsItem takes ownership of \a effect.
2770 \note This function will apply the effect on itself and all its children.
2774 void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
2776 if (d_ptr->graphicsEffect == effect)
2779 if (d_ptr->graphicsEffect) {
2780 delete d_ptr->graphicsEffect;
2781 d_ptr->graphicsEffect = 0;
2782 } else if (d_ptr->parent) {
2783 d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
2788 QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
2789 QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
2790 d_ptr->graphicsEffect = effect;
2791 effect->d_func()->setGraphicsEffectSource(source);
2792 prepareGeometryChange();
2795 #endif //QT_NO_GRAPHICSEFFECT
2797 void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively()
2799 #ifndef QT_NO_GRAPHICSEFFECT
2800 QGraphicsItemPrivate *itemPrivate = this;
2802 // parent chain already notified?
2803 if (itemPrivate->mayHaveChildWithGraphicsEffect)
2805 itemPrivate->mayHaveChildWithGraphicsEffect = 1;
2806 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
2813 Returns the effective bounding rect of the given item space rect.
2814 If the item has no effect, the rect is returned unmodified.
2815 If the item has an effect, the effective rect can be extend beyond the
2816 item's bounding rect, depending on the effect.
2820 QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
2822 #ifndef QT_NO_GRAPHICSEFFECT
2823 Q_Q(const QGraphicsItem);
2824 QGraphicsEffect *effect = graphicsEffect;
2825 if (scene && effect && effect->isEnabled()) {
2826 if (scene->d_func()->views.isEmpty())
2827 return effect->boundingRectFor(rect);
2828 QRectF sceneRect = q->mapRectToScene(rect);
2829 QRectF sceneEffectRect;
2830 foreach (QGraphicsView *view, scene->views()) {
2831 QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect);
2832 QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect();
2833 sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect);
2835 return q->mapRectFromScene(sceneEffectRect);
2837 #endif //QT_NO_GRAPHICSEFFECT
2844 Returns the effective bounding rect of the item.
2845 If the item has no effect, this is the same as the item's bounding rect.
2846 If the item has an effect, the effective rect can be larger than the item's
2847 bouding rect, depending on the effect.
2851 QRectF QGraphicsItemPrivate::effectiveBoundingRect(QGraphicsItem *topMostEffectItem) const
2853 #ifndef QT_NO_GRAPHICSEFFECT
2854 Q_Q(const QGraphicsItem);
2855 QRectF brect = effectiveBoundingRect(q_ptr->boundingRect());
2856 if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren || topMostEffectItem == q)
2859 const QGraphicsItem *effectParent = parent;
2860 while (effectParent) {
2861 QGraphicsEffect *effect = effectParent->d_ptr->graphicsEffect;
2862 if (scene && effect && effect->isEnabled()) {
2863 const QRectF brectInParentSpace = q->mapRectToItem(effectParent, brect);
2864 const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace);
2865 brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
2867 if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
2868 || topMostEffectItem == effectParent) {
2871 effectParent = effectParent->d_ptr->parent;
2875 #else //QT_NO_GRAPHICSEFFECT
2876 return q_ptr->boundingRect();
2877 #endif //QT_NO_GRAPHICSEFFECT
2884 Returns the effective bounding rect of this item in scene coordinates,
2885 by combining sceneTransform() with boundingRect(), taking into account
2886 the effect that the item might have.
2888 If the item has no effect, this is the same as sceneBoundingRect().
2890 \sa effectiveBoundingRect(), sceneBoundingRect()
2892 QRectF QGraphicsItemPrivate::sceneEffectiveBoundingRect() const
2894 // Find translate-only offset
2897 const QGraphicsItem *parentItem = q_ptr;
2898 const QGraphicsItemPrivate *itemd;
2900 itemd = parentItem->d_ptr.data();
2901 if (itemd->transformData)
2903 offset += itemd->pos;
2904 } while ((parentItem = itemd->parent));
2906 QRectF br = effectiveBoundingRect();
2907 br.translate(offset);
2908 return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
2912 Returns true if this item can accept drag and drop events; otherwise,
2913 returns false. By default, items do not accept drag and drop events; items
2914 are transparent to drag and drop.
2916 \sa setAcceptDrops()
2918 bool QGraphicsItem::acceptDrops() const
2920 return d_ptr->acceptDrops;
2924 If \a on is true, this item will accept drag and drop events; otherwise,
2925 it is transparent for drag and drop events. By default, items do not
2926 accept drag and drop events.
2930 void QGraphicsItem::setAcceptDrops(bool on)
2932 d_ptr->acceptDrops = on;
2936 Returns the mouse buttons that this item accepts mouse events for. By
2937 default, all mouse buttons are accepted.
2939 If an item accepts a mouse button, it will become the mouse
2940 grabber item when a mouse press event is delivered for that mouse
2941 button. However, if the item does not accept the button,
2942 QGraphicsScene will forward the mouse events to the first item
2943 beneath it that does.
2945 \sa setAcceptedMouseButtons(), mousePressEvent()
2947 Qt::MouseButtons QGraphicsItem::acceptedMouseButtons() const
2949 return Qt::MouseButtons(d_ptr->acceptedMouseButtons);
2953 Sets the mouse \a buttons that this item accepts mouse events for.
2955 By default, all mouse buttons are accepted. If an item accepts a
2956 mouse button, it will become the mouse grabber item when a mouse
2957 press event is delivered for that button. However, if the item
2958 does not accept the mouse button, QGraphicsScene will forward the
2959 mouse events to the first item beneath it that does.
2961 To disable mouse events for an item (i.e., make it transparent for mouse
2962 events), call setAcceptedMouseButtons(0).
2964 \sa acceptedMouseButtons(), mousePressEvent()
2966 void QGraphicsItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
2968 if (Qt::MouseButtons(d_ptr->acceptedMouseButtons) != buttons) {
2969 if (buttons == 0 && d_ptr->scene && d_ptr->scene->mouseGrabberItem() == this
2970 && d_ptr->scene->d_func()->lastMouseGrabberItemHasImplicitMouseGrab) {
2973 d_ptr->acceptedMouseButtons = quint32(buttons);
2980 Returns true if an item accepts hover events
2981 (QGraphicsSceneHoverEvent); otherwise, returns false. By default,
2982 items do not accept hover events.
2984 \sa setAcceptedMouseButtons()
2986 bool QGraphicsItem::acceptHoverEvents() const
2988 return d_ptr->acceptsHover;
2994 Call acceptHoverEvents() instead.
2996 bool QGraphicsItem::acceptsHoverEvents() const
2998 return d_ptr->acceptsHover;
3004 If \a enabled is true, this item will accept hover events;
3005 otherwise, it will ignore them. By default, items do not accept
3008 Hover events are delivered when there is no current mouse grabber
3009 item. They are sent when the mouse cursor enters an item, when it
3010 moves around inside the item, and when the cursor leaves an
3011 item. Hover events are commonly used to highlight an item when
3012 it's entered, and for tracking the mouse cursor as it hovers over
3013 the item (equivalent to QWidget::mouseTracking).
3015 Parent items receive hover enter events before their children, and
3016 leave events after their children. The parent does not receive a
3017 hover leave event if the cursor enters a child, though; the parent
3018 stays "hovered" until the cursor leaves its area, including its
3021 If a parent item handles child events, it will receive hover move,
3022 drag move, and drop events as the cursor passes through its
3023 children, but it does not receive hover enter and hover leave, nor
3024 drag enter and drag leave events on behalf of its children.
3026 A QGraphicsWidget with window decorations will accept hover events
3027 regardless of the value of acceptHoverEvents().
3029 \sa acceptHoverEvents(), hoverEnterEvent(), hoverMoveEvent(),
3032 void QGraphicsItem::setAcceptHoverEvents(bool enabled)
3034 if (d_ptr->acceptsHover == quint32(enabled))
3036 d_ptr->acceptsHover = quint32(enabled);
3037 if (d_ptr->acceptsHover && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreHoverEvents) {
3038 d_ptr->scene->d_func()->allItemsIgnoreHoverEvents = false;
3039 d_ptr->scene->d_func()->enableMouseTrackingOnViews();
3046 Use setAcceptHoverEvents(\a enabled) instead.
3048 void QGraphicsItem::setAcceptsHoverEvents(bool enabled)
3050 setAcceptHoverEvents(enabled);
3055 Returns true if an item accepts \l{QTouchEvent}{touch events};
3056 otherwise, returns false. By default, items do not accept touch events.
3058 \sa setAcceptTouchEvents()
3060 bool QGraphicsItem::acceptTouchEvents() const
3062 return d_ptr->acceptTouchEvents;
3068 If \a enabled is true, this item will accept \l{QTouchEvent}{touch events};
3069 otherwise, it will ignore them. By default, items do not accept
3072 void QGraphicsItem::setAcceptTouchEvents(bool enabled)
3074 if (d_ptr->acceptTouchEvents == quint32(enabled))
3076 d_ptr->acceptTouchEvents = quint32(enabled);
3077 if (d_ptr->acceptTouchEvents && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreTouchEvents) {
3078 d_ptr->scene->d_func()->allItemsIgnoreTouchEvents = false;
3079 d_ptr->scene->d_func()->enableTouchEventsOnViews();
3086 Returns true if this item filters child events (i.e., all events
3087 intended for any of its children are instead sent to this item);
3088 otherwise, false is returned.
3090 The default value is false; child events are not filtered.
3092 \sa setFiltersChildEvents()
3094 bool QGraphicsItem::filtersChildEvents() const
3096 return d_ptr->filtersDescendantEvents;
3102 If \a enabled is true, this item is set to filter all events for
3103 all its children (i.e., all events intented for any of its
3104 children are instead sent to this item); otherwise, if \a enabled
3105 is false, this item will only handle its own events. The default
3108 \sa filtersChildEvents()
3110 void QGraphicsItem::setFiltersChildEvents(bool enabled)
3112 if (d_ptr->filtersDescendantEvents == enabled)
3115 d_ptr->filtersDescendantEvents = enabled;
3116 d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
3122 Returns true if this item handles child events (i.e., all events
3123 intended for any of its children are instead sent to this item);
3124 otherwise, false is returned.
3126 This property is useful for item groups; it allows one item to
3127 handle events on behalf of its children, as opposed to its
3128 children handling their events individually.
3130 The default is to return false; children handle their own events.
3131 The exception for this is if the item is a QGraphicsItemGroup, then
3132 it defaults to return true.
3134 \sa setHandlesChildEvents()
3136 bool QGraphicsItem::handlesChildEvents() const
3138 return d_ptr->handlesChildEvents;
3144 If \a enabled is true, this item is set to handle all events for
3145 all its children (i.e., all events intented for any of its
3146 children are instead sent to this item); otherwise, if \a enabled
3147 is false, this item will only handle its own events. The default
3150 This property is useful for item groups; it allows one item to
3151 handle events on behalf of its children, as opposed to its
3152 children handling their events individually.
3154 If a child item accepts hover events, its parent will receive
3155 hover move events as the cursor passes through the child, but it
3156 does not receive hover enter and hover leave events on behalf of
3159 \sa handlesChildEvents()
3161 void QGraphicsItem::setHandlesChildEvents(bool enabled)
3163 if (d_ptr->handlesChildEvents == enabled)
3166 d_ptr->handlesChildEvents = enabled;
3167 d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
3171 Returns true if this item is active; otherwise returns false.
3173 An item can only be active if the scene is active. An item is active
3174 if it is, or is a descendent of, an active panel. Items in non-active
3175 panels are not active.
3177 Items that are not part of a panel follow scene activation when the
3178 scene has no active panel.
3180 Only active items can gain input focus.
3182 \sa QGraphicsScene::isActive(), QGraphicsScene::activePanel(), panel(), isPanel()
3184 bool QGraphicsItem::isActive() const
3186 if (!d_ptr->scene || !d_ptr->scene->isActive())
3188 return panel() == d_ptr->scene->activePanel();
3194 If \a active is true, and the scene is active, this item's panel will be
3195 activated. Otherwise, the panel is deactivated.
3197 If the item is not part of an active scene, \a active will decide what
3198 happens to the panel when the scene becomes active or the item is added to
3199 the scene. If true, the item's panel will be activated when the item is
3200 either added to the scene or the scene is activated. Otherwise, the item
3201 will stay inactive independent of the scene's activated state.
3203 \sa isPanel(), QGraphicsScene::setActivePanel(), QGraphicsScene::isActive()
3205 void QGraphicsItem::setActive(bool active)
3207 d_ptr->explicitActivate = 1;
3208 d_ptr->wantsActive = active;
3211 // Activate this item.
3212 d_ptr->scene->setActivePanel(this);
3214 // Deactivate this item, and reactivate the last active item
3216 QGraphicsItem *lastActive = d_ptr->scene->d_func()->lastActivePanel;
3217 d_ptr->scene->setActivePanel(lastActive != this ? lastActive : 0);
3223 Returns true if this item is active, and it or its \l{focusProxy()}{focus
3224 proxy} has keyboard input focus; otherwise, returns false.
3226 \sa focusItem(), setFocus(), QGraphicsScene::setFocusItem(), isActive()
3228 bool QGraphicsItem::hasFocus() const
3230 if (!d_ptr->scene || !d_ptr->scene->isActive())
3233 if (d_ptr->focusProxy)
3234 return d_ptr->focusProxy->hasFocus();
3236 if (d_ptr->scene->d_func()->focusItem != this)
3239 return panel() == d_ptr->scene->d_func()->activePanel;
3243 Gives keyboard input focus to this item. The \a focusReason argument will
3244 be passed into any \l{QFocusEvent}{focus event} generated by this function;
3245 it is used to give an explanation of what caused the item to get focus.
3247 Only enabled items that set the ItemIsFocusable flag can accept keyboard
3250 If this item is not visible, not active, or not associated with a scene,
3251 it will not gain immediate input focus. However, it will be registered as
3252 the preferred focus item for its subtree of items, should it later become
3255 As a result of calling this function, this item will receive a
3256 \l{focusInEvent()}{focus in event} with \a focusReason. If another item
3257 already has focus, that item will first receive a \l{focusOutEvent()}
3258 {focus out event} indicating that it has lost input focus.
3260 \sa clearFocus(), hasFocus(), focusItem(), focusProxy()
3262 void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
3264 d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromHide = */ false);
3270 void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide)
3272 // Disabled / unfocusable items cannot accept focus.
3273 if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
3276 // Find focus proxy.
3277 QGraphicsItem *f = q_ptr;
3278 while (f->d_ptr->focusProxy)
3279 f = f->d_ptr->focusProxy;
3281 // Return if it already has focus.
3282 if (scene && scene->focusItem() == f)
3285 // Update focus scope item ptr.
3286 QGraphicsItem *p = parent;
3288 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3289 QGraphicsItem *oldFocusScopeItem = p->d_ptr->focusScopeItem;
3290 p->d_ptr->focusScopeItem = q_ptr;
3291 if (!p->focusItem() && !focusFromHide) {
3292 if (oldFocusScopeItem)
3293 oldFocusScopeItem->d_ptr->focusScopeItemChange(false);
3294 focusScopeItemChange(true);
3295 // If you call setFocus on a child of a focus scope that
3296 // doesn't currently have a focus item, then stop.
3301 p = p->d_ptr->parent;
3305 while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible())
3306 f = f->d_ptr->focusScopeItem;
3309 // Update the child focus chain.
3310 QGraphicsItem *commonAncestor = 0;
3311 if (scene && scene->focusItem()) {
3312 commonAncestor = scene->focusItem()->commonAncestorItem(f);
3313 scene->focusItem()->d_ptr->clearSubFocus(scene->focusItem(), commonAncestor);
3316 f->d_ptr->setSubFocus(f, commonAncestor);
3318 // Update the scene's focus item.
3320 QGraphicsItem *p = q_ptr->panel();
3321 if ((!p && scene->isActive()) || (p && p->isActive())) {
3322 // Visible items immediately gain focus from scene.
3323 scene->d_func()->setFocusItemHelper(f, focusReason);
3329 Takes keyboard input focus from the item.
3331 If it has focus, a \l{focusOutEvent()}{focus out event} is sent to this
3332 item to tell it that it is about to lose the focus.
3334 Only items that set the ItemIsFocusable flag, or widgets that set an
3335 appropriate focus policy, can accept keyboard focus.
3337 \sa setFocus(), hasFocus(), QGraphicsWidget::focusPolicy
3339 void QGraphicsItem::clearFocus()
3341 d_ptr->clearFocusHelper(/* giveFocusToParent = */ true);
3347 void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent)
3349 if (giveFocusToParent) {
3350 // Pass focus to the closest parent focus scope
3351 if (!inDestructor) {
3352 QGraphicsItem *p = parent;
3354 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3355 if (p->d_ptr->focusScopeItem == q_ptr) {
3356 p->d_ptr->focusScopeItem = 0;
3357 if (!q_ptr->hasFocus()) //if it has focus, focusScopeItemChange is called elsewhere
3358 focusScopeItemChange(false);
3360 if (q_ptr->hasFocus())
3361 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false,
3362 /* focusFromHide = */ false);
3365 p = p->d_ptr->parent;
3370 if (q_ptr->hasFocus()) {
3371 // Invisible items with focus must explicitly clear subfocus.
3372 clearSubFocus(q_ptr);
3374 // If this item has the scene's input focus, clear it.
3375 scene->setFocusItem(0);
3382 Returns this item's focus proxy, or 0 if this item has no
3385 \sa setFocusProxy(), setFocus(), hasFocus()
3387 QGraphicsItem *QGraphicsItem::focusProxy() const
3389 return d_ptr->focusProxy;
3395 Sets the item's focus proxy to \a item.
3397 If an item has a focus proxy, the focus proxy will receive
3398 input focus when the item gains input focus. The item itself
3399 will still have focus (i.e., hasFocus() will return true),
3400 but only the focus proxy will receive the keyboard input.
3402 A focus proxy can itself have a focus proxy, and so on. In
3403 such case, keyboard input will be handled by the outermost
3406 The focus proxy \a item must belong to the same scene as
3409 \sa focusProxy(), setFocus(), hasFocus()
3411 void QGraphicsItem::setFocusProxy(QGraphicsItem *item)
3413 if (item == d_ptr->focusProxy)
3416 qWarning("QGraphicsItem::setFocusProxy: cannot assign self as focus proxy");
3420 if (item->d_ptr->scene != d_ptr->scene) {
3421 qWarning("QGraphicsItem::setFocusProxy: focus proxy must be in same scene");
3424 for (QGraphicsItem *f = item->focusProxy(); f != 0; f = f->focusProxy()) {
3426 qWarning("QGraphicsItem::setFocusProxy: %p is already in the focus proxy chain", item);
3432 QGraphicsItem *lastFocusProxy = d_ptr->focusProxy;
3434 lastFocusProxy->d_ptr->focusProxyRefs.removeOne(&d_ptr->focusProxy);
3435 d_ptr->focusProxy = item;
3437 item->d_ptr->focusProxyRefs << &d_ptr->focusProxy;
3443 If this item, a child or descendant of this item currently has input
3444 focus, this function will return a pointer to that item. If
3445 no descendant has input focus, 0 is returned.
3447 \sa hasFocus(), setFocus(), QWidget::focusWidget()
3449 QGraphicsItem *QGraphicsItem::focusItem() const
3451 return d_ptr->subFocusItem;
3457 Returns this item's focus scope item.
3459 QGraphicsItem *QGraphicsItem::focusScopeItem() const
3461 return d_ptr->focusScopeItem;
3466 Grabs the mouse input.
3468 This item will receive all mouse events for the scene until any of the
3469 following events occurs:
3472 \li The item becomes invisible
3473 \li The item is removed from the scene
3474 \li The item is deleted
3475 \li The item call ungrabMouse()
3476 \li Another item calls grabMouse(); the item will regain the mouse grab
3477 when the other item calls ungrabMouse().
3480 When an item gains the mouse grab, it receives a QEvent::GrabMouse
3481 event. When it loses the mouse grab, it receives a QEvent::UngrabMouse
3482 event. These events can be used to detect when your item gains or loses
3483 the mouse grab through other means than receiving mouse button events.
3485 It is almost never necessary to explicitly grab the mouse in Qt, as Qt
3486 grabs and releases it sensibly. In particular, Qt grabs the mouse when you
3487 press a mouse button, and keeps the mouse grabbed until you release the
3488 last mouse button. Also, Qt::Popup widgets implicitly call grabMouse()
3489 when shown, and ungrabMouse() when hidden.
3491 Note that only visible items can grab mouse input. Calling grabMouse() on
3492 an invisible item has no effect.
3494 Keyboard events are not affected.
3496 \sa QGraphicsScene::mouseGrabberItem(), ungrabMouse(), grabKeyboard()
3498 void QGraphicsItem::grabMouse()
3500 if (!d_ptr->scene) {
3501 qWarning("QGraphicsItem::grabMouse: cannot grab mouse without scene");
3504 if (!d_ptr->visible) {
3505 qWarning("QGraphicsItem::grabMouse: cannot grab mouse while invisible");
3508 d_ptr->scene->d_func()->grabMouse(this);
3513 Releases the mouse grab.
3515 \sa grabMouse(), ungrabKeyboard()
3517 void QGraphicsItem::ungrabMouse()
3519 if (!d_ptr->scene) {
3520 qWarning("QGraphicsItem::ungrabMouse: cannot ungrab mouse without scene");
3523 d_ptr->scene->d_func()->ungrabMouse(this);
3528 Grabs the keyboard input.
3530 The item will receive all keyboard input to the scene until one of the
3531 following events occur:
3534 \li The item becomes invisible
3535 \li The item is removed from the scene
3536 \li The item is deleted
3537 \li The item calls ungrabKeyboard()
3538 \li Another item calls grabKeyboard(); the item will regain the keyboard grab
3539 when the other item calls ungrabKeyboard().
3542 When an item gains the keyboard grab, it receives a QEvent::GrabKeyboard
3543 event. When it loses the keyboard grab, it receives a
3544 QEvent::UngrabKeyboard event. These events can be used to detect when your
3545 item gains or loses the keyboard grab through other means than gaining
3548 It is almost never necessary to explicitly grab the keyboard in Qt, as Qt
3549 grabs and releases it sensibly. In particular, Qt grabs the keyboard when
3550 your item gains input focus, and releases it when your item loses input
3551 focus, or when the item is hidden.
3553 Note that only visible items can grab keyboard input. Calling
3554 grabKeyboard() on an invisible item has no effect.
3556 Keyboard events are not affected.
3558 \sa ungrabKeyboard(), grabMouse(), setFocus()
3560 void QGraphicsItem::grabKeyboard()
3562 if (!d_ptr->scene) {
3563 qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard without scene");
3566 if (!d_ptr->visible) {
3567 qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard while invisible");
3570 d_ptr->scene->d_func()->grabKeyboard(this);
3575 Releases the keyboard grab.
3577 \sa grabKeyboard(), ungrabMouse()
3579 void QGraphicsItem::ungrabKeyboard()
3581 if (!d_ptr->scene) {
3582 qWarning("QGraphicsItem::ungrabKeyboard: cannot ungrab keyboard without scene");
3585 d_ptr->scene->d_func()->ungrabKeyboard(this);
3589 Returns the position of the item in parent coordinates. If the item has no
3590 parent, its position is given in scene coordinates.
3592 The position of the item describes its origin (local coordinate
3593 (0, 0)) in parent coordinates; this function returns the same as
3596 For convenience, you can also call scenePos() to determine the
3597 item's position in scene coordinates, regardless of its parent.
3599 \sa x(), y(), setPos(), transform(), {The Graphics View Coordinate System}
3601 QPointF QGraphicsItem::pos() const
3607 \fn QGraphicsItem::x() const
3609 This convenience function is equivalent to calling pos().x().
3617 Set's the \a x coordinate of the item's position. Equivalent to
3618 calling setPos(x, y()).
3622 void QGraphicsItem::setX(qreal x)
3624 if (d_ptr->inDestructor)
3630 setPos(QPointF(x, d_ptr->pos.y()));
3634 \fn QGraphicsItem::y() const
3636 This convenience function is equivalent to calling pos().y().
3644 Set's the \a y coordinate of the item's position. Equivalent to
3645 calling setPos(x(), y).
3649 void QGraphicsItem::setY(qreal y)
3651 if (d_ptr->inDestructor)
3657 setPos(QPointF(d_ptr->pos.x(), y));
3661 Returns the item's position in scene coordinates. This is
3662 equivalent to calling \c mapToScene(0, 0).
3664 \sa pos(), sceneTransform(), {The Graphics View Coordinate System}
3666 QPointF QGraphicsItem::scenePos() const
3668 return mapToScene(0, 0);
3674 Sets the position \a pos.
3676 void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
3681 q->prepareGeometryChange();
3682 QPointF oldPos = this->pos;
3684 dirtySceneTransform = 1;
3687 if (pos.x() != oldPos.x())
3688 emit static_cast<QGraphicsObject *>(q_ptr)->xChanged();
3689 if (pos.y() != oldPos.y())
3690 emit static_cast<QGraphicsObject *>(q_ptr)->yChanged();
3697 Sets the transform \a transform.
3699 void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
3701 q_ptr->prepareGeometryChange();
3702 transformData->transform = transform;
3703 dirtySceneTransform = 1;
3708 Sets the position of the item to \a pos, which is in parent
3709 coordinates. For items with no parent, \a pos is in scene
3712 The position of the item describes its origin (local coordinate
3713 (0, 0)) in parent coordinates.
3715 \sa pos(), scenePos(), {The Graphics View Coordinate System}
3717 void QGraphicsItem::setPos(const QPointF &pos)
3719 if (d_ptr->pos == pos)
3722 if (d_ptr->inDestructor)
3725 // Update and repositition.
3726 if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
3727 d_ptr->setPosHelper(pos);
3728 if (d_ptr->isWidget)
3729 static_cast<QGraphicsWidget *>(this)->d_func()->setGeometryFromSetPos();
3730 if (d_ptr->scenePosDescendants)
3731 d_ptr->sendScenePosChange();
3735 // Notify the item that the position is changing.
3736 const QVariant newPosVariant(itemChange(ItemPositionChange, QVariant::fromValue<QPointF>(pos)));
3737 QPointF newPos = newPosVariant.toPointF();
3738 if (newPos == d_ptr->pos)
3741 // Update and repositition.
3742 d_ptr->setPosHelper(newPos);
3744 // Send post-notification.
3745 itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
3746 d_ptr->sendScenePosChange();
3750 \fn void QGraphicsItem::setPos(qreal x, qreal y)
3753 This convenience function is equivalent to calling setPos(QPointF(\a x, \a
3758 \fn void QGraphicsItem::moveBy(qreal dx, qreal dy)
3760 Moves the item by \a dx points horizontally, and \a dy point
3761 vertically. This function is equivalent to calling setPos(pos() +
3762 QPointF(\a dx, \a dy)).
3766 If this item is part of a scene that is viewed by a QGraphicsView, this
3767 convenience function will attempt to scroll the view to ensure that \a
3768 rect is visible inside the view's viewport. If \a rect is a null rect (the
3769 default), QGraphicsItem will default to the item's bounding rect. \a xmargin
3770 and \a ymargin are the number of pixels the view should use for margins.
3772 If the specified rect cannot be reached, the contents are scrolled to the
3773 nearest valid position.
3775 If this item is not viewed by a QGraphicsView, this function does nothing.
3777 \sa QGraphicsView::ensureVisible()
3779 void QGraphicsItem::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
3784 sceneRect = sceneTransform().mapRect(rect);
3786 sceneRect = sceneBoundingRect();
3787 foreach (QGraphicsView *view, d_ptr->scene->d_func()->views)
3788 view->ensureVisible(sceneRect, xmargin, ymargin);
3793 \fn void QGraphicsItem::ensureVisible(qreal x, qreal y, qreal w, qreal h,
3794 int xmargin = 50, int ymargin = 50)
3796 This convenience function is equivalent to calling
3797 ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin):
3803 Returns the item's affine transformation matrix. This is a subset or the
3804 item's full transformation matrix, and might not represent the item's full
3807 Use transform() instead.
3809 \sa setTransform(), sceneTransform()
3811 QMatrix QGraphicsItem::matrix() const
3813 return transform().toAffine();
3819 Returns this item's transformation matrix.
3821 The transformation matrix is combined with the item's rotation(), scale()
3822 and transformations() into a combined transformations for the item.
3824 The default transformation matrix is an identity matrix.
3826 \sa setTransform(), sceneTransform()
3828 QTransform QGraphicsItem::transform() const
3830 if (!d_ptr->transformData)
3831 return QTransform();
3832 return d_ptr->transformData->transform;
3838 Returns the clockwise rotation, in degrees, around the Z axis. The default
3839 value is 0 (i.e., the item is not rotated).
3841 The rotation is combined with the item's scale(), transform() and
3842 transformations() to map the item's coordinate system to the parent item.
3844 \sa setRotation(), transformOriginPoint(), {Transformations}
3846 qreal QGraphicsItem::rotation() const
3848 if (!d_ptr->transformData)
3850 return d_ptr->transformData->rotation;
3856 Sets the clockwise rotation \a angle, in degrees, around the Z axis. The
3857 default value is 0 (i.e., the item is not rotated). Assigning a negative
3858 value will rotate the item counter-clockwise. Normally the rotation angle
3859 is in the range (-360, 360), but it's also possible to assign values
3860 outside of this range (e.g., a rotation of 370 degrees is the same as a
3861 rotation of 10 degrees).
3863 The item is rotated around its transform origin point, which by default
3864 is (0, 0). You can select a different transformation origin by calling
3865 setTransformOriginPoint().
3867 The rotation is combined with the item's scale(), transform() and
3868 transformations() to map the item's coordinate system to the parent item.
3870 \sa rotation(), setTransformOriginPoint(), {Transformations}
3872 void QGraphicsItem::setRotation(qreal angle)
3874 prepareGeometryChange();
3875 qreal newRotation = angle;
3877 if (d_ptr->flags & ItemSendsGeometryChanges) {
3878 // Notify the item that the rotation is changing.
3879 const QVariant newRotationVariant(itemChange(ItemRotationChange, angle));
3880 newRotation = newRotationVariant.toReal();
3883 if (!d_ptr->transformData)
3884 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
3886 if (d_ptr->transformData->rotation == newRotation)
3889 d_ptr->transformData->rotation = newRotation;
3890 d_ptr->transformData->onlyTransform = false;
3891 d_ptr->dirtySceneTransform = 1;
3893 // Send post-notification.
3894 if (d_ptr->flags & ItemSendsGeometryChanges)
3895 itemChange(ItemRotationHasChanged, newRotation);
3897 if (d_ptr->isObject)
3898 emit static_cast<QGraphicsObject *>(this)->rotationChanged();
3900 d_ptr->transformChanged();
3906 Returns the scale factor of the item. The default scale factor is 1.0
3907 (i.e., the item is not scaled).
3909 The scale is combined with the item's rotation(), transform() and
3910 transformations() to map the item's coordinate system to the parent item.
3912 \sa setScale(), rotation(), {Transformations}
3914 qreal QGraphicsItem::scale() const
3916 if (!d_ptr->transformData)
3918 return d_ptr->transformData->scale;
3924 Sets the scale \a factor of the item. The default scale factor is 1.0
3925 (i.e., the item is not scaled). A scale factor of 0.0 will collapse the
3926 item to a single point. If you provide a negative scale factor, the
3927 item will be flipped and mirrored (i.e., rotated 180 degrees).
3929 The item is scaled around its transform origin point, which by default
3930 is (0, 0). You can select a different transformation origin by calling
3931 setTransformOriginPoint().
3933 The scale is combined with the item's rotation(), transform() and
3934 transformations() to map the item's coordinate system to the parent item.
3936 \sa scale(), setTransformOriginPoint(), {Transformations Example}
3938 void QGraphicsItem::setScale(qreal factor)
3940 prepareGeometryChange();
3941 qreal newScale = factor;
3943 if (d_ptr->flags & ItemSendsGeometryChanges) {
3944 // Notify the item that the scale is changing.
3945 const QVariant newScaleVariant(itemChange(ItemScaleChange, factor));
3946 newScale = newScaleVariant.toReal();
3949 if (!d_ptr->transformData)
3950 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
3952 if (d_ptr->transformData->scale == newScale)
3955 d_ptr->transformData->scale = newScale;
3956 d_ptr->transformData->onlyTransform = false;
3957 d_ptr->dirtySceneTransform = 1;
3959 // Send post-notification.
3960 if (d_ptr->flags & ItemSendsGeometryChanges)
3961 itemChange(ItemScaleHasChanged, newScale);
3963 if (d_ptr->isObject)
3964 emit static_cast<QGraphicsObject *>(this)->scaleChanged();
3966 d_ptr->transformChanged();
3973 Returns a list of graphics transforms that currently apply to this item.
3975 QGraphicsTransform is for applying and controlling a chain of individual
3976 transformation operations on an item. It's particularly useful in
3977 animations, where each transform operation needs to be interpolated
3978 independently, or differently.
3980 The transformations are combined with the item's rotation(), scale() and
3981 transform() to map the item's coordinate system to the parent item.
3983 \sa scale(), rotation(), transformOriginPoint(), {Transformations}
3985 QList<QGraphicsTransform *> QGraphicsItem::transformations() const
3987 if (!d_ptr->transformData)
3988 return QList<QGraphicsTransform *>();
3989 return d_ptr->transformData->graphicsTransforms;
3995 Sets a list of graphics \a transformations (QGraphicsTransform) that
3996 currently apply to this item.
3998 If all you want is to rotate or scale an item, you should call setRotation()
3999 or setScale() instead. If you want to set an arbitrary transformation on
4000 an item, you can call setTransform().
4002 QGraphicsTransform is for applying and controlling a chain of individual
4003 transformation operations on an item. It's particularly useful in
4004 animations, where each transform operation needs to be interpolated
4005 independently, or differently.
4007 The transformations are combined with the item's rotation(), scale() and
4008 transform() to map the item's coordinate system to the parent item.
4010 \sa scale(), setTransformOriginPoint(), {Transformations}
4012 void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transformations)
4014 prepareGeometryChange();
4015 if (!d_ptr->transformData)
4016 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4017 d_ptr->transformData->graphicsTransforms = transformations;
4018 for (int i = 0; i < transformations.size(); ++i)
4019 transformations.at(i)->d_func()->setItem(this);
4020 d_ptr->transformData->onlyTransform = false;
4021 d_ptr->dirtySceneTransform = 1;
4022 d_ptr->transformChanged();
4028 void QGraphicsItemPrivate::prependGraphicsTransform(QGraphicsTransform *t)
4031 transformData = new QGraphicsItemPrivate::TransformData;
4032 if (!transformData->graphicsTransforms.contains(t))
4033 transformData->graphicsTransforms.prepend(t);
4036 t->d_func()->setItem(q);
4037 transformData->onlyTransform = false;
4038 dirtySceneTransform = 1;
4045 void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t)
4048 transformData = new QGraphicsItemPrivate::TransformData;
4049 if (!transformData->graphicsTransforms.contains(t))
4050 transformData->graphicsTransforms.append(t);
4053 t->d_func()->setItem(q);
4054 transformData->onlyTransform = false;
4055 dirtySceneTransform = 1;
4062 Returns the origin point for the transformation in item coordinates.
4064 The default is QPointF(0,0).
4066 \sa setTransformOriginPoint(), {Transformations}
4068 QPointF QGraphicsItem::transformOriginPoint() const
4070 if (!d_ptr->transformData)
4071 return QPointF(0,0);
4072 return QPointF(d_ptr->transformData->xOrigin, d_ptr->transformData->yOrigin);
4078 Sets the \a origin point for the transformation in item coordinates.
4080 \sa transformOriginPoint(), {Transformations}
4082 void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
4084 prepareGeometryChange();
4085 QPointF newOrigin = origin;
4087 if (d_ptr->flags & ItemSendsGeometryChanges) {
4088 // Notify the item that the origin point is changing.
4089 const QVariant newOriginVariant(itemChange(ItemTransformOriginPointChange,
4090 QVariant::fromValue<QPointF>(origin)));
4091 newOrigin = newOriginVariant.toPointF();
4094 if (!d_ptr->transformData)
4095 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4097 if (d_ptr->transformData->xOrigin == newOrigin.x()
4098 && d_ptr->transformData->yOrigin == newOrigin.y()) {
4102 d_ptr->transformData->xOrigin = newOrigin.x();
4103 d_ptr->transformData->yOrigin = newOrigin.y();
4104 d_ptr->transformData->onlyTransform = false;
4105 d_ptr->dirtySceneTransform = 1;
4107 // Send post-notification.
4108 if (d_ptr->flags & ItemSendsGeometryChanges)
4109 itemChange(ItemTransformOriginPointHasChanged, QVariant::fromValue<QPointF>(newOrigin));
4113 \fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y)
4118 Sets the origin point for the transformation in item coordinates.
4119 This is equivalent to calling setTransformOriginPoint(QPointF(\a x, \a y)).
4121 \sa setTransformOriginPoint(), {Transformations}
4128 Use sceneTransform() instead.
4130 \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}
4132 QMatrix QGraphicsItem::sceneMatrix() const
4134 d_ptr->ensureSceneTransform();
4135 return d_ptr->sceneTransform.toAffine();
4142 Returns this item's scene transformation matrix. This matrix can be used
4143 to map coordinates and geometrical shapes from this item's local
4144 coordinate system to the scene's coordinate system. To map coordinates
4145 from the scene, you must first invert the returned matrix.
4149 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 4
4151 Unlike transform(), which returns only an item's local transformation, this
4152 function includes the item's (and any parents') position, and all the transfomation properties.
4154 \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}, {Transformations}
4156 QTransform QGraphicsItem::sceneTransform() const
4158 d_ptr->ensureSceneTransform();
4159 return d_ptr->sceneTransform;
4165 Returns this item's device transformation matrix, using \a
4166 viewportTransform to map from scene to device coordinates. This matrix can
4167 be used to map coordinates and geometrical shapes from this item's local
4168 coordinate system to the viewport's (or any device's) coordinate
4169 system. To map coordinates from the viewport, you must first invert the
4174 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 5
4176 This function is the same as combining this item's scene transform with
4177 the view's viewport transform, but it also understands the
4178 ItemIgnoresTransformations flag. The device transform can be used to do
4179 accurate coordinate mapping (and collision detection) for untransformable
4182 \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate
4183 System}, itemTransform()
4185 QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) const
4187 // Ensure we return the standard transform if we're not untransformable.
4188 if (!d_ptr->itemIsUntransformable()) {
4189 d_ptr->ensureSceneTransform();
4190 return d_ptr->sceneTransform * viewportTransform;
4193 // Find the topmost item that ignores view transformations.
4194 const QGraphicsItem *untransformedAncestor = this;
4195 QList<const QGraphicsItem *> parents;
4196 while (untransformedAncestor && ((untransformedAncestor->d_ptr->ancestorFlags
4197 & QGraphicsItemPrivate::AncestorIgnoresTransformations))) {
4198 parents.prepend(untransformedAncestor);
4199 untransformedAncestor = untransformedAncestor->parentItem();
4202 if (!untransformedAncestor) {
4203 // Assert in debug mode, continue in release.
4204 Q_ASSERT_X(untransformedAncestor, "QGraphicsItem::deviceTransform",
4205 "Invalid object structure!");
4206 return QTransform();
4209 // First translate the base untransformable item.
4210 untransformedAncestor->d_ptr->ensureSceneTransform();
4211 QPointF mappedPoint = (untransformedAncestor->d_ptr->sceneTransform * viewportTransform).map(QPointF(0, 0));
4214 QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y());
4215 if (untransformedAncestor->d_ptr->transformData)
4216 matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform(&matrix);
4218 // Then transform and translate all children.
4219 for (int i = 0; i < parents.size(); ++i) {
4220 const QGraphicsItem *parent = parents.at(i);
4221 parent->d_ptr->combineTransformFromParent(&matrix);
4230 Returns a QTransform that maps coordinates from this item to \a other. If
4231 \a ok is not null, and if there is no such transform, the boolean pointed
4232 to by \a ok will be set to false; otherwise it will be set to true.
4234 This transform provides an alternative to the mapToItem() or mapFromItem()
4235 functions, by returning the appropriate transform so that you can map
4236 shapes and coordinates yourself. It also helps you write more efficient
4237 code when repeatedly mapping between the same two items.
4239 \note In rare circumstances, there is no transform that maps between two
4242 \sa mapToItem(), mapFromItem(), deviceTransform()
4244 QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) const
4246 // Catch simple cases first.
4248 qWarning("QGraphicsItem::itemTransform: null pointer passed");
4249 return QTransform();
4251 if (other == this) {
4254 return QTransform();
4257 QGraphicsItem *parent = d_ptr->parent;
4258 const QGraphicsItem *otherParent = other->d_ptr->parent;
4260 // This is other's child
4261 if (parent == other) {
4265 d_ptr->combineTransformFromParent(&x);
4269 // This is other's parent
4270 if (otherParent == this) {
4271 const QPointF &otherPos = other->d_ptr->pos;
4272 if (other->d_ptr->transformData) {
4273 QTransform otherToParent;
4274 other->d_ptr->combineTransformFromParent(&otherToParent);
4275 return otherToParent.inverted(ok);
4279 return QTransform::fromTranslate(-otherPos.x(), -otherPos.y());
4283 if (parent == otherParent) {
4285 const QPointF &itemPos = d_ptr->pos;
4286 const QPointF &otherPos = other->d_ptr->pos;
4287 if (!d_ptr->transformData && !other->d_ptr->transformData) {
4288 QPointF delta = itemPos - otherPos;
4291 return QTransform::fromTranslate(delta.x(), delta.y());
4294 QTransform itemToParent;
4295 d_ptr->combineTransformFromParent(&itemToParent);
4296 QTransform otherToParent;
4297 other->d_ptr->combineTransformFromParent(&otherToParent);
4298 return itemToParent * otherToParent.inverted(ok);
4301 // Find the closest common ancestor. If the two items don't share an
4302 // ancestor, then the only way is to combine their scene transforms.
4303 const QGraphicsItem *commonAncestor = commonAncestorItem(other);
4304 if (!commonAncestor) {
4305 d_ptr->ensureSceneTransform();
4306 other->d_ptr->ensureSceneTransform();
4307 return d_ptr->sceneTransform * other->d_ptr->sceneTransform.inverted(ok);
4310 // If the two items are cousins (in sibling branches), map both to the
4311 // common ancestor, and combine the two transforms.
4312 bool cousins = other != commonAncestor && this != commonAncestor;
4315 QTransform thisToScene = itemTransform(commonAncestor, &good);
4316 QTransform otherToScene(Qt::Uninitialized);
4318 otherToScene = other->itemTransform(commonAncestor, &good);
4322 return QTransform();
4324 return thisToScene * otherToScene.inverted(ok);
4327 // One is an ancestor of the other; walk the chain.
4328 bool parentOfOther = isAncestorOf(other);
4329 const QGraphicsItem *child = parentOfOther ? other : this;
4330 const QGraphicsItem *root = parentOfOther ? this : other;
4333 const QGraphicsItem *p = child;
4335 p->d_ptr.data()->combineTransformToParent(&x);
4336 } while ((p = p->d_ptr->parent) && p != root);
4338 return x.inverted(ok);
4347 Sets the item's affine transformation matrix. This is a subset or the
4348 item's full transformation matrix, and might not represent the item's full
4351 Use setTransform() instead.
4353 \sa transform(), {The Graphics View Coordinate System}
4355 void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
4357 if (!d_ptr->transformData)
4358 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4360 QTransform newTransform(combine ? QTransform(matrix) * d_ptr->transformData->transform : QTransform(matrix));
4361 if (d_ptr->transformData->transform == newTransform)
4364 // Update and set the new transformation.
4365 if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
4366 d_ptr->setTransformHelper(newTransform);
4370 // Notify the item that the transformation matrix is changing.
4371 const QVariant newMatrixVariant = QVariant::fromValue<QMatrix>(newTransform.toAffine());
4372 newTransform = QTransform(qvariant_cast<QMatrix>(itemChange(ItemMatrixChange, newMatrixVariant)));
4373 if (d_ptr->transformData->transform == newTransform)
4376 // Update and set the new transformation.
4377 d_ptr->setTransformHelper(newTransform);
4379 // Send post-notification.
4380 itemChange(ItemTransformHasChanged, QVariant::fromValue<QTransform>(newTransform));
4386 Sets the item's current transformation matrix to \a matrix.
4388 If \a combine is true, then \a matrix is combined with the current matrix;
4389 otherwise, \a matrix \e replaces the current matrix. \a combine is false
4392 To simplify interation with items using a transformed view, QGraphicsItem
4393 provides mapTo... and mapFrom... functions that can translate between
4394 items' and the scene's coordinates. For example, you can call mapToScene()
4395 to map an item coordiate to a scene coordinate, or mapFromScene() to map
4396 from scene coordinates to item coordinates.
4398 The transformation matrix is combined with the item's rotation(), scale()
4399 and transformations() into a combined transformation that maps the item's
4400 coordinate system to its parent.
4402 \sa transform(), setRotation(), setScale(), setTransformOriginPoint(), {The Graphics View Coordinate System}, {Transformations}
4404 void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
4406 if (!d_ptr->transformData)
4407 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4409 QTransform newTransform(combine ? matrix * d_ptr->transformData->transform : matrix);
4410 if (d_ptr->transformData->transform == newTransform)
4413 // Update and set the new transformation.
4414 if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
4415 d_ptr->setTransformHelper(newTransform);
4416 if (d_ptr->scenePosDescendants)
4417 d_ptr->sendScenePosChange();
4421 // Notify the item that the transformation matrix is changing.
4422 const QVariant newTransformVariant(itemChange(ItemTransformChange,
4423 QVariant::fromValue<QTransform>(newTransform)));
4424 newTransform = qvariant_cast<QTransform>(newTransformVariant);
4425 if (d_ptr->transformData->transform == newTransform)
4428 // Update and set the new transformation.
4429 d_ptr->setTransformHelper(newTransform);
4431 // Send post-notification.
4432 itemChange(ItemTransformHasChanged, newTransformVariant);
4433 d_ptr->sendScenePosChange();
4439 Use resetTransform() instead.
4441 void QGraphicsItem::resetMatrix()
4449 Resets this item's transformation matrix to the identity matrix or
4450 all the transformation properties to their default values.
4451 This is equivalent to calling \c setTransform(QTransform()).
4453 \sa setTransform(), transform()
4455 void QGraphicsItem::resetTransform()
4457 setTransform(QTransform(), false);
4466 setRotation(rotation() + angle);
4471 Rotates the current item transformation \a angle degrees clockwise around
4472 its origin. To translate around an arbitrary point (x, y), you need to
4473 combine translation and rotation with setTransform().
4477 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 6
4479 \sa setTransform(), transform(), scale(), shear(), translate()
4481 void QGraphicsItem::rotate(qreal angle)
4483 setTransform(QTransform().rotate(angle), true);
4492 setTransform(QTransform::fromScale(sx, sy), true);
4497 Scales the current item transformation by (\a sx, \a sy) around its
4498 origin. To scale from an arbitrary point (x, y), you need to combine
4499 translation and scaling with setTransform().
4503 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 7
4505 \sa setTransform(), transform()
4507 void QGraphicsItem::scale(qreal sx, qreal sy)
4509 setTransform(QTransform::fromScale(sx, sy), true);
4518 setTransform(QTransform().shear(sh, sv), true);
4523 Shears the current item transformation by (\a sh, \a sv).
4525 \sa setTransform(), transform()
4527 void QGraphicsItem::shear(qreal sh, qreal sv)
4529 setTransform(QTransform().shear(sh, sv), true);
4535 Use setPos() or setTransformOriginPoint() instead. For identical
4539 setTransform(QTransform::fromTranslate(dx, dy), true);
4542 Translates the current item transformation by (\a dx, \a dy).
4544 If all you want is to move an item, you should call moveBy() or
4545 setPos() instead; this function changes the item's translation,
4546 which is conceptually separate from its position.
4548 \sa setTransform(), transform()
4550 void QGraphicsItem::translate(qreal dx, qreal dy)
4552 setTransform(QTransform::fromTranslate(dx, dy), true);
4556 This virtual function is called twice for all items by the
4557 QGraphicsScene::advance() slot. In the first phase, all items are called
4558 with \a phase == 0, indicating that items on the scene are about to
4559 advance, and then all items are called with \a phase == 1. Reimplement
4560 this function to update your item if you need simple scene-controlled
4563 The default implementation does nothing.
4565 For individual item animation, an alternative to this function is to
4566 either use QGraphicsItemAnimation, or to multiple-inherit from QObject and
4567 QGraphicsItem, and animate your item using QObject::startTimer() and
4568 QObject::timerEvent().
4570 \sa QGraphicsItemAnimation, QTimeLine
4572 void QGraphicsItem::advance(int phase)
4578 Returns the Z-value of the item. The Z-value affects the stacking order of
4579 sibling (neighboring) items.
4581 The default Z-value is 0.
4583 \sa setZValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
4585 qreal QGraphicsItem::zValue() const
4591 Sets the Z-value of the item to \a z. The Z value decides the stacking
4592 order of sibling (neighboring) items. A sibling item of high Z value will
4593 always be drawn on top of another sibling item with a lower Z value.
4595 If you restore the Z value, the item's insertion order will decide its
4598 The Z-value does not affect the item's size in any way.
4600 The default Z-value is 0.
4602 \sa zValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
4604 void QGraphicsItem::setZValue(qreal z)
4606 const QVariant newZVariant(itemChange(ItemZValueChange, z));
4607 qreal newZ = newZVariant.toReal();
4608 if (newZ == d_ptr->z)
4611 if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
4612 // Z Value has changed, we have to notify the index.
4613 d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
4618 d_ptr->parent->d_ptr->needSortChildren = 1;
4619 else if (d_ptr->scene)
4620 d_ptr->scene->d_func()->needSortTopLevelItems = 1;
4623 d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
4625 itemChange(ItemZValueHasChanged, newZVariant);
4627 if (d_ptr->flags & ItemNegativeZStacksBehindParent)
4628 setFlag(QGraphicsItem::ItemStacksBehindParent, z < qreal(0.0));
4630 if (d_ptr->isObject)
4631 emit static_cast<QGraphicsObject *>(this)->zChanged();
4637 Ensures that the list of children is sorted by insertion order, and that
4638 the siblingIndexes are packed (no gaps), and start at 0.
4640 ### This function is almost identical to
4641 QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes().
4643 void QGraphicsItemPrivate::ensureSequentialSiblingIndex()
4645 if (!sequentialOrdering) {
4646 qSort(children.begin(), children.end(), insertionOrder);
4647 sequentialOrdering = 1;
4648 needSortChildren = 1;
4650 if (holesInSiblingIndex) {
4651 holesInSiblingIndex = 0;
4652 for (int i = 0; i < children.size(); ++i)
4653 children[i]->d_ptr->siblingIndex = i;
4660 inline void QGraphicsItemPrivate::sendScenePosChange()
4664 if (flags & QGraphicsItem::ItemSendsScenePositionChanges)
4665 q->itemChange(QGraphicsItem::ItemScenePositionHasChanged, q->scenePos());
4666 if (scenePosDescendants) {
4667 foreach (QGraphicsItem *item, scene->d_func()->scenePosItems) {
4668 if (q->isAncestorOf(item))
4669 item->itemChange(QGraphicsItem::ItemScenePositionHasChanged, item->scenePos());
4678 Stacks this item before \a sibling, which must be a sibling item (i.e., the
4679 two items must share the same parent item, or must both be toplevel items).
4680 The \a sibling must have the same Z value as this item, otherwise calling
4681 this function will have no effect.
4683 By default, all sibling items are stacked by insertion order (i.e., the
4684 first item you add is drawn before the next item you add). If two items' Z
4685 values are different, then the item with the highest Z value is drawn on
4686 top. When the Z values are the same, the insertion order will decide the
4689 \sa setZValue(), ItemStacksBehindParent, {QGraphicsItem#Sorting}{Sorting}
4691 void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
4693 if (sibling == this)
4695 if (!sibling || d_ptr->parent != sibling->parentItem()) {
4696 qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
4699 QList<QGraphicsItem *> *siblings = d_ptr->parent
4700 ? &d_ptr->parent->d_ptr->children
4701 : (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0);
4703 qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
4707 // First, make sure that the sibling indexes have no holes. This also
4708 // marks the children list for sorting.
4710 d_ptr->parent->d_ptr->ensureSequentialSiblingIndex();
4712 d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
4714 // Only move items with the same Z value, and that need moving.
4715 int siblingIndex = sibling->d_ptr->siblingIndex;
4716 int myIndex = d_ptr->siblingIndex;
4717 if (myIndex >= siblingIndex) {
4718 siblings->move(myIndex, siblingIndex);
4719 // Fixup the insertion ordering.
4720 for (int i = 0; i < siblings->size(); ++i) {
4721 int &index = siblings->at(i)->d_ptr->siblingIndex;
4722 if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
4725 d_ptr->siblingIndex = siblingIndex;
4726 for (int i = 0; i < siblings->size(); ++i) {
4727 int &index = siblings->at(i)->d_ptr->siblingIndex;
4728 if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
4729 siblings->at(i)->d_ptr->siblingOrderChange();
4731 d_ptr->siblingOrderChange();
4736 Returns the bounding rect of this item's descendants (i.e., its
4737 children, their children, etc.) in local coordinates. The
4738 rectangle will contain all descendants after they have been mapped
4739 to local coordinates. If the item has no children, this function
4740 returns an empty QRectF.
4742 This does not include this item's own bounding rect; it only returns
4743 its descendants' accumulated bounding rect. If you need to include this
4744 item's bounding rect, you can add boundingRect() to childrenBoundingRect()
4745 using QRectF::operator|().
4747 This function is linear in complexity; it determines the size of the
4748 returned bounding rect by iterating through all descendants.
4750 \sa boundingRect(), sceneBoundingRect()
4752 QRectF QGraphicsItem::childrenBoundingRect() const
4754 if (!d_ptr->dirtyChildrenBoundingRect)
4755 return d_ptr->childrenBoundingRect;
4757 d_ptr->childrenBoundingRect = QRectF();
4758 d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect, 0);
4759 d_ptr->dirtyChildrenBoundingRect = 0;
4760 return d_ptr->childrenBoundingRect;
4764 \fn virtual QRectF QGraphicsItem::boundingRect() const = 0
4766 This pure virtual function defines the outer bounds of the item as
4767 a rectangle; all painting must be restricted to inside an item's
4768 bounding rect. QGraphicsView uses this to determine whether the
4769 item requires redrawing.
4771 Although the item's shape can be arbitrary, the bounding rect is
4772 always rectangular, and it is unaffected by the items'
4775 If you want to change the item's bounding rectangle, you must first call
4776 prepareGeometryChange(). This notifies the scene of the imminent change,
4777 so that its can update its item geometry index; otherwise, the scene will
4778 be unaware of the item's new geometry, and the results are undefined
4779 (typically, rendering artifacts are left around in the view).
4781 Reimplement this function to let QGraphicsView determine what
4782 parts of the widget, if any, need to be redrawn.
4784 Note: For shapes that paint an outline / stroke, it is important
4785 to include half the pen width in the bounding rect. It is not
4786 necessary to compensate for antialiasing, though.
4790 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 8
4792 \sa boundingRegion(), shape(), contains(), {The Graphics View Coordinate
4793 System}, prepareGeometryChange()
4797 Returns the bounding rect of this item in scene coordinates, by combining
4798 sceneTransform() with boundingRect().
4800 \sa boundingRect(), {The Graphics View Coordinate System}
4802 QRectF QGraphicsItem::sceneBoundingRect() const
4804 // Find translate-only offset
4807 const QGraphicsItem *parentItem = this;
4808 const QGraphicsItemPrivate *itemd;
4810 itemd = parentItem->d_ptr.data();
4811 if (itemd->transformData)
4813 offset += itemd->pos;
4814 } while ((parentItem = itemd->parent));
4816 QRectF br = boundingRect();
4817 br.translate(offset);
4820 if (parentItem->d_ptr->hasTranslateOnlySceneTransform()) {
4821 br.translate(parentItem->d_ptr->sceneTransform.dx(), parentItem->d_ptr->sceneTransform.dy());
4824 return parentItem->d_ptr->sceneTransform.mapRect(br);
4828 Returns the shape of this item as a QPainterPath in local
4829 coordinates. The shape is used for many things, including collision
4830 detection, hit tests, and for the QGraphicsScene::items() functions.
4832 The default implementation calls boundingRect() to return a simple
4833 rectangular shape, but subclasses can reimplement this function to return
4834 a more accurate shape for non-rectangular items. For example, a round item
4835 may choose to return an elliptic shape for better collision detection. For
4838 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 9
4840 The outline of a shape can vary depending on the width and style of the
4841 pen used when drawing. If you want to include this outline in the item's
4842 shape, you can create a shape from the stroke using QPainterPathStroker.
4844 This function is called by the default implementations of contains() and
4847 \sa boundingRect(), contains(), prepareGeometryChange(), QPainterPathStroker
4849 QPainterPath QGraphicsItem::shape() const
4852 path.addRect(boundingRect());
4857 Returns true if this item is clipped. An item is clipped if it has either
4858 set the \l ItemClipsToShape flag, or if it or any of its ancestors has set
4859 the \l ItemClipsChildrenToShape flag.
4861 Clipping affects the item's appearance (i.e., painting), as well as mouse
4862 and hover event delivery.
4864 \sa clipPath(), shape(), setFlags()
4866 bool QGraphicsItem::isClipped() const
4868 Q_D(const QGraphicsItem);
4869 return (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
4870 || (d->flags & QGraphicsItem::ItemClipsToShape);
4876 Returns this item's clip path, or an empty QPainterPath if this item is
4877 not clipped. The clip path constrains the item's appearance and
4878 interaction (i.e., restricts the area the item can draw, and it also
4879 restricts the area that the item receives events).
4881 You can enable clipping by setting the ItemClipsToShape or
4882 ItemClipsChildrenToShape flags. The item's clip path is calculated by
4883 intersecting all clipping ancestors' shapes. If the item sets
4884 ItemClipsToShape, the final clip is intersected with the item's own shape.
4886 \note Clipping introduces a performance penalty for all items involved;
4887 you should generally avoid using clipping if you can (e.g., if your items
4888 always draw inside boundingRect() or shape() boundaries, clipping is not
4891 \sa isClipped(), shape(), setFlags()
4893 QPainterPath QGraphicsItem::clipPath() const
4895 Q_D(const QGraphicsItem);
4897 return QPainterPath();
4899 const QRectF thisBoundingRect(boundingRect());
4900 if (thisBoundingRect.isEmpty())
4901 return QPainterPath();
4904 // Start with the item's bounding rect.
4905 clip.addRect(thisBoundingRect);
4907 if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
4908 const QGraphicsItem *parent = this;
4909 const QGraphicsItem *lastParent = this;
4911 // Intersect any in-between clips starting at the top and moving downwards.
4912 while ((parent = parent->d_ptr->parent)) {
4913 if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
4914 // Map clip to the current parent and intersect with its shape/clipPath
4915 clip = lastParent->itemTransform(parent).map(clip);
4916 clip = clip.intersected(parent->shape());
4919 lastParent = parent;
4922 if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
4926 if (lastParent != this) {
4927 // Map clip back to the item's transform.
4928 // ### what if itemtransform fails
4929 clip = lastParent->itemTransform(this).map(clip);
4933 if (d->flags & ItemClipsToShape)
4934 clip = clip.intersected(shape());
4940 Returns true if this item contains \a point, which is in local
4941 coordinates; otherwise, false is returned. It is most often called from
4942 QGraphicsView to determine what item is under the cursor, and for that
4943 reason, the implementation of this function should be as light-weight as
4946 By default, this function calls shape(), but you can reimplement it in a
4947 subclass to provide a (perhaps more efficient) implementation.
4949 \sa shape(), boundingRect(), collidesWithPath()
4951 bool QGraphicsItem::contains(const QPointF &point) const
4953 return isClipped() ? clipPath().contains(point) : shape().contains(point);
4958 Returns true if this item collides with \a other; otherwise
4961 The \a mode is applied to \a other, and the resulting shape or
4962 bounding rectangle is then compared to this item's shape. The
4963 default value for \a mode is Qt::IntersectsItemShape; \a other
4964 collides with this item if it either intersects, contains, or is
4965 contained by this item's shape (see Qt::ItemSelectionMode for
4968 The default implementation is based on shape intersection, and it calls
4969 shape() on both items. Because the complexity of arbitrary shape-shape
4970 intersection grows with an order of magnitude when the shapes are complex,
4971 this operation can be noticably time consuming. You have the option of
4972 reimplementing this function in a subclass of QGraphicsItem to provide a
4973 custom algorithm. This allows you to make use of natural constraints in
4974 the shapes of your own items, in order to improve the performance of the
4975 collision detection. For instance, two untransformed perfectly circular
4976 items' collision can be determined very efficiently by comparing their
4977 positions and radii.
4979 Keep in mind that when reimplementing this function and calling shape() or
4980 boundingRect() on \a other, the returned coordinates must be mapped to
4981 this item's coordinate system before any intersection can take place.
4983 \sa contains(), shape()
4985 bool QGraphicsItem::collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode) const
4991 // The items share the same clip if their closest clipper is the same, or
4992 // if one clips the other.
4993 bool clips = (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
4994 bool otherClips = (other->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
4995 if (clips || otherClips) {
4996 const QGraphicsItem *closestClipper = isAncestorOf(other) ? this : parentItem();
4997 while (closestClipper && !(closestClipper->flags() & ItemClipsChildrenToShape))
4998 closestClipper = closestClipper->parentItem();
4999 const QGraphicsItem *otherClosestClipper = other->isAncestorOf(this) ? other : other->parentItem();
5000 while (otherClosestClipper && !(otherClosestClipper->flags() & ItemClipsChildrenToShape))
5001 otherClosestClipper = otherClosestClipper->parentItem();
5002 if (closestClipper == otherClosestClipper) {
5003 d_ptr->localCollisionHack = 1;
5004 bool res = collidesWithPath(mapFromItem(other, other->shape()), mode);
5005 d_ptr->localCollisionHack = 0;
5010 QPainterPath otherShape = other->isClipped() ? other->clipPath() : other->shape();
5011 return collidesWithPath(mapFromItem(other, otherShape), mode);
5015 Returns true if this item collides with \a path.
5017 The collision is determined by \a mode. The default value for \a mode is
5018 Qt::IntersectsItemShape; \a path collides with this item if it either
5019 intersects, contains, or is contained by this item's shape.
5021 Note that this function checks whether the item's shape or
5022 bounding rectangle (depending on \a mode) is contained within \a
5023 path, and not whether \a path is contained within the items shape
5024 or bounding rectangle.
5026 \sa collidesWithItem(), contains(), shape()
5028 bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelectionMode mode) const
5030 if (path.isEmpty()) {
5031 // No collision with empty paths.
5035 QRectF rectA(boundingRect());
5036 _q_adjustRect(&rectA);
5037 QRectF rectB(path.controlPointRect());
5038 _q_adjustRect(&rectB);
5039 if (!rectA.intersects(rectB)) {
5040 // This we can determine efficiently. If the two rects neither
5041 // intersect nor contain eachother, then the two items do not collide.
5045 // For further testing, we need this item's shape or bounding rect.
5046 QPainterPath thisShape;
5047 if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape)
5048 thisShape = (isClipped() && !d_ptr->localCollisionHack) ? clipPath() : shape();
5050 thisShape.addRect(rectA);
5052 if (thisShape == QPainterPath()) {
5053 // Empty shape? No collision.
5057 // Use QPainterPath boolean operations to determine the collision, O(N*logN).
5058 if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
5059 return path.intersects(thisShape);
5060 return path.contains(thisShape);
5064 Returns a list of all items that collide with this item.
5066 The way collisions are detected is determined by applying \a mode
5067 to items that are compared to this item, i.e., each item's shape
5068 or bounding rectangle is checked against this item's shape. The
5069 default value for \a mode is Qt::IntersectsItemShape.
5071 \sa collidesWithItem()
5073 QList<QGraphicsItem *> QGraphicsItem::collidingItems(Qt::ItemSelectionMode mode) const
5076 return d_ptr->scene->collidingItems(this, mode);
5077 return QList<QGraphicsItem *>();
5081 Returns true if this item's bounding rect is completely obscured by the
5082 opaque shape of any of colliding items above it (i.e., with a higher Z
5083 value than this item).
5085 Its implementation is based on calling isObscuredBy(), which you can
5086 reimplement to provide a custom obscurity algorithm.
5090 bool QGraphicsItem::isObscured() const
5092 return isObscured(QRectF());
5098 Item obscurity helper function.
5100 Returns true if the subrect \a rect of \a item's bounding rect is obscured
5101 by \a other (i.e., \a other's opaque area covers \a item's \a rect
5102 completely. \a other is assumed to already be "on top of" \a item
5103 wrt. stacking order.
5105 static bool qt_QGraphicsItem_isObscured(const QGraphicsItem *item,
5106 const QGraphicsItem *other,
5109 return other->mapToItem(item, other->opaqueArea()).contains(rect);
5116 Returns true if \a rect is completely obscured by the opaque shape of any
5117 of colliding items above it (i.e., with a higher Z value than this item).
5119 Unlike the default isObscured() function, this function does not call
5124 bool QGraphicsItem::isObscured(const QRectF &rect) const
5126 Q_D(const QGraphicsItem);
5130 QRectF br = boundingRect();
5131 QRectF testRect = rect.isNull() ? br : rect;
5133 foreach (QGraphicsItem *item, d->scene->items(mapToScene(br), Qt::IntersectsItemBoundingRect)) {
5136 if (qt_QGraphicsItem_isObscured(this, item, testRect))
5143 \fn bool QGraphicsItem::isObscured(qreal x, qreal y, qreal w, qreal h) const
5146 This convenience function is equivalent to calling isObscured(QRectF(\a x, \a y, \a w, \a h)).
5150 Returns true if this item's bounding rect is completely obscured by the
5151 opaque shape of \a item.
5153 The base implementation maps \a item's opaqueArea() to this item's
5154 coordinate system, and then checks if this item's boundingRect() is fully
5155 contained within the mapped shape.
5157 You can reimplement this function to provide a custom algorithm for
5158 determining whether this item is obscured by \a item.
5160 \sa opaqueArea(), isObscured()
5162 bool QGraphicsItem::isObscuredBy(const QGraphicsItem *item) const
5166 return qt_closestItemFirst(item, this)
5167 && qt_QGraphicsItem_isObscured(this, item, boundingRect());
5171 This virtual function returns a shape representing the area where this
5172 item is opaque. An area is opaque if it is filled using an opaque brush or
5173 color (i.e., not transparent).
5175 This function is used by isObscuredBy(), which is called by underlying
5176 items to determine if they are obscured by this item.
5178 The default implementation returns an empty QPainterPath, indicating that
5179 this item is completely transparent and does not obscure any other items.
5181 \sa isObscuredBy(), isObscured(), shape()
5183 QPainterPath QGraphicsItem::opaqueArea() const
5185 return QPainterPath();
5191 Returns the bounding region for this item. The coordinate space of the
5192 returned region depends on \a itemToDeviceTransform. If you pass an
5193 identity QTransform as a parameter, this function will return a local
5196 The bounding region describes a coarse outline of the item's visual
5197 contents. Although it's expensive to calculate, it's also more precise
5198 than boundingRect(), and it can help to avoid unnecessary repainting when
5199 an item is updated. This is particularly efficient for thin items (e.g.,
5200 lines or simple polygons). You can tune the granularity for the bounding
5201 region by calling setBoundingRegionGranularity(). The default granularity
5202 is 0; in which the item's bounding region is the same as its bounding
5205 \a itemToDeviceTransform is the transformation from item coordinates to
5206 device coordinates. If you want this function to return a QRegion in scene
5207 coordinates, you can pass sceneTransform() as an argument.
5209 \sa boundingRegionGranularity()
5211 QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) const
5213 // ### Ideally we would have a better way to generate this region,
5214 // preferably something in the lines of QPainterPath::toRegion(QTransform)
5215 // coupled with a way to generate a painter path from a set of painter
5216 // operations (e.g., QPicture::toPainterPath() or so). The current
5217 // approach generates a bitmap with the size of the item's bounding rect
5218 // in device coordinates, scaled by b.r.granularity, then paints the item
5219 // into the bitmap, converts the result to a QRegion and scales the region
5220 // back to device space with inverse granularity.
5221 qreal granularity = boundingRegionGranularity();
5222 QRect deviceRect = itemToDeviceTransform.mapRect(boundingRect()).toRect();
5223 _q_adjustRect(&deviceRect);
5224 if (granularity == 0.0)
5225 return QRegion(deviceRect);
5228 QSize bitmapSize(qMax(1, int(deviceRect.width() * granularity) + pad * 2),
5229 qMax(1, int(deviceRect.height() * granularity) + pad * 2));
5230 QImage mask(bitmapSize, QImage::Format_ARGB32_Premultiplied);
5233 p.setRenderHints(QPainter::Antialiasing);
5235 // Transform painter (### this code is from QGraphicsScene::drawItemHelper
5236 // and doesn't work properly with perspective transformations).
5237 QPointF viewOrigo = itemToDeviceTransform.map(QPointF(0, 0));
5238 QPointF offset = viewOrigo - deviceRect.topLeft();
5239 p.scale(granularity, granularity);
5240 p.translate(offset);
5241 p.translate(pad, pad);
5242 p.setWorldTransform(itemToDeviceTransform, true);
5243 p.translate(itemToDeviceTransform.inverted().map(QPointF(0, 0)));
5246 QStyleOptionGraphicsItem option;
5247 const_cast<QGraphicsItem *>(this)->paint(&p, &option, 0);
5250 // Transform QRegion back to device space
5251 QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity);
5253 QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0));
5254 foreach (const QRect &rect, QRegion( colorMask ).rects()) {
5255 QRect xrect = unscale.mapRect(rect).translated(deviceRect.topLeft() - QPoint(pad, pad));
5256 r += xrect.adjusted(-1, -1, 1, 1) & deviceRect;
5264 Returns the item's bounding region granularity; a value between and
5265 including 0 and 1. The default value is 0 (i.e., the lowest granularity,
5266 where the bounding region corresponds to the item's bounding rectangle).
5272 \sa setBoundingRegionGranularity()
5274 qreal QGraphicsItem::boundingRegionGranularity() const
5276 return d_ptr->hasBoundingRegionGranularity
5277 ? qvariant_cast<qreal>(d_ptr->extra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity))
5283 Sets the bounding region granularity to \a granularity; a value between
5284 and including 0 and 1. The default value is 0 (i.e., the lowest
5285 granularity, where the bounding region corresponds to the item's bounding
5288 The granularity is used by boundingRegion() to calculate how fine the
5289 bounding region of the item should be. The highest achievable granularity
5290 is 1, where boundingRegion() will return the finest outline possible for
5291 the respective device (e.g., for a QGraphicsView viewport, this gives you
5292 a pixel-perfect bounding region). The lowest possible granularity is
5293 0. The value of \a granularity describes the ratio between device
5294 resolution and the resolution of the bounding region (e.g., a value of
5295 0.25 will provide a region where each chunk corresponds to 4x4 device
5298 \sa boundingRegionGranularity()
5300 void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
5302 if (granularity < 0.0 || granularity > 1.0) {
5303 qWarning("QGraphicsItem::setBoundingRegionGranularity: invalid granularity %g", granularity);
5306 if (granularity == 0.0) {
5307 d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity);
5308 d_ptr->hasBoundingRegionGranularity = 0;
5311 d_ptr->hasBoundingRegionGranularity = 1;
5312 d_ptr->setExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity,
5313 QVariant::fromValue<qreal>(granularity));
5317 \fn virtual void QGraphicsItem::paint(QPainter *painter, const
5318 QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0
5320 This function, which is usually called by QGraphicsView, paints the
5321 contents of an item in local coordinates.
5323 Reimplement this function in a QGraphicsItem subclass to provide the
5324 item's painting implementation, using \a painter. The \a option parameter
5325 provides style options for the item, such as its state, exposed area and
5326 its level-of-detail hints. The \a widget argument is optional. If
5327 provided, it points to the widget that is being painted on; otherwise, it
5328 is 0. For cached painting, \a widget is always 0.
5330 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 10
5332 The painter's pen is 0-width by default, and its pen is initialized to the
5333 QPalette::Text brush from the paint device's palette. The brush is
5334 initialized to QPalette::Window.
5336 Make sure to constrain all painting inside the boundaries of
5337 boundingRect() to avoid rendering artifacts (as QGraphicsView does not
5338 clip the painter for you). In particular, when QPainter renders the
5339 outline of a shape using an assigned QPen, half of the outline will be
5340 drawn outside, and half inside, the shape you're rendering (e.g., with a
5341 pen width of 2 units, you must draw outlines 1 unit inside
5342 boundingRect()). QGraphicsItem does not support use of cosmetic pens with
5345 All painting is done in local coordinates.
5347 \sa setCacheMode(), QPen::width(), {Item Coordinates}, ItemUsesExtendedStyleOption
5352 Returns true if we can discard an update request; otherwise false.
5354 bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreVisibleBit, bool ignoreDirtyBit,
5355 bool ignoreOpacity) const
5357 // No scene, or if the scene is updating everything, means we have nothing
5358 // to do. The only exception is if the scene tracks the growing scene rect.
5360 || (!visible && !ignoreVisibleBit && !this->ignoreVisible)
5361 || (!ignoreDirtyBit && fullUpdatePending)
5362 || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent());
5368 int QGraphicsItemPrivate::depth() const
5370 if (itemDepth == -1)
5371 const_cast<QGraphicsItemPrivate *>(this)->resolveDepth();
5379 #ifndef QT_NO_GRAPHICSEFFECT
5380 void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
5382 QGraphicsItemPrivate *itemPrivate = this;
5384 if (itemPrivate->graphicsEffect) {
5385 itemPrivate->notifyInvalidated = 1;
5387 if (!itemPrivate->updateDueToGraphicsEffect)
5388 static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
5390 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
5393 void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason)
5395 if (!mayHaveChildWithGraphicsEffect)
5398 for (int i = 0; i < children.size(); ++i) {
5399 QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data();
5400 if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity))
5402 if (childPrivate->graphicsEffect) {
5403 childPrivate->notifyInvalidated = 1;
5404 static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
5407 childPrivate->invalidateChildGraphicsEffectsRecursively(reason);
5410 #endif //QT_NO_GRAPHICSEFFECT
5415 void QGraphicsItemPrivate::invalidateDepthRecursively()
5417 if (itemDepth == -1)
5421 for (int i = 0; i < children.size(); ++i)
5422 children.at(i)->d_ptr->invalidateDepthRecursively();
5428 Resolves the stacking depth of this object and all its ancestors.
5430 void QGraphicsItemPrivate::resolveDepth()
5435 if (parent->d_ptr->itemDepth == -1)
5436 parent->d_ptr->resolveDepth();
5437 itemDepth = parent->d_ptr->itemDepth + 1;
5444 ### This function is almost identical to
5445 QGraphicsScenePrivate::registerTopLevelItem().
5447 void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
5449 // Remove all holes from the sibling index list. Now the max index
5450 // number is equal to the size of the children list.
5451 ensureSequentialSiblingIndex();
5452 needSortChildren = 1; // ### maybe 0
5453 child->d_ptr->siblingIndex = children.size();
5454 children.append(child);
5456 emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
5462 ### This function is almost identical to
5463 QGraphicsScenePrivate::unregisterTopLevelItem().
5465 void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
5467 // When removing elements in the middle of the children list,
5468 // there will be a "gap" in the list of sibling indexes (0,1,3,4).
5469 if (!holesInSiblingIndex)
5470 holesInSiblingIndex = child->d_ptr->siblingIndex != children.size() - 1;
5471 if (sequentialOrdering && !holesInSiblingIndex)
5472 children.removeAt(child->d_ptr->siblingIndex);
5474 children.removeOne(child);
5475 // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
5476 // the child is not guaranteed to be at the index after the list is sorted.
5477 // (see ensureSortedChildren()).
5478 child->d_ptr->siblingIndex = -1;
5480 emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
5486 QGraphicsItemCache *QGraphicsItemPrivate::maybeExtraItemCache() const
5488 return (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5494 QGraphicsItemCache *QGraphicsItemPrivate::extraItemCache() const
5496 QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5498 QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this);
5499 c = new QGraphicsItemCache;
5500 that->setExtra(ExtraCacheData, QVariant::fromValue<void *>(c));
5508 void QGraphicsItemPrivate::removeExtraItemCache()
5510 QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5515 unsetExtra(ExtraCacheData);
5518 void QGraphicsItemPrivate::updatePaintedViewBoundingRects(bool updateChildren)
5523 for (int i = 0; i < scene->d_func()->views.size(); ++i) {
5524 QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func();
5525 QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport);
5526 rect.translate(viewPrivate->dirtyScrollOffset);
5527 viewPrivate->updateRect(rect);
5530 if (updateChildren) {
5531 for (int i = 0; i < children.size(); ++i)
5532 children.at(i)->d_ptr->updatePaintedViewBoundingRects(true);
5536 // Traverses all the ancestors up to the top-level and updates the pointer to
5537 // always point to the top-most item that has a dirty scene transform.
5538 // It then backtracks to the top-most dirty item and start calculating the
5539 // scene transform by combining the item's transform (+pos) with the parent's
5540 // cached scene transform (which we at this point know for sure is valid).
5541 void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem)
5543 Q_ASSERT(topMostDirtyItem);
5545 if (dirtySceneTransform)
5546 *topMostDirtyItem = q_ptr;
5549 parent->d_ptr->ensureSceneTransformRecursive(topMostDirtyItem);
5551 if (*topMostDirtyItem == q_ptr) {
5552 if (!dirtySceneTransform)
5553 return; // OK, neither my ancestors nor I have dirty scene transforms.
5554 *topMostDirtyItem = 0;
5555 } else if (*topMostDirtyItem) {
5556 return; // Continue backtrack.
5559 // This item and all its descendants have dirty scene transforms.
5560 // We're about to validate this item's scene transform, so we have to
5561 // invalidate all the children; otherwise there's no way for the descendants
5562 // to detect that the ancestor has changed.
5563 invalidateChildrenSceneTransform();
5565 // COMBINE my transform with the parent's scene transform.
5566 updateSceneTransformFromParent();
5567 Q_ASSERT(!dirtySceneTransform);
5573 void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
5575 // Update focus child chain. Stop at panels, or if this item
5576 // is hidden, stop at the first item with a visible parent.
5577 QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
5578 if (parent->panel() != q_ptr->panel())
5582 // Clear any existing ancestor's subFocusItem.
5583 if (parent != q_ptr && parent->d_ptr->subFocusItem) {
5584 if (parent->d_ptr->subFocusItem == q_ptr)
5586 parent->d_ptr->subFocusItem->d_ptr->clearSubFocus(0, stopItem);
5588 parent->d_ptr->subFocusItem = q_ptr;
5589 parent->d_ptr->subFocusItemChange();
5590 } while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
5592 if (scene && !scene->isActive()) {
5593 scene->d_func()->passiveFocusItem = subFocusItem;
5594 scene->d_func()->lastFocusItem = subFocusItem;
5601 void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
5603 // Reset sub focus chain.
5604 QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
5606 if (parent->d_ptr->subFocusItem != q_ptr)
5608 parent->d_ptr->subFocusItem = 0;
5609 if (parent != stopItem && !parent->isAncestorOf(stopItem))
5610 parent->d_ptr->subFocusItemChange();
5611 } while (!parent->isPanel() && (parent = parent->d_ptr->parent));
5617 Sets the focusProxy pointer to 0 for all items that have this item as their
5618 focusProxy. ### Qt 5: Use QPointer instead.
5620 void QGraphicsItemPrivate::resetFocusProxy()
5622 for (int i = 0; i < focusProxyRefs.size(); ++i)
5623 *focusProxyRefs.at(i) = 0;
5624 focusProxyRefs.clear();
5630 Subclasses can reimplement this function to be notified when subFocusItem
5633 void QGraphicsItemPrivate::subFocusItemChange()
5640 Subclasses can reimplement this function to be notified when an item
5641 becomes a focusScopeItem (or is no longer a focusScopeItem).
5643 void QGraphicsItemPrivate::focusScopeItemChange(bool isSubFocusItem)
5645 Q_UNUSED(isSubFocusItem);
5651 Subclasses can reimplement this function to be notified when its
5652 siblingIndex order is changed.
5654 void QGraphicsItemPrivate::siblingOrderChange()
5661 Tells us if it is a proxy widget
5663 bool QGraphicsItemPrivate::isProxyWidget() const
5669 Schedules a redraw of the area covered by \a rect in this item. You can
5670 call this function whenever your item needs to be redrawn, such as if it
5671 changes appearance or size.
5673 This function does not cause an immediate paint; instead it schedules a
5674 paint request that is processed by QGraphicsView after control reaches the
5675 event loop. The item will only be redrawn if it is visible in any
5678 As a side effect of the item being repainted, other items that overlap the
5679 area \a rect may also be repainted.
5681 If the item is invisible (i.e., isVisible() returns false), this function
5684 \sa paint(), boundingRect()
5686 void QGraphicsItem::update(const QRectF &rect)
5688 if (rect.isEmpty() && !rect.isNull())
5691 // Make sure we notify effects about invalidated source.
5692 #ifndef QT_NO_GRAPHICSEFFECT
5693 d_ptr->invalidateParentGraphicsEffectsRecursively();
5694 #endif //QT_NO_GRAPHICSEFFECT
5696 if (CacheMode(d_ptr->cacheMode) != NoCache) {
5697 // Invalidate cache.
5698 QGraphicsItemCache *cache = d_ptr->extraItemCache();
5699 if (!cache->allExposed) {
5700 if (rect.isNull()) {
5701 cache->allExposed = true;
5702 cache->exposed.clear();
5704 cache->exposed.append(rect);
5707 // Only invalidate cache; item is already dirty.
5708 if (d_ptr->fullUpdatePending)
5713 d_ptr->scene->d_func()->markDirty(this, rect);
5718 Scrolls the contents of \a rect by \a dx, \a dy. If \a rect is a null rect
5719 (the default), the item's bounding rect is scrolled.
5721 Scrolling provides a fast alternative to simply redrawing when the
5722 contents of the item (or parts of the item) are shifted vertically or
5723 horizontally. Depending on the current transformation and the capabilities
5724 of the paint device (i.e., the viewport), this operation may consist of
5725 simply moving pixels from one location to another using memmove(). In most
5726 cases this is faster than rerendering the entire area.
5728 After scrolling, the item will issue an update for the newly exposed
5729 areas. If scrolling is not supported (e.g., you are rendering to an OpenGL
5730 viewport, which does not benefit from scroll optimizations), this function
5731 is equivalent to calling update(\a rect).
5733 \b{Note:} Scrolling is only supported when QGraphicsItem::ItemCoordinateCache
5734 is enabled; in all other cases calling this function is equivalent to calling
5735 update(\a rect). If you for sure know that the item is opaque and not overlapped
5736 by other items, you can map the \a rect to viewport coordinates and scroll the
5739 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 19
5743 void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
5746 if (dx == 0.0 && dy == 0.0)
5751 // Accelerated scrolling means moving pixels from one location to another
5752 // and only redraw the newly exposed area. The following requirements must
5753 // be fulfilled in order to do that:
5755 // 1) Item is opaque.
5756 // 2) Item is not overlapped by other items.
5758 // There's (yet) no way to detect whether an item is opaque or not, which means
5759 // we cannot do accelerated scrolling unless the cache is enabled. In case of using
5760 // DeviceCoordinate cache we also have to take the device transform into account in
5761 // order to determine whether we can do accelerated scrolling or not. That's left out
5762 // for simplicity here, but it is definitely something we can consider in the future
5763 // as a performance improvement.
5764 if (d->cacheMode != QGraphicsItem::ItemCoordinateCache
5765 || !qFuzzyIsNull(dx - int(dx)) || !qFuzzyIsNull(dy - int(dy))) {
5770 QGraphicsItemCache *cache = d->extraItemCache();
5771 if (cache->allExposed || cache->fixedSize.isValid()) {
5772 // Cache is either invalidated or item is scaled (see QGraphicsItem::setCacheMode).
5777 // Find pixmap in cache.
5778 QPixmap cachedPixmap;
5779 if (!QPixmapCache::find(cache->key, &cachedPixmap)) {
5784 QRect scrollRect = (rect.isNull() ? boundingRect() : rect).toAlignedRect();
5785 if (!scrollRect.intersects(cache->boundingRect))
5786 return; // Nothing to scroll.
5788 // Remove from cache to avoid deep copy when modifying.
5789 QPixmapCache::remove(cache->key);
5792 cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed);
5794 // Reinsert into cache.
5795 cache->key = QPixmapCache::insert(cachedPixmap);
5797 // Translate the existing expose.
5798 for (int i = 0; i < cache->exposed.size(); ++i) {
5799 QRectF &e = cache->exposed[i];
5800 if (!rect.isNull() && !e.intersects(rect))
5802 e.translate(dx, dy);
5805 // Append newly exposed areas. Note that the exposed region is currently
5806 // in pixmap coordinates, so we have to translate it to item coordinates.
5807 exposed.translate(cache->boundingRect.topLeft());
5808 const QVector<QRect> exposedRects = exposed.rects();
5809 for (int i = 0; i < exposedRects.size(); ++i)
5810 cache->exposed += exposedRects.at(i);
5812 // Trigger update. This will redraw the newly exposed area and make sure
5813 // the pixmap is re-blitted in case there are overlapping items.
5814 d->scene->d_func()->markDirty(this, rect);
5818 \fn void QGraphicsItem::update(qreal x, qreal y, qreal width, qreal height)
5821 This convenience function is equivalent to calling update(QRectF(\a x, \a
5822 y, \a width, \a height)).
5826 Maps the point \a point, which is in this item's coordinate system, to \a
5827 item's coordinate system, and returns the mapped coordinate.
5829 If \a item is 0, this function returns the same as mapToScene().
5831 \sa itemTransform(), mapToParent(), mapToScene(), transform(), mapFromItem(), {The Graphics
5832 View Coordinate System}
5834 QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF &point) const
5837 return itemTransform(item).map(point);
5838 return mapToScene(point);
5842 \fn QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y) const
5845 This convenience function is equivalent to calling mapToItem(\a item,
5846 QPointF(\a x, \a y)).
5850 Maps the point \a point, which is in this item's coordinate system, to its
5851 parent's coordinate system, and returns the mapped coordinate. If the item
5852 has no parent, \a point will be mapped to the scene's coordinate system.
5854 \sa mapToItem(), mapToScene(), transform(), mapFromParent(), {The Graphics
5855 View Coordinate System}
5857 QPointF QGraphicsItem::mapToParent(const QPointF &point) const
5860 if (!d_ptr->transformData)
5861 return point + d_ptr->pos;
5862 return d_ptr->transformToParent().map(point);
5866 \fn QPointF QGraphicsItem::mapToParent(qreal x, qreal y) const
5869 This convenience function is equivalent to calling mapToParent(QPointF(\a
5874 Maps the point \a point, which is in this item's coordinate system, to the
5875 scene's coordinate system, and returns the mapped coordinate.
5877 \sa mapToItem(), mapToParent(), transform(), mapFromScene(), {The Graphics
5878 View Coordinate System}
5880 QPointF QGraphicsItem::mapToScene(const QPointF &point) const
5882 if (d_ptr->hasTranslateOnlySceneTransform())
5883 return QPointF(point.x() + d_ptr->sceneTransform.dx(), point.y() + d_ptr->sceneTransform.dy());
5884 return d_ptr->sceneTransform.map(point);
5888 \fn QPointF QGraphicsItem::mapToScene(qreal x, qreal y) const
5891 This convenience function is equivalent to calling mapToScene(QPointF(\a
5896 Maps the rectangle \a rect, which is in this item's coordinate system, to
5897 \a item's coordinate system, and returns the mapped rectangle as a polygon.
5899 If \a item is 0, this function returns the same as mapToScene().
5901 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5902 Graphics View Coordinate System}
5904 QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect) const
5907 return itemTransform(item).map(rect);
5908 return mapToScene(rect);
5912 \fn QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
5915 This convenience function is equivalent to calling mapToItem(item, QRectF(\a x, \a y, \a w, \a h)).
5919 Maps the rectangle \a rect, which is in this item's coordinate system, to
5920 its parent's coordinate system, and returns the mapped rectangle as a
5921 polygon. If the item has no parent, \a rect will be mapped to the scene's
5924 \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
5927 QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
5930 if (!d_ptr->transformData)
5931 return rect.translated(d_ptr->pos);
5932 return d_ptr->transformToParent().map(rect);
5936 \fn QPolygonF QGraphicsItem::mapToParent(qreal x, qreal y, qreal w, qreal h) const
5939 This convenience function is equivalent to calling mapToParent(QRectF(\a x, \a y, \a w, \a h)).
5943 Maps the rectangle \a rect, which is in this item's coordinate system, to
5944 the scene's coordinate system, and returns the mapped rectangle as a polygon.
5946 \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
5949 QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const
5951 if (d_ptr->hasTranslateOnlySceneTransform())
5952 return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
5953 return d_ptr->sceneTransform.map(rect);
5957 \fn QPolygonF QGraphicsItem::mapToScene(qreal x, qreal y, qreal w, qreal h) const
5960 This convenience function is equivalent to calling mapToScene(QRectF(\a x, \a y, \a w, \a h)).
5966 Maps the rectangle \a rect, which is in this item's coordinate system, to
5967 \a item's coordinate system, and returns the mapped rectangle as a new
5968 rectangle (i.e., the bounding rectangle of the resulting polygon).
5970 If \a item is 0, this function returns the same as mapRectToScene().
5972 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5973 Graphics View Coordinate System}
5975 QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, const QRectF &rect) const
5978 return itemTransform(item).mapRect(rect);
5979 return mapRectToScene(rect);
5983 \fn QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
5986 This convenience function is equivalent to calling mapRectToItem(item, QRectF(\a x, \a y, \a w, \a h)).
5992 Maps the rectangle \a rect, which is in this item's coordinate system, to
5993 its parent's coordinate system, and returns the mapped rectangle as a new
5994 rectangle (i.e., the bounding rectangle of the resulting polygon).
5996 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5997 Graphics View Coordinate System}
5999 QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const
6002 if (!d_ptr->transformData)
6003 return rect.translated(d_ptr->pos);
6004 return d_ptr->transformToParent().mapRect(rect);
6008 \fn QRectF QGraphicsItem::mapRectToParent(qreal x, qreal y, qreal w, qreal h) const
6011 This convenience function is equivalent to calling mapRectToParent(QRectF(\a x, \a y, \a w, \a h)).
6017 Maps the rectangle \a rect, which is in this item's coordinate system, to
6018 the scene coordinate system, and returns the mapped rectangle as a new
6019 rectangle (i.e., the bounding rectangle of the resulting polygon).
6021 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6022 Graphics View Coordinate System}
6024 QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const
6026 if (d_ptr->hasTranslateOnlySceneTransform())
6027 return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6028 return d_ptr->sceneTransform.mapRect(rect);
6032 \fn QRectF QGraphicsItem::mapRectToScene(qreal x, qreal y, qreal w, qreal h) const
6035 This convenience function is equivalent to calling mapRectToScene(QRectF(\a x, \a y, \a w, \a h)).
6041 Maps the rectangle \a rect, which is in \a item's coordinate system, to
6042 this item's coordinate system, and returns the mapped rectangle as a new
6043 rectangle (i.e., the bounding rectangle of the resulting polygon).
6045 If \a item is 0, this function returns the same as mapRectFromScene().
6047 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6048 Graphics View Coordinate System}
6050 QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, const QRectF &rect) const
6053 return item->itemTransform(this).mapRect(rect);
6054 return mapRectFromScene(rect);
6058 \fn QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
6061 This convenience function is equivalent to calling mapRectFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
6067 Maps the rectangle \a rect, which is in this item's parent's coordinate
6068 system, to this item's coordinate system, and returns the mapped rectangle
6069 as a new rectangle (i.e., the bounding rectangle of the resulting
6072 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6073 Graphics View Coordinate System}
6075 QRectF QGraphicsItem::mapRectFromParent(const QRectF &rect) const
6078 if (!d_ptr->transformData)
6079 return rect.translated(-d_ptr->pos);
6080 return d_ptr->transformToParent().inverted().mapRect(rect);
6084 \fn QRectF QGraphicsItem::mapRectFromParent(qreal x, qreal y, qreal w, qreal h) const
6087 This convenience function is equivalent to calling mapRectFromParent(QRectF(\a x, \a y, \a w, \a h)).
6093 Maps the rectangle \a rect, which is in scene coordinates, to this item's
6094 coordinate system, and returns the mapped rectangle as a new rectangle
6095 (i.e., the bounding rectangle of the resulting polygon).
6097 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6098 Graphics View Coordinate System}
6100 QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const
6102 if (d_ptr->hasTranslateOnlySceneTransform())
6103 return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6104 return d_ptr->sceneTransform.inverted().mapRect(rect);
6108 \fn QRectF QGraphicsItem::mapRectFromScene(qreal x, qreal y, qreal w, qreal h) const
6111 This convenience function is equivalent to calling mapRectFromScene(QRectF(\a x, \a y, \a w, \a h)).
6115 Maps the polygon \a polygon, which is in this item's coordinate system, to
6116 \a item's coordinate system, and returns the mapped polygon.
6118 If \a item is 0, this function returns the same as mapToScene().
6120 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6121 Graphics View Coordinate System}
6123 QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &polygon) const
6126 return itemTransform(item).map(polygon);
6127 return mapToScene(polygon);
6131 Maps the polygon \a polygon, which is in this item's coordinate system, to
6132 its parent's coordinate system, and returns the mapped polygon. If the
6133 item has no parent, \a polygon will be mapped to the scene's coordinate
6136 \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
6139 QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
6142 if (!d_ptr->transformData)
6143 return polygon.translated(d_ptr->pos);
6144 return d_ptr->transformToParent().map(polygon);
6148 Maps the polygon \a polygon, which is in this item's coordinate system, to
6149 the scene's coordinate system, and returns the mapped polygon.
6151 \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
6154 QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const
6156 if (d_ptr->hasTranslateOnlySceneTransform())
6157 return polygon.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6158 return d_ptr->sceneTransform.map(polygon);
6162 Maps the path \a path, which is in this item's coordinate system, to
6163 \a item's coordinate system, and returns the mapped path.
6165 If \a item is 0, this function returns the same as mapToScene().
6167 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6168 Graphics View Coordinate System}
6170 QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterPath &path) const
6173 return itemTransform(item).map(path);
6174 return mapToScene(path);
6178 Maps the path \a path, which is in this item's coordinate system, to
6179 its parent's coordinate system, and returns the mapped path. If the
6180 item has no parent, \a path will be mapped to the scene's coordinate
6183 \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
6186 QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
6189 if (!d_ptr->transformData)
6190 return path.translated(d_ptr->pos);
6191 return d_ptr->transformToParent().map(path);
6195 Maps the path \a path, which is in this item's coordinate system, to
6196 the scene's coordinate system, and returns the mapped path.
6198 \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
6201 QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const
6203 if (d_ptr->hasTranslateOnlySceneTransform())
6204 return path.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6205 return d_ptr->sceneTransform.map(path);
6209 Maps the point \a point, which is in \a item's coordinate system, to this
6210 item's coordinate system, and returns the mapped coordinate.
6212 If \a item is 0, this function returns the same as mapFromScene().
6214 \sa itemTransform(), mapFromParent(), mapFromScene(), transform(), mapToItem(), {The Graphics
6215 View Coordinate System}
6217 QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &point) const
6220 return item->itemTransform(this).map(point);
6221 return mapFromScene(point);
6225 \fn QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y) const
6228 This convenience function is equivalent to calling mapFromItem(\a item,
6229 QPointF(\a x, \a y)).
6233 Maps the point \a point, which is in this item's parent's coordinate
6234 system, to this item's coordinate system, and returns the mapped
6237 \sa mapFromItem(), mapFromScene(), transform(), mapToParent(), {The Graphics
6238 View Coordinate System}
6240 QPointF QGraphicsItem::mapFromParent(const QPointF &point) const
6243 if (d_ptr->transformData)
6244 return d_ptr->transformToParent().inverted().map(point);
6245 return point - d_ptr->pos;
6249 \fn QPointF QGraphicsItem::mapFromParent(qreal x, qreal y) const
6252 This convenience function is equivalent to calling
6253 mapFromParent(QPointF(\a x, \a y)).
6257 Maps the point \a point, which is in this item's scene's coordinate
6258 system, to this item's coordinate system, and returns the mapped
6261 \sa mapFromItem(), mapFromParent(), transform(), mapToScene(), {The Graphics
6262 View Coordinate System}
6264 QPointF QGraphicsItem::mapFromScene(const QPointF &point) const
6266 if (d_ptr->hasTranslateOnlySceneTransform())
6267 return QPointF(point.x() - d_ptr->sceneTransform.dx(), point.y() - d_ptr->sceneTransform.dy());
6268 return d_ptr->sceneTransform.inverted().map(point);
6272 \fn QPointF QGraphicsItem::mapFromScene(qreal x, qreal y) const
6275 This convenience function is equivalent to calling mapFromScene(QPointF(\a
6280 Maps the rectangle \a rect, which is in \a item's coordinate system, to
6281 this item's coordinate system, and returns the mapped rectangle as a
6284 If \a item is 0, this function returns the same as mapFromScene()
6286 \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The Graphics View Coordinate
6289 QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QRectF &rect) const
6292 return item->itemTransform(this).map(rect);
6293 return mapFromScene(rect);
6297 \fn QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
6300 This convenience function is equivalent to calling mapFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
6304 Maps the rectangle \a rect, which is in this item's parent's coordinate
6305 system, to this item's coordinate system, and returns the mapped rectangle
6308 \sa mapToParent(), mapFromItem(), transform(), {The Graphics View Coordinate
6311 QPolygonF QGraphicsItem::mapFromParent(const QRectF &rect) const
6314 if (!d_ptr->transformData)
6315 return rect.translated(-d_ptr->pos);
6316 return d_ptr->transformToParent().inverted().map(rect);
6320 \fn QPolygonF QGraphicsItem::mapFromParent(qreal x, qreal y, qreal w, qreal h) const
6323 This convenience function is equivalent to calling mapFromItem(QRectF(\a x, \a y, \a w, \a h)).
6327 Maps the rectangle \a rect, which is in this item's scene's coordinate
6328 system, to this item's coordinate system, and returns the mapped rectangle
6331 \sa mapToScene(), mapFromItem(), transform(), {The Graphics View Coordinate
6334 QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const
6336 if (d_ptr->hasTranslateOnlySceneTransform())
6337 return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6338 return d_ptr->sceneTransform.inverted().map(rect);
6342 \fn QPolygonF QGraphicsItem::mapFromScene(qreal x, qreal y, qreal w, qreal h) const
6345 This convenience function is equivalent to calling mapFromScene(QRectF(\a x, \a y, \a w, \a h)).
6349 Maps the polygon \a polygon, which is in \a item's coordinate system, to
6350 this item's coordinate system, and returns the mapped polygon.
6352 If \a item is 0, this function returns the same as mapFromScene().
6354 \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The
6355 Graphics View Coordinate System}
6357 QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPolygonF &polygon) const
6360 return item->itemTransform(this).map(polygon);
6361 return mapFromScene(polygon);
6365 Maps the polygon \a polygon, which is in this item's parent's coordinate
6366 system, to this item's coordinate system, and returns the mapped polygon.
6368 \sa mapToParent(), mapToItem(), transform(), {The Graphics View Coordinate
6371 QPolygonF QGraphicsItem::mapFromParent(const QPolygonF &polygon) const
6374 if (!d_ptr->transformData)
6375 return polygon.translated(-d_ptr->pos);
6376 return d_ptr->transformToParent().inverted().map(polygon);
6380 Maps the polygon \a polygon, which is in this item's scene's coordinate
6381 system, to this item's coordinate system, and returns the mapped polygon.
6383 \sa mapToScene(), mapFromParent(), transform(), {The Graphics View Coordinate
6386 QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const
6388 if (d_ptr->hasTranslateOnlySceneTransform())
6389 return polygon.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6390 return d_ptr->sceneTransform.inverted().map(polygon);
6394 Maps the path \a path, which is in \a item's coordinate system, to
6395 this item's coordinate system, and returns the mapped path.
6397 If \a item is 0, this function returns the same as mapFromScene().
6399 \sa itemTransform(), mapFromParent(), mapFromScene(), mapToItem(), {The
6400 Graphics View Coordinate System}
6402 QPainterPath QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPainterPath &path) const
6405 return item->itemTransform(this).map(path);
6406 return mapFromScene(path);
6410 Maps the path \a path, which is in this item's parent's coordinate
6411 system, to this item's coordinate system, and returns the mapped path.
6413 \sa mapFromScene(), mapFromItem(), mapToParent(), {The Graphics View
6416 QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const
6419 if (!d_ptr->transformData)
6420 return path.translated(-d_ptr->pos);
6421 return d_ptr->transformToParent().inverted().map(path);
6425 Maps the path \a path, which is in this item's scene's coordinate
6426 system, to this item's coordinate system, and returns the mapped path.
6428 \sa mapFromParent(), mapFromItem(), mapToScene(), {The Graphics View
6431 QPainterPath QGraphicsItem::mapFromScene(const QPainterPath &path) const
6433 if (d_ptr->hasTranslateOnlySceneTransform())
6434 return path.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6435 return d_ptr->sceneTransform.inverted().map(path);
6439 Returns true if this item is an ancestor of \a child (i.e., if this item
6440 is \a child's parent, or one of \a child's parent's ancestors).
6444 bool QGraphicsItem::isAncestorOf(const QGraphicsItem *child) const
6446 if (!child || child == this)
6448 if (child->d_ptr->depth() < d_ptr->depth())
6450 const QGraphicsItem *ancestor = child;
6451 while ((ancestor = ancestor->d_ptr->parent)) {
6452 if (ancestor == this)
6461 Returns the closest common ancestor item of this item and \a other, or 0
6462 if either \a other is 0, or there is no common ancestor.
6466 QGraphicsItem *QGraphicsItem::commonAncestorItem(const QGraphicsItem *other) const
6471 return const_cast<QGraphicsItem *>(this);
6472 const QGraphicsItem *thisw = this;
6473 const QGraphicsItem *otherw = other;
6474 int thisDepth = d_ptr->depth();
6475 int otherDepth = other->d_ptr->depth();
6476 while (thisDepth > otherDepth) {
6477 thisw = thisw->d_ptr->parent;
6480 while (otherDepth > thisDepth) {
6481 otherw = otherw->d_ptr->parent;
6484 while (thisw && thisw != otherw) {
6485 thisw = thisw->d_ptr->parent;
6486 otherw = otherw->d_ptr->parent;
6488 return const_cast<QGraphicsItem *>(thisw);
6493 Returns true if this item is currently under the mouse cursor in one of
6494 the views; otherwise, false is returned.
6496 \sa QGraphicsScene::views(), QCursor::pos()
6498 bool QGraphicsItem::isUnderMouse() const
6500 Q_D(const QGraphicsItem);
6504 QPoint cursorPos = QCursor::pos();
6505 foreach (QGraphicsView *view, d->scene->views()) {
6506 if (contains(mapFromScene(view->mapToScene(view->mapFromGlobal(cursorPos)))))
6513 Returns this item's custom data for the key \a key as a QVariant.
6515 Custom item data is useful for storing arbitrary properties in any
6518 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 11
6520 Qt does not use this feature for storing data; it is provided solely
6521 for the convenience of the user.
6525 QVariant QGraphicsItem::data(int key) const
6527 QGraphicsItemCustomDataStore *store = qt_dataStore();
6528 if (!store->data.contains(this))
6530 return store->data.value(this).value(key);
6534 Sets this item's custom data for the key \a key to \a value.
6536 Custom item data is useful for storing arbitrary properties for any
6537 item. Qt does not use this feature for storing data; it is provided solely
6538 for the convenience of the user.
6542 void QGraphicsItem::setData(int key, const QVariant &value)
6544 qt_dataStore()->data[this][key] = value;
6548 \fn T qgraphicsitem_cast(QGraphicsItem *item)
6549 \relates QGraphicsItem
6552 Returns the given \a item cast to type T if \a item is of type T;
6553 otherwise, 0 is returned.
6555 \note To make this function work correctly with custom items, reimplement
6556 the \l{QGraphicsItem::}{type()} function for each custom QGraphicsItem
6559 \sa QGraphicsItem::type(), QGraphicsItem::UserType
6563 Returns the type of an item as an int. All standard graphicsitem classes
6564 are associated with a unique value; see QGraphicsItem::Type. This type
6565 information is used by qgraphicsitem_cast() to distinguish between types.
6567 The default implementation (in QGraphicsItem) returns UserType.
6569 To enable use of qgraphicsitem_cast() with a custom item, reimplement this
6570 function and declare a Type enum value equal to your custom item's type.
6571 Custom items must return a value larger than or equal to UserType (65536).
6575 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp QGraphicsItem type
6579 int QGraphicsItem::type() const
6581 return (int)UserType;
6585 Installs an event filter for this item on \a filterItem, causing
6586 all events for this item to first pass through \a filterItem's
6587 sceneEventFilter() function.
6589 To filter another item's events, install this item as an event filter
6590 for the other item. Example:
6592 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 12
6594 An item can only filter events for other items in the same
6595 scene. Also, an item cannot filter its own events; instead, you
6596 can reimplement sceneEvent() directly.
6598 Items must belong to a scene for scene event filters to be installed and
6601 \sa removeSceneEventFilter(), sceneEventFilter(), sceneEvent()
6603 void QGraphicsItem::installSceneEventFilter(QGraphicsItem *filterItem)
6605 if (!d_ptr->scene) {
6606 qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
6607 " on items in a scene.");
6610 if (d_ptr->scene != filterItem->scene()) {
6611 qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
6612 " on items in the same scene.");
6615 d_ptr->scene->d_func()->installSceneEventFilter(this, filterItem);
6619 Removes an event filter on this item from \a filterItem.
6621 \sa installSceneEventFilter()
6623 void QGraphicsItem::removeSceneEventFilter(QGraphicsItem *filterItem)
6625 if (!d_ptr->scene || d_ptr->scene != filterItem->scene())
6627 d_ptr->scene->d_func()->removeSceneEventFilter(this, filterItem);
6631 Filters events for the item \a watched. \a event is the filtered
6634 Reimplementing this function in a subclass makes it possible
6635 for the item to be used as an event filter for other items,
6636 intercepting all the events send to those items before they are
6639 Reimplementations must return true to prevent further processing of
6640 a given event, ensuring that it will not be delivered to the watched
6641 item, or return false to indicate that the event should be propagated
6642 further by the event system.
6644 \sa installSceneEventFilter()
6646 bool QGraphicsItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
6654 This virtual function receives events to this item. Reimplement
6655 this function to intercept events before they are dispatched to
6656 the specialized event handlers contextMenuEvent(), focusInEvent(),
6657 focusOutEvent(), hoverEnterEvent(), hoverMoveEvent(),
6658 hoverLeaveEvent(), keyPressEvent(), keyReleaseEvent(),
6659 mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent(), and
6660 mouseDoubleClickEvent().
6662 Returns true if the event was recognized and handled; otherwise, (e.g., if
6663 the event type was not recognized,) false is returned.
6665 \a event is the intercepted event.
6667 bool QGraphicsItem::sceneEvent(QEvent *event)
6669 if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents) {
6670 if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverLeave
6671 || event->type() == QEvent::DragEnter || event->type() == QEvent::DragLeave) {
6672 // Hover enter and hover leave events for children are ignored;
6673 // hover move events are forwarded.
6677 QGraphicsItem *handler = this;
6679 handler = handler->d_ptr->parent;
6681 } while (handler->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents);
6682 // Forward the event to the closest parent that handles child
6683 // events, mapping existing item-local coordinates to its
6684 // coordinate system.
6685 d_ptr->remapItemPos(event, handler);
6686 handler->sceneEvent(event);
6690 if (event->type() == QEvent::FocusOut) {
6691 focusOutEvent(static_cast<QFocusEvent *>(event));
6695 if (!d_ptr->visible) {
6700 switch (event->type()) {
6701 case QEvent::FocusIn:
6702 focusInEvent(static_cast<QFocusEvent *>(event));
6704 case QEvent::GraphicsSceneContextMenu:
6705 contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event));
6707 case QEvent::GraphicsSceneDragEnter:
6708 dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6710 case QEvent::GraphicsSceneDragMove:
6711 dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6713 case QEvent::GraphicsSceneDragLeave:
6714 dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6716 case QEvent::GraphicsSceneDrop:
6717 dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6719 case QEvent::GraphicsSceneHoverEnter:
6720 hoverEnterEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6722 case QEvent::GraphicsSceneHoverMove:
6723 hoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6725 case QEvent::GraphicsSceneHoverLeave:
6726 hoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6728 case QEvent::GraphicsSceneMouseMove:
6729 mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6731 case QEvent::GraphicsSceneMousePress:
6732 mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6734 case QEvent::GraphicsSceneMouseRelease:
6735 mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6737 case QEvent::GraphicsSceneMouseDoubleClick:
6738 mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6740 case QEvent::GraphicsSceneWheel:
6741 wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
6743 case QEvent::KeyPress: {
6744 QKeyEvent *k = static_cast<QKeyEvent *>(event);
6745 if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
6746 if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
6748 if (k->key() == Qt::Key_Backtab
6749 || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
6750 if (d_ptr->isWidget) {
6751 res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(false);
6752 } else if (d_ptr->scene) {
6753 res = d_ptr->scene->focusNextPrevChild(false);
6755 } else if (k->key() == Qt::Key_Tab) {
6756 if (d_ptr->isWidget) {
6757 res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(true);
6758 } else if (d_ptr->scene) {
6759 res = d_ptr->scene->focusNextPrevChild(true);
6767 keyPressEvent(static_cast<QKeyEvent *>(event));
6770 case QEvent::KeyRelease:
6771 keyReleaseEvent(static_cast<QKeyEvent *>(event));
6773 case QEvent::InputMethod:
6774 inputMethodEvent(static_cast<QInputMethodEvent *>(event));
6776 case QEvent::WindowActivate:
6777 case QEvent::WindowDeactivate:
6778 // Propagate panel activation.
6780 for (int i = 0; i < d_ptr->children.size(); ++i) {
6781 QGraphicsItem *child = d_ptr->children.at(i);
6782 if (child->isVisible() && !child->isPanel()) {
6783 if (!(child->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents))
6784 d_ptr->scene->sendEvent(child, event);
6797 This event handler can be reimplemented in a subclass to process context
6798 menu events. The \a event parameter contains details about the event to
6801 If you ignore the event, (i.e., by calling QEvent::ignore(),) \a event
6802 will propagate to any item beneath this item. If no items accept the
6803 event, it will be ignored by the scene, and propagate to the view.
6805 It's common to open a QMenu in response to receiving a context menu
6808 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 13
6810 The default implementation ignores the event.
6814 void QGraphicsItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
6820 This event handler, for event \a event, can be reimplemented to receive
6821 drag enter events for this item. Drag enter events are generated as the
6822 cursor enters the item's area.
6824 By accepting the event, (i.e., by calling QEvent::accept(),) the item will
6825 accept drop events, in addition to receiving drag move and drag
6826 leave. Otherwise, the event will be ignored and propagate to the item
6827 beneath. If the event is accepted, the item will receive a drag move event
6828 before control goes back to the event loop.
6830 A common implementation of dragEnterEvent accepts or ignores \a event
6831 depending on the associated mime data in \a event. Example:
6833 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 14
6835 Items do not receive drag and drop events by default; to enable this
6836 feature, call \c setAcceptDrops(true).
6838 The default implementation does nothing.
6840 \sa dropEvent(), dragMoveEvent(), dragLeaveEvent()
6842 void QGraphicsItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
6845 // binary compatibility workaround between 4.4 and 4.5
6846 if (d->isProxyWidget())
6847 static_cast<QGraphicsProxyWidget*>(this)->dragEnterEvent(event);
6851 This event handler, for event \a event, can be reimplemented to receive
6852 drag leave events for this item. Drag leave events are generated as the
6853 cursor leaves the item's area. Most often you will not need to reimplement
6854 this function, but it can be useful for resetting state in your item
6855 (e.g., highlighting).
6857 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6859 Items do not receive drag and drop events by default; to enable this
6860 feature, call \c setAcceptDrops(true).
6862 The default implementation does nothing.
6864 \sa dragEnterEvent(), dropEvent(), dragMoveEvent()
6866 void QGraphicsItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
6869 // binary compatibility workaround between 4.4 and 4.5
6870 if (d->isProxyWidget())
6871 static_cast<QGraphicsProxyWidget*>(this)->dragLeaveEvent(event);
6875 This event handler, for event \a event, can be reimplemented to receive
6876 drag move events for this item. Drag move events are generated as the
6877 cursor moves around inside the item's area. Most often you will not need
6878 to reimplement this function; it is used to indicate that only parts of
6879 the item can accept drops.
6881 Calling QEvent::ignore() or QEvent::accept() on \a event toggles whether
6882 or not the item will accept drops at the position from the event. By
6883 default, \a event is accepted, indicating that the item allows drops at
6884 the specified position.
6886 Items do not receive drag and drop events by default; to enable this
6887 feature, call \c setAcceptDrops(true).
6889 The default implementation does nothing.
6891 \sa dropEvent(), dragEnterEvent(), dragLeaveEvent()
6893 void QGraphicsItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
6896 // binary compatibility workaround between 4.4 and 4.5
6897 if (d->isProxyWidget())
6898 static_cast<QGraphicsProxyWidget*>(this)->dragMoveEvent(event);
6902 This event handler, for event \a event, can be reimplemented to receive
6903 drop events for this item. Items can only receive drop events if the last
6904 drag move event was accepted.
6906 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6908 Items do not receive drag and drop events by default; to enable this
6909 feature, call \c setAcceptDrops(true).
6911 The default implementation does nothing.
6913 \sa dragEnterEvent(), dragMoveEvent(), dragLeaveEvent()
6915 void QGraphicsItem::dropEvent(QGraphicsSceneDragDropEvent *event)
6918 // binary compatibility workaround between 4.4 and 4.5
6919 if (d->isProxyWidget())
6920 static_cast<QGraphicsProxyWidget*>(this)->dropEvent(event);
6924 This event handler, for event \a event, can be reimplemented to receive
6925 focus in events for this item. The default implementation calls
6928 \sa focusOutEvent(), sceneEvent(), setFocus()
6930 void QGraphicsItem::focusInEvent(QFocusEvent *event)
6937 This event handler, for event \a event, can be reimplemented to receive
6938 focus out events for this item. The default implementation does nothing.
6940 \sa focusInEvent(), sceneEvent(), setFocus()
6942 void QGraphicsItem::focusOutEvent(QFocusEvent *event)
6949 This event handler, for event \a event, can be reimplemented to receive
6950 hover enter events for this item. The default implementation calls
6951 update(); otherwise it does nothing.
6953 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6955 \sa hoverMoveEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
6957 void QGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
6964 This event handler, for event \a event, can be reimplemented to receive
6965 hover move events for this item. The default implementation does nothing.
6967 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6969 \sa hoverEnterEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
6971 void QGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
6977 This event handler, for event \a event, can be reimplemented to receive
6978 hover leave events for this item. The default implementation calls
6979 update(); otherwise it does nothing.
6981 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6983 \sa hoverEnterEvent(), hoverMoveEvent(), sceneEvent(), setAcceptHoverEvents()
6985 void QGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
6992 This event handler, for event \a event, can be reimplemented to
6993 receive key press events for this item. The default implementation
6994 ignores the event. If you reimplement this handler, the event will by
6995 default be accepted.
6997 Note that key events are only received for items that set the
6998 ItemIsFocusable flag, and that have keyboard input focus.
7000 \sa keyReleaseEvent(), setFocus(), QGraphicsScene::setFocusItem(),
7003 void QGraphicsItem::keyPressEvent(QKeyEvent *event)
7009 This event handler, for event \a event, can be reimplemented to receive
7010 key release events for this item. The default implementation
7011 ignores the event. If you reimplement this handler, the event will by
7012 default be accepted.
7014 Note that key events are only received for items that set the
7015 ItemIsFocusable flag, and that have keyboard input focus.
7017 \sa keyPressEvent(), setFocus(), QGraphicsScene::setFocusItem(),
7020 void QGraphicsItem::keyReleaseEvent(QKeyEvent *event)
7026 This event handler, for event \a event, can be reimplemented to
7027 receive mouse press events for this item. Mouse press events are
7028 only delivered to items that accept the mouse button that is
7029 pressed. By default, an item accepts all mouse buttons, but you
7030 can change this by calling setAcceptedMouseButtons().
7032 The mouse press event decides which item should become the mouse
7033 grabber (see QGraphicsScene::mouseGrabberItem()). If you do not
7034 reimplement this function, the press event will propagate to any
7035 topmost item beneath this item, and no other mouse events will be
7036 delivered to this item.
7038 If you do reimplement this function, \a event will by default be
7039 accepted (see QEvent::accept()), and this item is then the mouse
7040 grabber. This allows the item to receive future move, release and
7041 doubleclick events. If you call QEvent::ignore() on \a event, this
7042 item will lose the mouse grab, and \a event will propagate to any
7043 topmost item beneath. No further mouse events will be delivered to
7044 this item unless a new mouse press event is received.
7046 The default implementation handles basic item interaction, such as
7047 selection and moving. If you want to keep the base implementation
7048 when reimplementing this function, call
7049 QGraphicsItem::mousePressEvent() in your reimplementation.
7051 The event is \l{QEvent::ignore()}d for items that are neither
7052 \l{QGraphicsItem::ItemIsMovable}{movable} nor
7053 \l{QGraphicsItem::ItemIsSelectable}{selectable}.
7055 \sa mouseMoveEvent(), mouseReleaseEvent(),
7056 mouseDoubleClickEvent(), sceneEvent()
7058 void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
7060 if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
7061 bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
7063 if (!d_ptr->selected) {
7064 if (QGraphicsScene *scene = d_ptr->scene) {
7065 ++scene->d_func()->selectionChanging;
7066 scene->clearSelection();
7067 --scene->d_func()->selectionChanging;
7072 } else if (!(flags() & ItemIsMovable)) {
7075 if (d_ptr->isWidget) {
7076 // Qt::Popup closes when you click outside.
7077 QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
7078 if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
7080 if (!w->rect().contains(event->pos()))
7089 bool _qt_movableAncestorIsSelected(const QGraphicsItem *item)
7091 const QGraphicsItem *parent = item->parentItem();
7092 return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
7095 bool QGraphicsItemPrivate::movableAncestorIsSelected(const QGraphicsItem *item)
7097 const QGraphicsItem *parent = item->d_ptr->parent;
7098 return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
7102 This event handler, for event \a event, can be reimplemented to
7103 receive mouse move events for this item. If you do receive this
7104 event, you can be certain that this item also received a mouse
7105 press event, and that this item is the current mouse grabber.
7107 Calling QEvent::ignore() or QEvent::accept() on \a event has no
7110 The default implementation handles basic item interaction, such as
7111 selection and moving. If you want to keep the base implementation
7112 when reimplementing this function, call
7113 QGraphicsItem::mouseMoveEvent() in your reimplementation.
7115 Please note that mousePressEvent() decides which graphics item it
7116 is that receives mouse events. See the mousePressEvent()
7117 description for details.
7119 \sa mousePressEvent(), mouseReleaseEvent(),
7120 mouseDoubleClickEvent(), sceneEvent()
7122 void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
7124 if ((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) {
7125 // Determine the list of items that need to be moved.
7126 QList<QGraphicsItem *> selectedItems;
7127 QHash<QGraphicsItem *, QPointF> initialPositions;
7129 selectedItems = d_ptr->scene->selectedItems();
7130 initialPositions = d_ptr->scene->d_func()->movingItemsInitialPositions;
7131 if (initialPositions.isEmpty()) {
7132 foreach (QGraphicsItem *item, selectedItems)
7133 initialPositions[item] = item->pos();
7134 initialPositions[this] = pos();
7136 d_ptr->scene->d_func()->movingItemsInitialPositions = initialPositions;
7139 // Find the active view.
7140 QGraphicsView *view = 0;
7141 if (event->widget())
7142 view = qobject_cast<QGraphicsView *>(event->widget()->parentWidget());
7144 // Move all selected items
7146 bool movedMe = false;
7147 while (i <= selectedItems.size()) {
7148 QGraphicsItem *item = 0;
7149 if (i < selectedItems.size())
7150 item = selectedItems.at(i);
7154 // Slightly clumsy-looking way to ensure that "this" is part
7155 // of the list of items to move, this is to avoid allocations
7156 // (appending this item to the list of selected items causes a
7163 if ((item->flags() & ItemIsMovable) && !QGraphicsItemPrivate::movableAncestorIsSelected(item)) {
7164 QPointF currentParentPos;
7165 QPointF buttonDownParentPos;
7166 if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorIgnoresTransformations) {
7167 // Items whose ancestors ignore transformations need to
7168 // map screen coordinates to local coordinates, then map
7169 // those to the parent.
7170 QTransform viewToItemTransform = (item->deviceTransform(view->viewportTransform())).inverted();
7171 currentParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))));
7172 buttonDownParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))));
7173 } else if (item->flags() & ItemIgnoresTransformations) {
7174 // Root items that ignore transformations need to
7175 // calculate their diff by mapping viewport coordinates
7176 // directly to parent coordinates.
7178 QTransform itemTransform;
7179 if (item->d_ptr->transformData)
7180 itemTransform = item->d_ptr->transformData->computedFullTransform();
7181 itemTransform.translate(item->d_ptr->pos.x(), item->d_ptr->pos.y());
7182 QTransform viewToParentTransform = itemTransform
7183 * (item->sceneTransform() * view->viewportTransform()).inverted();
7184 currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos())));
7185 buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton))));
7187 // All other items simply map from the scene.
7188 currentParentPos = item->mapToParent(item->mapFromScene(event->scenePos()));
7189 buttonDownParentPos = item->mapToParent(item->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)));
7192 item->setPos(initialPositions.value(item) + currentParentPos - buttonDownParentPos);
7194 if (item->flags() & ItemIsSelectable)
7195 item->setSelected(true);
7206 This event handler, for event \a event, can be reimplemented to
7207 receive mouse release events for this item.
7209 Calling QEvent::ignore() or QEvent::accept() on \a event has no
7212 The default implementation handles basic item interaction, such as
7213 selection and moving. If you want to keep the base implementation
7214 when reimplementing this function, call
7215 QGraphicsItem::mouseReleaseEvent() in your reimplementation.
7217 Please note that mousePressEvent() decides which graphics item it
7218 is that receives mouse events. See the mousePressEvent()
7219 description for details.
7221 \sa mousePressEvent(), mouseMoveEvent(), mouseDoubleClickEvent(),
7224 void QGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
7226 if (flags() & ItemIsSelectable) {
7227 bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
7228 if (event->scenePos() == event->buttonDownScenePos(Qt::LeftButton)) {
7229 // The item didn't move
7231 setSelected(!isSelected());
7233 bool selectionChanged = false;
7234 if (QGraphicsScene *scene = d_ptr->scene) {
7235 ++scene->d_func()->selectionChanging;
7236 // Clear everything but this item. Bypass
7237 // QGraphicsScene::clearSelection()'s default behavior by
7238 // temporarily removing this item from the selection list.
7239 if (d_ptr->selected) {
7240 scene->d_func()->selectedItems.remove(this);
7241 foreach (QGraphicsItem *item, scene->d_func()->selectedItems) {
7242 if (item->isSelected()) {
7243 selectionChanged = true;
7248 scene->clearSelection();
7249 if (d_ptr->selected)
7250 scene->d_func()->selectedItems.insert(this);
7251 --scene->d_func()->selectionChanging;
7252 if (selectionChanged)
7253 emit d_ptr->scene->selectionChanged();
7259 if (d_ptr->scene && !event->buttons())
7260 d_ptr->scene->d_func()->movingItemsInitialPositions.clear();
7264 This event handler, for event \a event, can be reimplemented to
7265 receive mouse doubleclick events for this item.
7267 When doubleclicking an item, the item will first receive a mouse
7268 press event, followed by a release event (i.e., a click), then a
7269 doubleclick event, and finally a release event.
7271 Calling QEvent::ignore() or QEvent::accept() on \a event has no
7274 The default implementation calls mousePressEvent(). If you want to
7275 keep the base implementation when reimplementing this function,
7276 call QGraphicsItem::mouseDoubleClickEvent() in your
7279 Note that an item will not receive double click events if it is
7280 neither \l {QGraphicsItem::ItemIsSelectable}{selectable} nor
7281 \l{QGraphicsItem::ItemIsMovable}{movable} (single mouse clicks are
7282 ignored in this case, and that stops the generation of double
7285 \sa mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), sceneEvent()
7287 void QGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
7289 mousePressEvent(event);
7293 This event handler, for event \a event, can be reimplemented to receive
7294 wheel events for this item. If you reimplement this function, \a event
7295 will be accepted by default.
7297 If you ignore the event, (i.e., by calling QEvent::ignore(),) it will
7298 propagate to any item beneath this item. If no items accept the event, it
7299 will be ignored by the scene, and propagate to the view (e.g., the view's
7300 vertical scroll bar).
7302 The default implementation ignores the event.
7306 void QGraphicsItem::wheelEvent(QGraphicsSceneWheelEvent *event)
7312 This event handler, for event \a event, can be reimplemented to receive
7313 input method events for this item. The default implementation ignores the
7316 \sa inputMethodQuery(), sceneEvent()
7318 void QGraphicsItem::inputMethodEvent(QInputMethodEvent *event)
7324 This method is only relevant for input items. It is used by the
7325 input method to query a set of properties of the item to be able
7326 to support complex input method operations, such as support for
7327 surrounding text and reconversions. \a query specifies which
7328 property is queried.
7330 \sa inputMethodEvent(), QInputMethodEvent
7332 QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const
7335 // ### Qt 5: Remove. The reimplementation in
7336 // QGraphicsProxyWidget solves this problem (but requires a
7337 // recompile to take effect).
7338 return d_ptr->inputMethodQueryHelper(query);
7346 Returns the current input method hints of this item.
7348 Input method hints are only relevant for input items.
7349 The hints are used by the input method to indicate how it should operate.
7350 For example, if the Qt::ImhNumbersOnly flag is set, the input method may change
7351 its visual components to reflect that only numbers can be entered.
7353 The effect may vary between input method implementations.
7357 \sa setInputMethodHints(), inputMethodQuery()
7359 Qt::InputMethodHints QGraphicsItem::inputMethodHints() const
7361 Q_D(const QGraphicsItem);
7366 Sets the current input method hints of this item to \a hints.
7370 \sa inputMethodHints(), inputMethodQuery()
7372 void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
7378 d->scene->d_func()->updateInputMethodSensitivityInViews();
7379 QWidget *fw = QApplication::focusWidget();
7382 qApp->inputMethod()->update(Qt::ImHints);
7386 Updates the item's micro focus.
7392 void QGraphicsItem::updateMicroFocus()
7394 #if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS))
7395 if (QWidget *fw = QApplication::focusWidget()) {
7397 for (int i = 0 ; i < scene()->views().count() ; ++i) {
7398 if (scene()->views().at(i) == fw) {
7400 qApp->inputMethod()->update(Qt::ImQueryAll);
7402 #ifndef QT_NO_ACCESSIBILITY
7403 // ##### is this correct
7404 if (toGraphicsObject())
7405 QAccessible::updateAccessibility(toGraphicsObject(), 0, QAccessible::StateChanged);
7417 This virtual function is called by QGraphicsItem to notify custom items
7418 that some part of the item's state changes. By reimplementing this
7419 function, your can react to a change, and in some cases, (depending on \a
7420 change,) adjustments can be made.
7422 \a change is the parameter of the item that is changing. \a value is the
7423 new value; the type of the value depends on \a change.
7427 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 15
7429 The default implementation does nothing, and returns \a value.
7431 Note: Certain QGraphicsItem functions cannot be called in a
7432 reimplementation of this function; see the GraphicsItemChange
7433 documentation for details.
7435 \sa GraphicsItemChange
7437 QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value)
7446 Note: This is provided as a hook to avoid future problems related
7447 to adding virtual functions.
7449 bool QGraphicsItem::supportsExtension(Extension extension) const
7451 Q_UNUSED(extension);
7458 Note: This is provided as a hook to avoid future problems related
7459 to adding virtual functions.
7461 void QGraphicsItem::setExtension(Extension extension, const QVariant &variant)
7463 Q_UNUSED(extension);
7470 Note: This is provided as a hook to avoid future problems related
7471 to adding virtual functions.
7473 QVariant QGraphicsItem::extension(const QVariant &variant) const
7482 Adds this item to the scene's index. Called in conjunction with
7483 removeFromIndex() to ensure the index bookkeeping is correct when
7484 the item's position, transformation or shape changes.
7486 void QGraphicsItem::addToIndex()
7488 if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
7489 // ### add to child index only if applicable
7493 d_ptr->scene->d_func()->index->addItem(this);
7499 Removes this item from the scene's index. Called in conjunction
7500 with addToIndex() to ensure the index bookkeeping is correct when
7501 the item's position, transformation or shape changes.
7503 void QGraphicsItem::removeFromIndex()
7505 if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
7506 // ### remove from child index only if applicable
7510 d_ptr->scene->d_func()->index->removeItem(this);
7514 Prepares the item for a geometry change. Call this function before
7515 changing the bounding rect of an item to keep QGraphicsScene's index up to
7518 prepareGeometryChange() will call update() if this is necessary.
7522 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 16
7526 void QGraphicsItem::prepareGeometryChange()
7528 if (d_ptr->inDestructor)
7531 d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true;
7532 d_ptr->geometryChanged = 1;
7533 d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
7534 d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper;
7536 QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
7537 scenePrivate->index->prepareBoundingRectChange(this);
7538 scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false,
7539 /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false,
7540 /*updateBoundingRect=*/true);
7542 // For compatibility reasons, we have to update the item's old geometry
7543 // if someone is connected to the changed signal or the scene has no views.
7544 // Note that this has to be done *after* markDirty to ensure that
7545 // _q_processDirtyItems is called before _q_emitUpdated.
7546 if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
7547 || scenePrivate->views.isEmpty()) {
7548 if (d_ptr->hasTranslateOnlySceneTransform()) {
7549 d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
7550 d_ptr->sceneTransform.dy()));
7552 d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect()));
7557 d_ptr->markParentDirty(/*updateBoundingRect=*/true);
7563 Highlights \a item as selected.
7565 NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in
7566 qgraphicssvgitem.cpp!
7568 static void qt_graphicsItem_highlightSelected(
7569 QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option)
7571 const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1));
7572 if (qFuzzyIsNull(qMax(murect.width(), murect.height())))
7575 const QRectF mbrect = painter->transform().mapRect(item->boundingRect());
7576 if (qMin(mbrect.width(), mbrect.height()) < qreal(1.0))
7580 switch (item->type()) {
7581 case QGraphicsEllipseItem::Type:
7582 itemPenWidth = static_cast<QGraphicsEllipseItem *>(item)->pen().widthF();
7584 case QGraphicsPathItem::Type:
7585 itemPenWidth = static_cast<QGraphicsPathItem *>(item)->pen().widthF();
7587 case QGraphicsPolygonItem::Type:
7588 itemPenWidth = static_cast<QGraphicsPolygonItem *>(item)->pen().widthF();
7590 case QGraphicsRectItem::Type:
7591 itemPenWidth = static_cast<QGraphicsRectItem *>(item)->pen().widthF();
7593 case QGraphicsSimpleTextItem::Type:
7594 itemPenWidth = static_cast<QGraphicsSimpleTextItem *>(item)->pen().widthF();
7596 case QGraphicsLineItem::Type:
7597 itemPenWidth = static_cast<QGraphicsLineItem *>(item)->pen().widthF();
7602 const qreal pad = itemPenWidth / 2;
7604 const qreal penWidth = 0; // cosmetic pen
7606 const QColor fgcolor = option->palette.windowText().color();
7607 const QColor bgcolor( // ensure good contrast against fgcolor
7608 fgcolor.red() > 127 ? 0 : 255,
7609 fgcolor.green() > 127 ? 0 : 255,
7610 fgcolor.blue() > 127 ? 0 : 255);
7612 painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
7613 painter->setBrush(Qt::NoBrush);
7614 painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
7616 painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
7617 painter->setBrush(Qt::NoBrush);
7618 painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
7622 \class QGraphicsObject
7623 \brief The QGraphicsObject class provides a base class for all graphics items that
7624 require signals, slots and properties.
7626 \ingroup graphicsview-api
7629 The class extends a QGraphicsItem with QObject's signal/slot and property mechanisms.
7630 It maps many of QGraphicsItem's basic setters and getters to properties and adds notification
7631 signals for many of them.
7633 \section1 Parents and Children
7635 Each graphics object can be constructed with a parent item. This ensures that the
7636 item will be destroyed when its parent item is destroyed. Although QGraphicsObject
7637 inherits from both QObject and QGraphicsItem, you should use the functions provided
7638 by QGraphicsItem, \e not QObject, to manage the relationships between parent and
7641 The relationships between items can be explored using the parentItem() and childItems()
7642 functions. In the hierarchy of items in a scene, the parentObject() and parentWidget()
7643 functions are the equivalent of the QWidget::parent() and QWidget::parentWidget()
7644 functions for QWidget subclasses.
7650 Constructs a QGraphicsObject with \a parent.
7652 QGraphicsObject::QGraphicsObject(QGraphicsItem *parent)
7653 : QGraphicsItem(parent)
7655 QGraphicsItem::d_ptr->isObject = true;
7661 QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene)
7662 : QGraphicsItem(dd, parent, scene)
7664 QGraphicsItem::d_ptr->isObject = true;
7667 #ifndef QT_NO_GESTURES
7669 Subscribes the graphics object to the given \a gesture with specific \a flags.
7671 \sa ungrabGesture(), QGestureEvent
7673 void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
7675 bool contains = QGraphicsItem::d_ptr->gestureContext.contains(gesture);
7676 QGraphicsItem::d_ptr->gestureContext.insert(gesture, flags);
7677 if (!contains && QGraphicsItem::d_ptr->scene)
7678 QGraphicsItem::d_ptr->scene->d_func()->grabGesture(this, gesture);
7682 Unsubscribes the graphics object from the given \a gesture.
7684 \sa grabGesture(), QGestureEvent
7686 void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
7688 if (QGraphicsItem::d_ptr->gestureContext.remove(gesture) && QGraphicsItem::d_ptr->scene)
7689 QGraphicsItem::d_ptr->scene->d_func()->ungrabGesture(this, gesture);
7691 #endif // QT_NO_GESTURES
7694 Updates the item's micro focus. This is slot for convenience.
7700 void QGraphicsObject::updateMicroFocus()
7702 QGraphicsItem::updateMicroFocus();
7705 void QGraphicsItemPrivate::children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item)
7708 QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(list->object);
7709 if (QGraphicsItemPrivate::get(graphicsObject)->sendParentChangeNotification) {
7710 item->setParentItem(graphicsObject);
7712 QGraphicsItemPrivate::get(item)->setParentItemHelper(graphicsObject, 0, 0);
7717 int QGraphicsItemPrivate::children_count(QDeclarativeListProperty<QGraphicsObject> *list)
7719 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7720 return d->children.count();
7723 QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGraphicsObject> *list, int index)
7725 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7726 if (index >= 0 && index < d->children.count())
7727 return d->children.at(index)->toGraphicsObject();
7732 void QGraphicsItemPrivate::children_clear(QDeclarativeListProperty<QGraphicsObject> *list)
7734 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7735 int childCount = d->children.count();
7736 if (d->sendParentChangeNotification) {
7737 for (int index = 0; index < childCount; index++)
7738 d->children.at(0)->setParentItem(0);
7740 for (int index = 0; index < childCount; index++)
7741 QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, 0, 0);
7746 Returns a list of this item's children.
7748 The items are sorted by stacking order. This takes into account both the
7749 items' insertion order and their Z-values.
7752 QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList()
7756 QGraphicsObject *that = static_cast<QGraphicsObject *>(q);
7757 return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append,
7758 children_count, children_at, children_clear);
7760 //QGraphicsItem is not supported for this property
7761 return QDeclarativeListProperty<QGraphicsObject>();
7767 Returns the width of the item
7768 Reimplemented by QGraphicsWidget
7770 qreal QGraphicsItemPrivate::width() const
7777 Set the width of the item
7778 Reimplemented by QGraphicsWidget
7780 void QGraphicsItemPrivate::setWidth(qreal w)
7787 Reset the width of the item
7788 Reimplemented by QGraphicsWidget
7790 void QGraphicsItemPrivate::resetWidth()
7796 Returns the height of the item
7797 Reimplemented by QGraphicsWidget
7799 qreal QGraphicsItemPrivate::height() const
7806 Set the height of the item
7807 Reimplemented by QGraphicsWidget
7809 void QGraphicsItemPrivate::setHeight(qreal h)
7816 Reset the height of the item
7817 Reimplemented by QGraphicsWidget
7819 void QGraphicsItemPrivate::resetHeight()
7824 \property QGraphicsObject::children
7830 \property QGraphicsObject::width
7836 \property QGraphicsObject::height
7842 \property QGraphicsObject::parent
7843 \brief the parent of the item
7845 \note The item's parent is set independently of the parent object returned
7846 by QObject::parent().
7848 \sa QGraphicsItem::setParentItem(), QGraphicsItem::parentObject()
7852 \property QGraphicsObject::opacity
7853 \brief the opacity of the item
7855 \sa QGraphicsItem::setOpacity(), QGraphicsItem::opacity()
7859 \fn QGraphicsObject::opacityChanged()
7861 This signal gets emitted whenever the opacity of the item changes
7863 \sa QGraphicsItem::opacity()
7867 \fn QGraphicsObject::parentChanged()
7869 This signal gets emitted whenever the parent of the item changes
7873 \property QGraphicsObject::pos
7874 \brief the position of the item
7876 Describes the items position.
7878 \sa QGraphicsItem::setPos(), QGraphicsItem::pos()
7882 \property QGraphicsObject::x
7883 \brief the x position of the item
7885 Describes the items x position.
7887 \sa QGraphicsItem::setX(), setPos(), xChanged()
7891 \fn QGraphicsObject::xChanged()
7893 This signal gets emitted whenever the x position of the item changes
7899 \property QGraphicsObject::y
7900 \brief the y position of the item
7902 Describes the items y position.
7904 \sa QGraphicsItem::setY(), setPos(), yChanged()
7908 \fn QGraphicsObject::yChanged()
7910 This signal gets emitted whenever the y position of the item changes.
7916 \property QGraphicsObject::z
7917 \brief the z value of the item
7919 Describes the items z value.
7921 \sa QGraphicsItem::setZValue(), zValue(), zChanged()
7925 \fn QGraphicsObject::zChanged()
7927 This signal gets emitted whenever the z value of the item changes.
7933 \property QGraphicsObject::rotation
7934 This property holds the rotation of the item in degrees.
7936 This specifies how many degrees to rotate the item around its transformOrigin.
7937 The default rotation is 0 degrees (i.e. not rotated at all).
7941 \fn QGraphicsObject::rotationChanged()
7943 This signal gets emitted whenever the roation of the item changes.
7947 \property QGraphicsObject::scale
7948 This property holds the scale of the item.
7950 A scale of less than 1 means the item will be displayed smaller than
7951 normal, and a scale of greater than 1 means the item will be
7952 displayed larger than normal. A negative scale means the item will
7955 By default, items are displayed at a scale of 1 (i.e. at their
7958 Scaling is from the item's transformOrigin.
7962 \fn void QGraphicsObject::scaleChanged()
7964 This signal is emitted when the scale of the item changes.
7969 \property QGraphicsObject::enabled
7970 \brief whether the item is enabled or not
7972 This property is declared in QGraphicsItem.
7974 By default, this property is true.
7976 \sa QGraphicsItem::isEnabled(), QGraphicsItem::setEnabled()
7977 \sa QGraphicsObject::enabledChanged()
7981 \fn void QGraphicsObject::enabledChanged()
7983 This signal gets emitted whenever the item get's enabled or disabled.
7989 \property QGraphicsObject::visible
7990 \brief whether the item is visible or not
7992 This property is declared in QGraphicsItem.
7994 By default, this property is true.
7996 \sa QGraphicsItem::isVisible(), QGraphicsItem::setVisible(), visibleChanged()
8000 \fn QGraphicsObject::visibleChanged()
8002 This signal gets emitted whenever the visibility of the item changes
8008 \fn const QObjectList &QGraphicsObject::children() const
8011 This function returns the same value as QObject::children(). It's
8012 provided to differentiate between the obsolete member
8013 QGraphicsItem::children() and QObject::children(). QGraphicsItem now
8014 provides childItems() instead.
8018 \property QGraphicsObject::transformOriginPoint
8019 \brief the transformation origin
8021 This property sets a specific point in the items coordiante system as the
8022 origin for scale and rotation.
8024 \sa scale, rotation, QGraphicsItem::transformOriginPoint()
8028 \fn void QGraphicsObject::widthChanged()
8033 \fn void QGraphicsObject::heightChanged()
8039 \fn QGraphicsObject::childrenChanged()
8041 This signal gets emitted whenever the children list changes
8046 \property QGraphicsObject::effect
8048 \brief the effect attached to this item
8050 \sa QGraphicsItem::setGraphicsEffect(), QGraphicsItem::graphicsEffect()
8054 \class QAbstractGraphicsShapeItem
8055 \brief The QAbstractGraphicsShapeItem class provides a common base for
8058 \ingroup graphicsview-api
8061 This class does not fully implement an item by itself; in particular, it
8062 does not implement boundingRect() and paint(), which are inherited by
8065 You can subclass this item to provide a simple base implementation of
8066 accessors for the item's pen and brush.
8068 \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPathItem,
8069 QGraphicsPolygonItem, QGraphicsTextItem, QGraphicsLineItem,
8070 QGraphicsPixmapItem, {Graphics View Framework}
8073 class QAbstractGraphicsShapeItemPrivate : public QGraphicsItemPrivate
8075 Q_DECLARE_PUBLIC(QAbstractGraphicsShapeItem)
8081 // Cached bounding rectangle
8082 mutable QRectF boundingRect;
8086 Constructs a QAbstractGraphicsShapeItem. \a parent is passed to
8087 QGraphicsItem's constructor.
8089 QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QGraphicsItem *parent
8091 // obsolete argument
8092 , QGraphicsScene *scene
8095 : QGraphicsItem(*new QAbstractGraphicsShapeItemPrivate, parent, scene)
8102 QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QAbstractGraphicsShapeItemPrivate &dd,
8103 QGraphicsItem *parent,
8104 QGraphicsScene *scene)
8105 : QGraphicsItem(dd, parent, scene)
8110 Destroys a QAbstractGraphicsShapeItem.
8112 QAbstractGraphicsShapeItem::~QAbstractGraphicsShapeItem()
8117 Returns the item's pen. If no pen has been set, this function returns
8118 QPen(), a default black solid line pen with 0 width.
8120 QPen QAbstractGraphicsShapeItem::pen() const
8122 Q_D(const QAbstractGraphicsShapeItem);
8127 Sets the pen for this item to \a pen.
8129 The pen is used to draw the item's outline.
8133 void QAbstractGraphicsShapeItem::setPen(const QPen &pen)
8135 Q_D(QAbstractGraphicsShapeItem);
8138 prepareGeometryChange();
8140 d->boundingRect = QRectF();
8145 Returns the item's brush, or an empty brush if no brush has been set.
8149 QBrush QAbstractGraphicsShapeItem::brush() const
8151 Q_D(const QAbstractGraphicsShapeItem);
8156 Sets the item's brush to \a brush.
8158 The item's brush is used to fill the item.
8160 If you use a brush with a QGradient, the gradient
8161 is relative to the item's coordinate system.
8165 void QAbstractGraphicsShapeItem::setBrush(const QBrush &brush)
8167 Q_D(QAbstractGraphicsShapeItem);
8168 if (d->brush == brush)
8177 bool QAbstractGraphicsShapeItem::isObscuredBy(const QGraphicsItem *item) const
8179 return QGraphicsItem::isObscuredBy(item);
8185 QPainterPath QAbstractGraphicsShapeItem::opaqueArea() const
8187 Q_D(const QAbstractGraphicsShapeItem);
8188 if (d->brush.isOpaque())
8189 return isClipped() ? clipPath() : shape();
8190 return QGraphicsItem::opaqueArea();
8194 \class QGraphicsPathItem
8195 \brief The QGraphicsPathItem class provides a path item that you
8196 can add to a QGraphicsScene.
8198 \ingroup graphicsview-api
8201 To set the item's path, pass a QPainterPath to QGraphicsPathItem's
8202 constructor, or call the setPath() function. The path() function
8203 returns the current path.
8205 \image graphicsview-pathitem.png
8207 QGraphicsPathItem uses the path to provide a reasonable
8208 implementation of boundingRect(), shape(), and contains(). The
8209 paint() function draws the path using the item's associated pen
8210 and brush, which you can set by calling the setPen() and
8211 setBrush() functions.
8213 \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
8214 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8218 class QGraphicsPathItemPrivate : public QAbstractGraphicsShapeItemPrivate
8220 Q_DECLARE_PUBLIC(QGraphicsPathItem)
8226 Constructs a QGraphicsPath item using \a path as the default path. \a
8227 parent is passed to QAbstractGraphicsShapeItem's constructor.
8229 \sa QGraphicsScene::addItem()
8231 QGraphicsPathItem::QGraphicsPathItem(const QPainterPath &path,
8232 QGraphicsItem *parent
8234 // obsolete argument
8235 , QGraphicsScene *scene
8238 : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
8240 if (!path.isEmpty())
8245 Constructs a QGraphicsPath. \a parent is passed to
8246 QAbstractGraphicsShapeItem's constructor.
8248 \sa QGraphicsScene::addItem()
8250 QGraphicsPathItem::QGraphicsPathItem(QGraphicsItem *parent
8252 // obsolete argument
8253 , QGraphicsScene *scene
8256 : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
8261 Destroys the QGraphicsPathItem.
8263 QGraphicsPathItem::~QGraphicsPathItem()
8268 Returns the item's path as a QPainterPath. If no item has been set, an
8269 empty QPainterPath is returned.
8273 QPainterPath QGraphicsPathItem::path() const
8275 Q_D(const QGraphicsPathItem);
8280 Sets the item's path to be the given \a path.
8284 void QGraphicsPathItem::setPath(const QPainterPath &path)
8286 Q_D(QGraphicsPathItem);
8287 if (d->path == path)
8289 prepareGeometryChange();
8291 d->boundingRect = QRectF();
8298 QRectF QGraphicsPathItem::boundingRect() const
8300 Q_D(const QGraphicsPathItem);
8301 if (d->boundingRect.isNull()) {
8302 qreal pw = pen().widthF();
8304 d->boundingRect = d->path.controlPointRect();
8306 d->boundingRect = shape().controlPointRect();
8309 return d->boundingRect;
8315 QPainterPath QGraphicsPathItem::shape() const
8317 Q_D(const QGraphicsPathItem);
8318 return qt_graphicsItem_shapeFromPath(d->path, d->pen);
8324 bool QGraphicsPathItem::contains(const QPointF &point) const
8326 return QAbstractGraphicsShapeItem::contains(point);
8332 void QGraphicsPathItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8335 Q_D(QGraphicsPathItem);
8337 painter->setPen(d->pen);
8338 painter->setBrush(d->brush);
8339 painter->drawPath(d->path);
8341 if (option->state & QStyle::State_Selected)
8342 qt_graphicsItem_highlightSelected(this, painter, option);
8348 bool QGraphicsPathItem::isObscuredBy(const QGraphicsItem *item) const
8350 return QAbstractGraphicsShapeItem::isObscuredBy(item);
8356 QPainterPath QGraphicsPathItem::opaqueArea() const
8358 return QAbstractGraphicsShapeItem::opaqueArea();
8364 int QGraphicsPathItem::type() const
8372 bool QGraphicsPathItem::supportsExtension(Extension extension) const
8374 Q_UNUSED(extension);
8381 void QGraphicsPathItem::setExtension(Extension extension, const QVariant &variant)
8383 Q_UNUSED(extension);
8390 QVariant QGraphicsPathItem::extension(const QVariant &variant) const
8397 \class QGraphicsRectItem
8398 \brief The QGraphicsRectItem class provides a rectangle item that you
8399 can add to a QGraphicsScene.
8401 \ingroup graphicsview-api
8404 To set the item's rectangle, pass a QRectF to QGraphicsRectItem's
8405 constructor, or call the setRect() function. The rect() function
8406 returns the current rectangle.
8408 \image graphicsview-rectitem.png
8410 QGraphicsRectItem uses the rectangle and the pen width to provide
8411 a reasonable implementation of boundingRect(), shape(), and
8412 contains(). The paint() function draws the rectangle using the
8413 item's associated pen and brush, which you can set by calling the
8414 setPen() and setBrush() functions.
8416 \note The rendering of invalid rectangles, such as those with negative
8417 widths or heights, is undefined. If you cannot be sure that you are
8418 using valid rectangles (for example, if you are creating
8419 rectangles using data from an unreliable source) then you should
8420 use QRectF::normalized() to create normalized rectangles, and use
8423 \sa QGraphicsPathItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
8424 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8428 class QGraphicsRectItemPrivate : public QAbstractGraphicsShapeItemPrivate
8430 Q_DECLARE_PUBLIC(QGraphicsRectItem)
8436 Constructs a QGraphicsRectItem, using \a rect as the default rectangle.
8437 \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8439 \sa QGraphicsScene::addItem()
8441 QGraphicsRectItem::QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent
8443 // obsolete argument
8444 , QGraphicsScene *scene
8447 : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
8453 \fn QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal width, qreal height,
8454 QGraphicsItem *parent)
8456 Constructs a QGraphicsRectItem with a default rectangle defined
8457 by (\a x, \a y) and the given \a width and \a height.
8459 \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8461 \sa QGraphicsScene::addItem()
8463 QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h,
8464 QGraphicsItem *parent
8466 // obsolete argument
8467 , QGraphicsScene *scene
8470 : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
8472 setRect(QRectF(x, y, w, h));
8476 Constructs a QGraphicsRectItem. \a parent is passed to
8477 QAbstractGraphicsShapeItem's constructor.
8479 \sa QGraphicsScene::addItem()
8481 QGraphicsRectItem::QGraphicsRectItem(QGraphicsItem *parent
8483 // obsolete argument
8484 , QGraphicsScene *scene
8487 : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
8492 Destroys the QGraphicsRectItem.
8494 QGraphicsRectItem::~QGraphicsRectItem()
8499 Returns the item's rectangle.
8503 QRectF QGraphicsRectItem::rect() const
8505 Q_D(const QGraphicsRectItem);
8510 \fn void QGraphicsRectItem::setRect(const QRectF &rectangle)
8512 Sets the item's rectangle to be the given \a rectangle.
8516 void QGraphicsRectItem::setRect(const QRectF &rect)
8518 Q_D(QGraphicsRectItem);
8519 if (d->rect == rect)
8521 prepareGeometryChange();
8523 d->boundingRect = QRectF();
8528 \fn void QGraphicsRectItem::setRect(qreal x, qreal y, qreal width, qreal height)
8529 \fn void QGraphicsEllipseItem::setRect(qreal x, qreal y, qreal width, qreal height)
8531 Sets the item's rectangle to the rectangle defined by (\a x, \a y)
8532 and the given \a width and \a height.
8534 This convenience function is equivalent to calling \c
8535 {setRect(QRectF(x, y, width, height))}
8543 QRectF QGraphicsRectItem::boundingRect() const
8545 Q_D(const QGraphicsRectItem);
8546 if (d->boundingRect.isNull()) {
8547 qreal halfpw = pen().widthF() / 2;
8548 d->boundingRect = d->rect;
8550 d->boundingRect.adjust(-halfpw, -halfpw, halfpw, halfpw);
8552 return d->boundingRect;
8558 QPainterPath QGraphicsRectItem::shape() const
8560 Q_D(const QGraphicsRectItem);
8562 path.addRect(d->rect);
8563 return qt_graphicsItem_shapeFromPath(path, d->pen);
8569 bool QGraphicsRectItem::contains(const QPointF &point) const
8571 return QAbstractGraphicsShapeItem::contains(point);
8577 void QGraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8580 Q_D(QGraphicsRectItem);
8582 painter->setPen(d->pen);
8583 painter->setBrush(d->brush);
8584 painter->drawRect(d->rect);
8586 if (option->state & QStyle::State_Selected)
8587 qt_graphicsItem_highlightSelected(this, painter, option);
8593 bool QGraphicsRectItem::isObscuredBy(const QGraphicsItem *item) const
8595 return QAbstractGraphicsShapeItem::isObscuredBy(item);
8601 QPainterPath QGraphicsRectItem::opaqueArea() const
8603 return QAbstractGraphicsShapeItem::opaqueArea();
8609 int QGraphicsRectItem::type() const
8617 bool QGraphicsRectItem::supportsExtension(Extension extension) const
8619 Q_UNUSED(extension);
8626 void QGraphicsRectItem::setExtension(Extension extension, const QVariant &variant)
8628 Q_UNUSED(extension);
8635 QVariant QGraphicsRectItem::extension(const QVariant &variant) const
8642 \class QGraphicsEllipseItem
8643 \brief The QGraphicsEllipseItem class provides an ellipse item that you
8644 can add to a QGraphicsScene.
8646 \ingroup graphicsview-api
8649 QGraphicsEllipseItem respresents an ellipse with a fill and an outline,
8650 and you can also use it for ellipse segments (see startAngle(),
8655 \li \inlineimage graphicsview-ellipseitem.png
8656 \li \inlineimage graphicsview-ellipseitem-pie.png
8659 To set the item's ellipse, pass a QRectF to QGraphicsEllipseItem's
8660 constructor, or call setRect(). The rect() function returns the
8661 current ellipse geometry.
8663 QGraphicsEllipseItem uses the rect and the pen width to provide a
8664 reasonable implementation of boundingRect(), shape(), and contains(). The
8665 paint() function draws the ellipse using the item's associated pen and
8666 brush, which you can set by calling setPen() and setBrush().
8668 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsPolygonItem,
8669 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8673 class QGraphicsEllipseItemPrivate : public QAbstractGraphicsShapeItemPrivate
8675 Q_DECLARE_PUBLIC(QGraphicsEllipseItem)
8677 inline QGraphicsEllipseItemPrivate()
8678 : startAngle(0), spanAngle(360 * 16)
8687 Constructs a QGraphicsEllipseItem using \a rect as the default rectangle.
8688 \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8690 \sa QGraphicsScene::addItem()
8692 QGraphicsEllipseItem::QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent
8694 // obsolete argument
8695 , QGraphicsScene *scene
8698 : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
8704 \fn QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent)
8707 Constructs a QGraphicsEllipseItem using the rectangle defined by (\a x, \a
8708 y) and the given \a width and \a height, as the default rectangle. \a
8709 parent is passed to QAbstractGraphicsShapeItem's constructor.
8711 \sa QGraphicsScene::addItem()
8713 QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h,
8714 QGraphicsItem *parent
8716 // obsolete argument
8717 , QGraphicsScene *scene
8720 : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
8728 Constructs a QGraphicsEllipseItem. \a parent is passed to
8729 QAbstractGraphicsShapeItem's constructor.
8731 \sa QGraphicsScene::addItem()
8733 QGraphicsEllipseItem::QGraphicsEllipseItem(QGraphicsItem *parent
8735 // obsolete argument
8736 , QGraphicsScene *scene
8739 : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
8744 Destroys the QGraphicsEllipseItem.
8746 QGraphicsEllipseItem::~QGraphicsEllipseItem()
8751 Returns the item's ellipse geometry as a QRectF.
8753 \sa setRect(), QPainter::drawEllipse()
8755 QRectF QGraphicsEllipseItem::rect() const
8757 Q_D(const QGraphicsEllipseItem);
8762 Sets the item's ellipse geometry to \a rect. The rectangle's left edge
8763 defines the left edge of the ellipse, and the rectangle's top edge
8764 describes the top of the ellipse. The height and width of the rectangle
8765 describe the height and width of the ellipse.
8767 \sa rect(), QPainter::drawEllipse()
8769 void QGraphicsEllipseItem::setRect(const QRectF &rect)
8771 Q_D(QGraphicsEllipseItem);
8772 if (d->rect == rect)
8774 prepareGeometryChange();
8776 d->boundingRect = QRectF();
8781 Returns the start angle for an ellipse segment in 16ths of a degree. This
8782 angle is used together with spanAngle() for representing an ellipse
8783 segment (a pie). By default, the start angle is 0.
8785 \sa setStartAngle(), spanAngle()
8787 int QGraphicsEllipseItem::startAngle() const
8789 Q_D(const QGraphicsEllipseItem);
8790 return d->startAngle;
8794 Sets the start angle for an ellipse segment to \a angle, which is in 16ths
8795 of a degree. This angle is used together with spanAngle() for representing
8796 an ellipse segment (a pie). By default, the start angle is 0.
8798 \sa startAngle(), setSpanAngle(), QPainter::drawPie()
8800 void QGraphicsEllipseItem::setStartAngle(int angle)
8802 Q_D(QGraphicsEllipseItem);
8803 if (angle != d->startAngle) {
8804 prepareGeometryChange();
8805 d->boundingRect = QRectF();
8806 d->startAngle = angle;
8812 Returns the span angle of an ellipse segment in 16ths of a degree. This
8813 angle is used together with startAngle() for representing an ellipse
8814 segment (a pie). By default, this function returns 5760 (360 * 16, a full
8817 \sa setSpanAngle(), startAngle()
8819 int QGraphicsEllipseItem::spanAngle() const
8821 Q_D(const QGraphicsEllipseItem);
8822 return d->spanAngle;
8826 Sets the span angle for an ellipse segment to \a angle, which is in 16ths
8827 of a degree. This angle is used together with startAngle() to represent an
8828 ellipse segment (a pie). By default, the span angle is 5760 (360 * 16, a
8831 \sa spanAngle(), setStartAngle(), QPainter::drawPie()
8833 void QGraphicsEllipseItem::setSpanAngle(int angle)
8835 Q_D(QGraphicsEllipseItem);
8836 if (angle != d->spanAngle) {
8837 prepareGeometryChange();
8838 d->boundingRect = QRectF();
8839 d->spanAngle = angle;
8847 QRectF QGraphicsEllipseItem::boundingRect() const
8849 Q_D(const QGraphicsEllipseItem);
8850 if (d->boundingRect.isNull()) {
8851 qreal pw = pen().widthF();
8852 if (pw == 0.0 && d->spanAngle == 360 * 16)
8853 d->boundingRect = d->rect;
8855 d->boundingRect = shape().controlPointRect();
8857 return d->boundingRect;
8863 QPainterPath QGraphicsEllipseItem::shape() const
8865 Q_D(const QGraphicsEllipseItem);
8867 if (d->rect.isNull())
8869 if (d->spanAngle != 360 * 16) {
8870 path.moveTo(d->rect.center());
8871 path.arcTo(d->rect, d->startAngle / 16.0, d->spanAngle / 16.0);
8873 path.addEllipse(d->rect);
8876 return qt_graphicsItem_shapeFromPath(path, d->pen);
8882 bool QGraphicsEllipseItem::contains(const QPointF &point) const
8884 return QAbstractGraphicsShapeItem::contains(point);
8890 void QGraphicsEllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8893 Q_D(QGraphicsEllipseItem);
8895 painter->setPen(d->pen);
8896 painter->setBrush(d->brush);
8897 if ((d->spanAngle != 0) && (qAbs(d->spanAngle) % (360 * 16) == 0))
8898 painter->drawEllipse(d->rect);
8900 painter->drawPie(d->rect, d->startAngle, d->spanAngle);
8902 if (option->state & QStyle::State_Selected)
8903 qt_graphicsItem_highlightSelected(this, painter, option);
8909 bool QGraphicsEllipseItem::isObscuredBy(const QGraphicsItem *item) const
8911 return QAbstractGraphicsShapeItem::isObscuredBy(item);
8917 QPainterPath QGraphicsEllipseItem::opaqueArea() const
8919 return QAbstractGraphicsShapeItem::opaqueArea();
8925 int QGraphicsEllipseItem::type() const
8934 bool QGraphicsEllipseItem::supportsExtension(Extension extension) const
8936 Q_UNUSED(extension);
8943 void QGraphicsEllipseItem::setExtension(Extension extension, const QVariant &variant)
8945 Q_UNUSED(extension);
8952 QVariant QGraphicsEllipseItem::extension(const QVariant &variant) const
8959 \class QGraphicsPolygonItem
8960 \brief The QGraphicsPolygonItem class provides a polygon item that you
8961 can add to a QGraphicsScene.
8963 \ingroup graphicsview-api
8966 To set the item's polygon, pass a QPolygonF to
8967 QGraphicsPolygonItem's constructor, or call the setPolygon()
8968 function. The polygon() function returns the current polygon.
8970 \image graphicsview-polygonitem.png
8972 QGraphicsPolygonItem uses the polygon and the pen width to provide
8973 a reasonable implementation of boundingRect(), shape(), and
8974 contains(). The paint() function draws the polygon using the
8975 item's associated pen and brush, which you can set by calling the
8976 setPen() and setBrush() functions.
8978 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
8979 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8983 class QGraphicsPolygonItemPrivate : public QAbstractGraphicsShapeItemPrivate
8985 Q_DECLARE_PUBLIC(QGraphicsPolygonItem)
8987 inline QGraphicsPolygonItemPrivate()
8988 : fillRule(Qt::OddEvenFill)
8992 Qt::FillRule fillRule;
8996 Constructs a QGraphicsPolygonItem with \a polygon as the default
8997 polygon. \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8999 \sa QGraphicsScene::addItem()
9001 QGraphicsPolygonItem::QGraphicsPolygonItem(const QPolygonF &polygon,
9002 QGraphicsItem *parent
9004 // obsolete argument
9005 , QGraphicsScene *scene
9008 : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
9010 setPolygon(polygon);
9014 Constructs a QGraphicsPolygonItem. \a parent is passed to
9015 QAbstractGraphicsShapeItem's constructor.
9017 \sa QGraphicsScene::addItem()
9019 QGraphicsPolygonItem::QGraphicsPolygonItem(QGraphicsItem *parent
9021 // obsolete argument
9022 , QGraphicsScene *scene
9025 : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
9030 Destroys the QGraphicsPolygonItem.
9032 QGraphicsPolygonItem::~QGraphicsPolygonItem()
9037 Returns the item's polygon, or an empty polygon if no polygon
9042 QPolygonF QGraphicsPolygonItem::polygon() const
9044 Q_D(const QGraphicsPolygonItem);
9049 Sets the item's polygon to be the given \a polygon.
9053 void QGraphicsPolygonItem::setPolygon(const QPolygonF &polygon)
9055 Q_D(QGraphicsPolygonItem);
9056 if (d->polygon == polygon)
9058 prepareGeometryChange();
9059 d->polygon = polygon;
9060 d->boundingRect = QRectF();
9065 Returns the fill rule of the polygon. The default fill rule is
9068 \sa setFillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
9070 Qt::FillRule QGraphicsPolygonItem::fillRule() const
9072 Q_D(const QGraphicsPolygonItem);
9077 Sets the fill rule of the polygon to \a rule. The default fill rule is
9080 \sa fillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
9082 void QGraphicsPolygonItem::setFillRule(Qt::FillRule rule)
9084 Q_D(QGraphicsPolygonItem);
9085 if (rule != d->fillRule) {
9094 QRectF QGraphicsPolygonItem::boundingRect() const
9096 Q_D(const QGraphicsPolygonItem);
9097 if (d->boundingRect.isNull()) {
9098 qreal pw = pen().widthF();
9100 d->boundingRect = d->polygon.boundingRect();
9102 d->boundingRect = shape().controlPointRect();
9104 return d->boundingRect;
9110 QPainterPath QGraphicsPolygonItem::shape() const
9112 Q_D(const QGraphicsPolygonItem);
9114 path.addPolygon(d->polygon);
9115 return qt_graphicsItem_shapeFromPath(path, d->pen);
9121 bool QGraphicsPolygonItem::contains(const QPointF &point) const
9123 return QAbstractGraphicsShapeItem::contains(point);
9129 void QGraphicsPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
9131 Q_D(QGraphicsPolygonItem);
9133 painter->setPen(d->pen);
9134 painter->setBrush(d->brush);
9135 painter->drawPolygon(d->polygon, d->fillRule);
9137 if (option->state & QStyle::State_Selected)
9138 qt_graphicsItem_highlightSelected(this, painter, option);
9144 bool QGraphicsPolygonItem::isObscuredBy(const QGraphicsItem *item) const
9146 return QAbstractGraphicsShapeItem::isObscuredBy(item);
9152 QPainterPath QGraphicsPolygonItem::opaqueArea() const
9154 return QAbstractGraphicsShapeItem::opaqueArea();
9160 int QGraphicsPolygonItem::type() const
9168 bool QGraphicsPolygonItem::supportsExtension(Extension extension) const
9170 Q_UNUSED(extension);
9177 void QGraphicsPolygonItem::setExtension(Extension extension, const QVariant &variant)
9179 Q_UNUSED(extension);
9186 QVariant QGraphicsPolygonItem::extension(const QVariant &variant) const
9193 \class QGraphicsLineItem
9194 \brief The QGraphicsLineItem class provides a line item that you can add to a
9197 \ingroup graphicsview-api
9200 To set the item's line, pass a QLineF to QGraphicsLineItem's
9201 constructor, or call the setLine() function. The line() function
9202 returns the current line. By default the line is black with a
9203 width of 0, but you can change this by calling setPen().
9205 \img graphicsview-lineitem.png
9207 QGraphicsLineItem uses the line and the pen width to provide a reasonable
9208 implementation of boundingRect(), shape(), and contains(). The paint()
9209 function draws the line using the item's associated pen.
9211 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
9212 QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsPixmapItem,
9213 {Graphics View Framework}
9216 class QGraphicsLineItemPrivate : public QGraphicsItemPrivate
9218 Q_DECLARE_PUBLIC(QGraphicsLineItem)
9225 Constructs a QGraphicsLineItem, using \a line as the default line. \a
9226 parent is passed to QGraphicsItem's constructor.
9228 \sa QGraphicsScene::addItem()
9230 QGraphicsLineItem::QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent
9232 // obsolete argument
9233 , QGraphicsScene *scene
9236 : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
9242 Constructs a QGraphicsLineItem, using the line between (\a x1, \a y1) and
9243 (\a x2, \a y2) as the default line. \a parent is passed to
9244 QGraphicsItem's constructor.
9246 \sa QGraphicsScene::addItem()
9248 QGraphicsLineItem::QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent
9250 // obsolete argument
9251 , QGraphicsScene *scene
9254 : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
9256 setLine(x1, y1, x2, y2);
9262 Constructs a QGraphicsLineItem. \a parent is passed to QGraphicsItem's
9265 \sa QGraphicsScene::addItem()
9267 QGraphicsLineItem::QGraphicsLineItem(QGraphicsItem *parent
9269 // obsolete argument
9270 , QGraphicsScene *scene
9273 : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
9278 Destroys the QGraphicsLineItem.
9280 QGraphicsLineItem::~QGraphicsLineItem()
9285 Returns the item's pen, or a black solid 0-width pen if no pen has
9290 QPen QGraphicsLineItem::pen() const
9292 Q_D(const QGraphicsLineItem);
9297 Sets the item's pen to \a pen. If no pen is set, the line will be painted
9298 using a black solid 0-width pen.
9302 void QGraphicsLineItem::setPen(const QPen &pen)
9304 Q_D(QGraphicsLineItem);
9307 prepareGeometryChange();
9313 Returns the item's line, or a null line if no line has been set.
9317 QLineF QGraphicsLineItem::line() const
9319 Q_D(const QGraphicsLineItem);
9324 Sets the item's line to be the given \a line.
9328 void QGraphicsLineItem::setLine(const QLineF &line)
9330 Q_D(QGraphicsLineItem);
9331 if (d->line == line)
9333 prepareGeometryChange();
9339 \fn void QGraphicsLineItem::setLine(qreal x1, qreal y1, qreal x2, qreal y2)
9342 Sets the item's line to be the line between (\a x1, \a y1) and (\a
9345 This is the same as calling \c {setLine(QLineF(x1, y1, x2, y2))}.
9351 QRectF QGraphicsLineItem::boundingRect() const
9353 Q_D(const QGraphicsLineItem);
9354 if (d->pen.widthF() == 0.0) {
9355 const qreal x1 = d->line.p1().x();
9356 const qreal x2 = d->line.p2().x();
9357 const qreal y1 = d->line.p1().y();
9358 const qreal y2 = d->line.p2().y();
9359 qreal lx = qMin(x1, x2);
9360 qreal rx = qMax(x1, x2);
9361 qreal ty = qMin(y1, y2);
9362 qreal by = qMax(y1, y2);
9363 return QRectF(lx, ty, rx - lx, by - ty);
9365 return shape().controlPointRect();
9371 QPainterPath QGraphicsLineItem::shape() const
9373 Q_D(const QGraphicsLineItem);
9375 if (d->line == QLineF())
9378 path.moveTo(d->line.p1());
9379 path.lineTo(d->line.p2());
9380 return qt_graphicsItem_shapeFromPath(path, d->pen);
9386 bool QGraphicsLineItem::contains(const QPointF &point) const
9388 return QGraphicsItem::contains(point);
9394 void QGraphicsLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
9396 Q_D(QGraphicsLineItem);
9398 painter->setPen(d->pen);
9399 painter->drawLine(d->line);
9401 if (option->state & QStyle::State_Selected)
9402 qt_graphicsItem_highlightSelected(this, painter, option);
9408 bool QGraphicsLineItem::isObscuredBy(const QGraphicsItem *item) const
9410 return QGraphicsItem::isObscuredBy(item);
9416 QPainterPath QGraphicsLineItem::opaqueArea() const
9418 return QGraphicsItem::opaqueArea();
9424 int QGraphicsLineItem::type() const
9432 bool QGraphicsLineItem::supportsExtension(Extension extension) const
9434 Q_UNUSED(extension);
9441 void QGraphicsLineItem::setExtension(Extension extension, const QVariant &variant)
9443 Q_UNUSED(extension);
9450 QVariant QGraphicsLineItem::extension(const QVariant &variant) const
9457 \class QGraphicsPixmapItem
9458 \brief The QGraphicsPixmapItem class provides a pixmap item that you can add to
9461 \ingroup graphicsview-api
9464 To set the item's pixmap, pass a QPixmap to QGraphicsPixmapItem's
9465 constructor, or call the setPixmap() function. The pixmap()
9466 function returns the current pixmap.
9468 QGraphicsPixmapItem uses pixmap's optional alpha mask to provide a
9469 reasonable implementation of boundingRect(), shape(), and contains().
9471 \image graphicsview-pixmapitem.png
9473 The pixmap is drawn at the item's (0, 0) coordinate, as returned by
9474 offset(). You can change the drawing offset by calling setOffset().
9476 You can set the pixmap's transformation mode by calling
9477 setTransformationMode(). By default, Qt::FastTransformation is used, which
9478 provides fast, non-smooth scaling. Qt::SmoothTransformation enables
9479 QPainter::SmoothPixmapTransform on the painter, and the quality depends on
9480 the platform and viewport. The result is usually not as good as calling
9481 QPixmap::scale() directly. Call transformationMode() to get the current
9482 transformation mode for the item.
9484 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
9485 QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsLineItem,
9486 {Graphics View Framework}
9490 \enum QGraphicsPixmapItem::ShapeMode
9492 This enum describes how QGraphicsPixmapItem calculates its shape and
9495 The default value is MaskShape.
9497 \value MaskShape The shape is determined by calling QPixmap::mask().
9498 This shape includes only the opaque pixels of the pixmap.
9499 Because the shape is more complex, however, it can be slower than the other modes,
9500 and uses more memory.
9502 \value BoundingRectShape The shape is determined by tracing the outline of
9503 the pixmap. This is the fastest shape mode, but it does not take into account
9504 any transparent areas on the pixmap.
9506 \value HeuristicMaskShape The shape is determine by calling
9507 QPixmap::createHeuristicMask(). The performance and memory consumption
9508 is similar to MaskShape.
9510 extern QPainterPath qt_regionToPath(const QRegion ®ion);
9512 class QGraphicsPixmapItemPrivate : public QGraphicsItemPrivate
9514 Q_DECLARE_PUBLIC(QGraphicsPixmapItem)
9516 QGraphicsPixmapItemPrivate()
9517 : transformationMode(Qt::FastTransformation),
9518 shapeMode(QGraphicsPixmapItem::MaskShape),
9523 Qt::TransformationMode transformationMode;
9525 QGraphicsPixmapItem::ShapeMode shapeMode;
9531 shape = QPainterPath();
9532 switch (shapeMode) {
9533 case QGraphicsPixmapItem::MaskShape: {
9534 QBitmap mask = pixmap.mask();
9535 if (!mask.isNull()) {
9536 shape = qt_regionToPath(QRegion(mask).translated(offset.toPoint()));
9541 case QGraphicsPixmapItem::BoundingRectShape:
9542 shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
9544 case QGraphicsPixmapItem::HeuristicMaskShape:
9545 #ifndef QT_NO_IMAGE_HEURISTIC_MASK
9546 shape = qt_regionToPath(QRegion(pixmap.createHeuristicMask()).translated(offset.toPoint()));
9548 shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
9556 Constructs a QGraphicsPixmapItem, using \a pixmap as the default pixmap.
9557 \a parent is passed to QGraphicsItem's constructor.
9559 \sa QGraphicsScene::addItem()
9561 QGraphicsPixmapItem::QGraphicsPixmapItem(const QPixmap &pixmap,
9562 QGraphicsItem *parent
9564 // obsolete argument
9565 , QGraphicsScene *scene
9568 : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
9574 Constructs a QGraphicsPixmapItem. \a parent is passed to QGraphicsItem's
9577 \sa QGraphicsScene::addItem()
9579 QGraphicsPixmapItem::QGraphicsPixmapItem(QGraphicsItem *parent
9581 // obsolete argument
9582 , QGraphicsScene *scene
9585 : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
9590 Destroys the QGraphicsPixmapItem.
9592 QGraphicsPixmapItem::~QGraphicsPixmapItem()
9597 Sets the item's pixmap to \a pixmap.
9601 void QGraphicsPixmapItem::setPixmap(const QPixmap &pixmap)
9603 Q_D(QGraphicsPixmapItem);
9604 prepareGeometryChange();
9606 d->hasShape = false;
9611 Returns the item's pixmap, or an invalid QPixmap if no pixmap has been
9616 QPixmap QGraphicsPixmapItem::pixmap() const
9618 Q_D(const QGraphicsPixmapItem);
9623 Returns the transformation mode of the pixmap. The default mode is
9624 Qt::FastTransformation, which provides quick transformation with no
9627 \sa setTransformationMode()
9629 Qt::TransformationMode QGraphicsPixmapItem::transformationMode() const
9631 Q_D(const QGraphicsPixmapItem);
9632 return d->transformationMode;
9636 Sets the pixmap item's transformation mode to \a mode, and toggles an
9637 update of the item. The default mode is Qt::FastTransformation, which
9638 provides quick transformation with no smoothing.
9640 Qt::SmoothTransformation enables QPainter::SmoothPixmapTransform on the
9641 painter, and the quality depends on the platform and viewport. The result
9642 is usually not as good as calling QPixmap::scale() directly.
9644 \sa transformationMode()
9646 void QGraphicsPixmapItem::setTransformationMode(Qt::TransformationMode mode)
9648 Q_D(QGraphicsPixmapItem);
9649 if (mode != d->transformationMode) {
9650 d->transformationMode = mode;
9656 Returns the pixmap item's \e offset, which defines the point of the
9657 top-left corner of the pixmap, in local coordinates.
9661 QPointF QGraphicsPixmapItem::offset() const
9663 Q_D(const QGraphicsPixmapItem);
9668 Sets the pixmap item's offset to \a offset. QGraphicsPixmapItem will draw
9669 its pixmap using \a offset for its top-left corner.
9673 void QGraphicsPixmapItem::setOffset(const QPointF &offset)
9675 Q_D(QGraphicsPixmapItem);
9676 if (d->offset == offset)
9678 prepareGeometryChange();
9680 d->hasShape = false;
9685 \fn void QGraphicsPixmapItem::setOffset(qreal x, qreal y)
9688 This convenience function is equivalent to calling setOffset(QPointF(\a x, \a y)).
9694 QRectF QGraphicsPixmapItem::boundingRect() const
9696 Q_D(const QGraphicsPixmapItem);
9697 if (d->pixmap.isNull())
9699 if (d->flags & ItemIsSelectable) {
9701 return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
9703 return QRectF(d->offset, d->pixmap.size());
9710 QPainterPath QGraphicsPixmapItem::shape() const
9712 Q_D(const QGraphicsPixmapItem);
9714 QGraphicsPixmapItemPrivate *thatD = const_cast<QGraphicsPixmapItemPrivate *>(d);
9715 thatD->updateShape();
9716 thatD->hasShape = true;
9718 return d_func()->shape;
9724 bool QGraphicsPixmapItem::contains(const QPointF &point) const
9726 return QGraphicsItem::contains(point);
9732 void QGraphicsPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
9735 Q_D(QGraphicsPixmapItem);
9738 painter->setRenderHint(QPainter::SmoothPixmapTransform,
9739 (d->transformationMode == Qt::SmoothTransformation));
9741 painter->drawPixmap(d->offset, d->pixmap);
9743 if (option->state & QStyle::State_Selected)
9744 qt_graphicsItem_highlightSelected(this, painter, option);
9750 bool QGraphicsPixmapItem::isObscuredBy(const QGraphicsItem *item) const
9752 return QGraphicsItem::isObscuredBy(item);
9758 QPainterPath QGraphicsPixmapItem::opaqueArea() const
9766 int QGraphicsPixmapItem::type() const
9772 Returns the item's shape mode. The shape mode describes how
9773 QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
9775 \sa setShapeMode(), ShapeMode
9777 QGraphicsPixmapItem::ShapeMode QGraphicsPixmapItem::shapeMode() const
9779 return d_func()->shapeMode;
9783 Sets the item's shape mode to \a mode. The shape mode describes how
9784 QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
9786 \sa shapeMode(), ShapeMode
9788 void QGraphicsPixmapItem::setShapeMode(ShapeMode mode)
9790 Q_D(QGraphicsPixmapItem);
9791 if (d->shapeMode == mode)
9793 d->shapeMode = mode;
9794 d->hasShape = false;
9800 bool QGraphicsPixmapItem::supportsExtension(Extension extension) const
9802 Q_UNUSED(extension);
9809 void QGraphicsPixmapItem::setExtension(Extension extension, const QVariant &variant)
9811 Q_UNUSED(extension);
9818 QVariant QGraphicsPixmapItem::extension(const QVariant &variant) const
9825 \class QGraphicsTextItem
9826 \brief The QGraphicsTextItem class provides a text item that you can add to
9827 a QGraphicsScene to display formatted text.
9829 \ingroup graphicsview-api
9832 If you only need to show plain text in an item, consider using QGraphicsSimpleTextItem
9835 To set the item's text, pass a QString to QGraphicsTextItem's
9836 constructor, or call setHtml()/setPlainText().
9838 QGraphicsTextItem uses the text's formatted size and the associated font
9839 to provide a reasonable implementation of boundingRect(), shape(),
9840 and contains(). You can set the font by calling setFont().
9842 It is possible to make the item editable by setting the Qt::TextEditorInteraction flag
9843 using setTextInteractionFlags().
9845 The item's preferred text width can be set using setTextWidth() and obtained
9848 \note In order to align HTML text in the center, the item's text width must be set.
9850 \img graphicsview-textitem.png
9852 \note QGraphicsTextItem accepts \l{QGraphicsItem::acceptHoverEvents()}{hover events}
9853 by default. You can change this with \l{QGraphicsItem::}{setAcceptHoverEvents()}.
9855 \sa QGraphicsSimpleTextItem, QGraphicsPathItem, QGraphicsRectItem,
9856 QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
9857 QGraphicsLineItem, {Graphics View Framework}
9860 class QGraphicsTextItemPrivate
9863 QGraphicsTextItemPrivate()
9864 : control(0), pageNumber(0), useDefaultImpl(false), tabChangesFocus(false), clickCausedFocus(0)
9867 mutable QWidgetTextControl *control;
9868 QWidgetTextControl *textControl() const;
9870 inline QPointF controlOffset() const
9871 { return QPointF(0., pageNumber * control->document()->pageSize().height()); }
9872 inline void sendControlEvent(QEvent *e)
9873 { if (control) control->processEvent(e, controlOffset()); }
9875 void _q_updateBoundingRect(const QSizeF &);
9876 void _q_update(QRectF);
9877 void _q_ensureVisible(QRectF);
9878 bool _q_mouseOnEdge(QGraphicsSceneMouseEvent *);
9880 QRectF boundingRect;
9882 bool useDefaultImpl;
9883 bool tabChangesFocus;
9885 uint clickCausedFocus : 1;
9887 QGraphicsTextItem *qq;
9892 Constructs a QGraphicsTextItem, using \a text as the default plain
9893 text. \a parent is passed to QGraphicsItem's constructor.
9895 \sa QGraphicsScene::addItem()
9897 QGraphicsTextItem::QGraphicsTextItem(const QString &text, QGraphicsItem *parent
9899 // obsolete argument
9900 , QGraphicsScene *scene
9903 : QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
9906 if (!text.isEmpty())
9908 setAcceptDrops(true);
9909 setAcceptHoverEvents(true);
9910 setFlags(ItemUsesExtendedStyleOption);
9914 Constructs a QGraphicsTextItem. \a parent is passed to QGraphicsItem's
9917 \sa QGraphicsScene::addItem()
9919 QGraphicsTextItem::QGraphicsTextItem(QGraphicsItem *parent
9921 // obsolete argument
9922 , QGraphicsScene *scene
9925 : QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
9928 setAcceptDrops(true);
9929 setAcceptHoverEvents(true);
9930 setFlag(ItemUsesExtendedStyleOption);
9934 Destroys the QGraphicsTextItem.
9936 QGraphicsTextItem::~QGraphicsTextItem()
9942 Returns the item's text converted to HTML, or an empty QString if no text has been set.
9946 QString QGraphicsTextItem::toHtml() const
9948 #ifndef QT_NO_TEXTHTMLPARSER
9950 return dd->control->toHtml();
9956 Sets the item's text to \a text, assuming that text is HTML formatted. If
9957 the item has keyboard input focus, this function will also call
9958 ensureVisible() to ensure that the text is visible in all viewports.
9960 \sa toHtml(), hasFocus(), QGraphicsSimpleTextItem
9962 void QGraphicsTextItem::setHtml(const QString &text)
9964 dd->textControl()->setHtml(text);
9968 Returns the item's text converted to plain text, or an empty QString if no text has been set.
9972 QString QGraphicsTextItem::toPlainText() const
9975 return dd->control->toPlainText();
9980 Sets the item's text to \a text. If the item has keyboard input focus,
9981 this function will also call ensureVisible() to ensure that the text is
9982 visible in all viewports.
9984 \sa toHtml(), hasFocus()
9986 void QGraphicsTextItem::setPlainText(const QString &text)
9988 dd->textControl()->setPlainText(text);
9992 Returns the item's font, which is used to render the text.
9996 QFont QGraphicsTextItem::font() const
10000 return dd->control->document()->defaultFont();
10004 Sets the font used to render the text item to \a font.
10008 void QGraphicsTextItem::setFont(const QFont &font)
10010 dd->textControl()->document()->setDefaultFont(font);
10014 Sets the color for unformatted text to \a col.
10016 void QGraphicsTextItem::setDefaultTextColor(const QColor &col)
10018 QWidgetTextControl *c = dd->textControl();
10019 QPalette pal = c->palette();
10020 QColor old = pal.color(QPalette::Text);
10021 pal.setColor(QPalette::Text, col);
10022 c->setPalette(pal);
10028 Returns the default text color that is used to for unformatted text.
10030 QColor QGraphicsTextItem::defaultTextColor() const
10032 return dd->textControl()->palette().color(QPalette::Text);
10038 QRectF QGraphicsTextItem::boundingRect() const
10040 return dd->boundingRect;
10046 QPainterPath QGraphicsTextItem::shape() const
10049 return QPainterPath();
10051 path.addRect(dd->boundingRect);
10058 bool QGraphicsTextItem::contains(const QPointF &point) const
10060 return dd->boundingRect.contains(point);
10066 void QGraphicsTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
10072 QRectF r = option->exposedRect;
10073 painter->translate(-dd->controlOffset());
10074 r.translate(dd->controlOffset());
10076 QTextDocument *doc = dd->control->document();
10077 QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
10079 // the layout might need to expand the root frame to
10080 // the viewport if NoWrap is set
10082 layout->setViewport(dd->boundingRect);
10084 dd->control->drawContents(painter, r);
10087 layout->setViewport(QRect());
10089 painter->restore();
10092 if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
10093 qt_graphicsItem_highlightSelected(this, painter, option);
10099 bool QGraphicsTextItem::isObscuredBy(const QGraphicsItem *item) const
10101 return QGraphicsItem::isObscuredBy(item);
10107 QPainterPath QGraphicsTextItem::opaqueArea() const
10109 return QGraphicsItem::opaqueArea();
10115 int QGraphicsTextItem::type() const
10121 Sets the preferred width for the item's text. If the actual text
10122 is wider than the specified width then it will be broken into
10125 If \a width is set to -1 then the text will not be broken into
10126 multiple lines unless it is enforced through an explicit line
10127 break or a new paragraph.
10129 The default value is -1.
10131 Note that QGraphicsTextItem keeps a QTextDocument internally,
10132 which is used to calculate the text width.
10134 \sa textWidth(), QTextDocument::setTextWidth()
10136 void QGraphicsTextItem::setTextWidth(qreal width)
10138 dd->textControl()->setTextWidth(width);
10142 Returns the text width.
10144 The width is calculated with the QTextDocument that
10145 QGraphicsTextItem keeps internally.
10147 \sa setTextWidth(), QTextDocument::textWidth()
10149 qreal QGraphicsTextItem::textWidth() const
10153 return dd->control->textWidth();
10157 Adjusts the text item to a reasonable size.
10159 void QGraphicsTextItem::adjustSize()
10162 dd->control->adjustSize();
10166 Sets the text document \a document on the item.
10168 void QGraphicsTextItem::setDocument(QTextDocument *document)
10170 dd->textControl()->setDocument(document);
10171 dd->_q_updateBoundingRect(dd->control->size());
10175 Returns the item's text document.
10177 QTextDocument *QGraphicsTextItem::document() const
10179 return dd->textControl()->document();
10185 bool QGraphicsTextItem::sceneEvent(QEvent *event)
10187 QEvent::Type t = event->type();
10188 if (!dd->tabChangesFocus && (t == QEvent::KeyPress || t == QEvent::KeyRelease)) {
10189 int k = ((QKeyEvent *)event)->key();
10190 if (k == Qt::Key_Tab || k == Qt::Key_Backtab) {
10191 dd->sendControlEvent(event);
10195 bool result = QGraphicsItem::sceneEvent(event);
10197 // Ensure input context is updated.
10198 switch (event->type()) {
10199 case QEvent::ContextMenu:
10200 case QEvent::FocusIn:
10201 case QEvent::FocusOut:
10202 case QEvent::GraphicsSceneDragEnter:
10203 case QEvent::GraphicsSceneDragLeave:
10204 case QEvent::GraphicsSceneDragMove:
10205 case QEvent::GraphicsSceneDrop:
10206 case QEvent::GraphicsSceneHoverEnter:
10207 case QEvent::GraphicsSceneHoverLeave:
10208 case QEvent::GraphicsSceneHoverMove:
10209 case QEvent::GraphicsSceneMouseDoubleClick:
10210 case QEvent::GraphicsSceneMousePress:
10211 case QEvent::GraphicsSceneMouseMove:
10212 case QEvent::GraphicsSceneMouseRelease:
10213 case QEvent::KeyPress:
10214 case QEvent::KeyRelease:
10215 // Reset the focus widget's input context, regardless
10216 // of how this item gained or lost focus.
10217 if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) {
10218 qApp->inputMethod()->reset();
10220 qApp->inputMethod()->update(Qt::ImQueryInput);
10223 case QEvent::ShortcutOverride:
10224 dd->sendControlEvent(event);
10236 void QGraphicsTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
10238 if ((QGraphicsItem::d_ptr->flags & (ItemIsSelectable | ItemIsMovable))
10239 && (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) {
10240 // User left-pressed on edge of selectable/movable item, use
10242 dd->useDefaultImpl = true;
10243 } else if (event->buttons() == event->button()
10244 && dd->control->textInteractionFlags() == Qt::NoTextInteraction) {
10245 // User pressed first button on non-interactive item.
10246 dd->useDefaultImpl = true;
10248 if (dd->useDefaultImpl) {
10249 QGraphicsItem::mousePressEvent(event);
10250 if (!event->isAccepted())
10251 dd->useDefaultImpl = false;
10255 dd->sendControlEvent(event);
10261 void QGraphicsTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
10263 if (dd->useDefaultImpl) {
10264 QGraphicsItem::mouseMoveEvent(event);
10268 dd->sendControlEvent(event);
10274 void QGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
10276 if (dd->useDefaultImpl) {
10277 QGraphicsItem::mouseReleaseEvent(event);
10278 if (dd->control->textInteractionFlags() == Qt::NoTextInteraction
10279 && !event->buttons()) {
10280 // User released last button on non-interactive item.
10281 dd->useDefaultImpl = false;
10282 } else if ((event->buttons() & Qt::LeftButton) == 0) {
10283 // User released the left button on an interactive item.
10284 dd->useDefaultImpl = false;
10289 QWidget *widget = event->widget();
10290 if (widget && (dd->control->textInteractionFlags() & Qt::TextEditable) && boundingRect().contains(event->pos())) {
10291 qt_widget_private(widget)->handleSoftwareInputPanel(event->button(), dd->clickCausedFocus);
10293 dd->clickCausedFocus = 0;
10294 dd->sendControlEvent(event);
10300 void QGraphicsTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
10302 if (dd->useDefaultImpl) {
10303 QGraphicsItem::mouseDoubleClickEvent(event);
10308 QGraphicsItem::mouseDoubleClickEvent(event);
10312 dd->sendControlEvent(event);
10318 void QGraphicsTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
10320 dd->sendControlEvent(event);
10326 void QGraphicsTextItem::keyPressEvent(QKeyEvent *event)
10328 dd->sendControlEvent(event);
10334 void QGraphicsTextItem::keyReleaseEvent(QKeyEvent *event)
10336 dd->sendControlEvent(event);
10342 void QGraphicsTextItem::focusInEvent(QFocusEvent *event)
10344 dd->sendControlEvent(event);
10345 if (event->reason() == Qt::MouseFocusReason) {
10346 dd->clickCausedFocus = 1;
10354 void QGraphicsTextItem::focusOutEvent(QFocusEvent *event)
10356 dd->sendControlEvent(event);
10363 void QGraphicsTextItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
10365 dd->sendControlEvent(event);
10371 void QGraphicsTextItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
10373 dd->sendControlEvent(event);
10379 void QGraphicsTextItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
10381 dd->sendControlEvent(event);
10387 void QGraphicsTextItem::dropEvent(QGraphicsSceneDragDropEvent *event)
10389 dd->sendControlEvent(event);
10395 void QGraphicsTextItem::inputMethodEvent(QInputMethodEvent *event)
10397 dd->sendControlEvent(event);
10403 void QGraphicsTextItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
10405 dd->sendControlEvent(event);
10411 void QGraphicsTextItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
10413 dd->sendControlEvent(event);
10419 void QGraphicsTextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
10421 dd->sendControlEvent(event);
10427 QVariant QGraphicsTextItem::inputMethodQuery(Qt::InputMethodQuery query) const
10431 v = dd->control->inputMethodQuery(query);
10432 if (v.type() == QVariant::RectF)
10433 v = v.toRectF().translated(-dd->controlOffset());
10434 else if (v.type() == QVariant::PointF)
10435 v = v.toPointF() - dd->controlOffset();
10436 else if (v.type() == QVariant::Rect)
10437 v = v.toRect().translated(-dd->controlOffset().toPoint());
10438 else if (v.type() == QVariant::Point)
10439 v = v.toPoint() - dd->controlOffset().toPoint();
10446 bool QGraphicsTextItem::supportsExtension(Extension extension) const
10448 Q_UNUSED(extension);
10455 void QGraphicsTextItem::setExtension(Extension extension, const QVariant &variant)
10457 Q_UNUSED(extension);
10464 QVariant QGraphicsTextItem::extension(const QVariant &variant) const
10473 void QGraphicsTextItemPrivate::_q_update(QRectF rect)
10475 if (rect.isValid()) {
10476 rect.translate(-controlOffset());
10478 rect = boundingRect;
10480 if (rect.intersects(boundingRect))
10487 void QGraphicsTextItemPrivate::_q_updateBoundingRect(const QSizeF &size)
10489 if (!control) return; // can't happen
10490 const QSizeF pageSize = control->document()->pageSize();
10491 // paged items have a constant (page) size
10492 if (size == boundingRect.size() || pageSize.height() != -1)
10494 qq->prepareGeometryChange();
10495 boundingRect.setSize(size);
10502 void QGraphicsTextItemPrivate::_q_ensureVisible(QRectF rect)
10504 if (qq->hasFocus()) {
10505 rect.translate(-controlOffset());
10506 qq->ensureVisible(rect, /*xmargin=*/0, /*ymargin=*/0);
10510 QWidgetTextControl *QGraphicsTextItemPrivate::textControl() const
10513 QGraphicsTextItem *that = const_cast<QGraphicsTextItem *>(qq);
10514 control = new QWidgetTextControl(that);
10515 control->setTextInteractionFlags(Qt::NoTextInteraction);
10517 QObject::connect(control, SIGNAL(updateRequest(QRectF)),
10518 qq, SLOT(_q_update(QRectF)));
10519 QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)),
10520 qq, SLOT(_q_updateBoundingRect(QSizeF)));
10521 QObject::connect(control, SIGNAL(visibilityRequest(QRectF)),
10522 qq, SLOT(_q_ensureVisible(QRectF)));
10523 QObject::connect(control, SIGNAL(linkActivated(QString)),
10524 qq, SIGNAL(linkActivated(QString)));
10525 QObject::connect(control, SIGNAL(linkHovered(QString)),
10526 qq, SIGNAL(linkHovered(QString)));
10528 const QSizeF pgSize = control->document()->pageSize();
10529 if (pgSize.height() != -1) {
10530 qq->prepareGeometryChange();
10531 that->dd->boundingRect.setSize(pgSize);
10534 that->dd->_q_updateBoundingRect(control->size());
10543 bool QGraphicsTextItemPrivate::_q_mouseOnEdge(QGraphicsSceneMouseEvent *event)
10546 path.addRect(qq->boundingRect());
10548 QPainterPath docPath;
10549 const QTextFrameFormat format = control->document()->rootFrame()->frameFormat();
10551 qq->boundingRect().adjusted(
10552 format.leftMargin(),
10553 format.topMargin(),
10554 -format.rightMargin(),
10555 -format.bottomMargin()));
10557 return path.subtracted(docPath).contains(event->pos());
10561 \fn QGraphicsTextItem::linkActivated(const QString &link)
10563 This signal is emitted when the user clicks on a link on a text item
10564 that enables Qt::LinksAccessibleByMouse or Qt::LinksAccessibleByKeyboard.
10565 \a link is the link that was clicked.
10567 \sa setTextInteractionFlags()
10571 \fn QGraphicsTextItem::linkHovered(const QString &link)
10573 This signal is emitted when the user hovers over a link on a text item
10574 that enables Qt::LinksAccessibleByMouse. \a link is
10575 the link that was hovered over.
10577 \sa setTextInteractionFlags()
10581 Sets the flags \a flags to specify how the text item should react to user
10584 The default for a QGraphicsTextItem is Qt::NoTextInteraction. This function
10585 also affects the ItemIsFocusable QGraphicsItem flag by setting it if \a flags
10586 is different from Qt::NoTextInteraction and clearing it otherwise.
10588 By default, the text is read-only. To transform the item into an editor,
10589 set the Qt::TextEditable flag.
10591 void QGraphicsTextItem::setTextInteractionFlags(Qt::TextInteractionFlags flags)
10593 if (flags == Qt::NoTextInteraction)
10594 setFlags(this->flags() & ~(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod));
10596 setFlags(this->flags() | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod);
10598 dd->textControl()->setTextInteractionFlags(flags);
10602 Returns the current text interaction flags.
10604 \sa setTextInteractionFlags()
10606 Qt::TextInteractionFlags QGraphicsTextItem::textInteractionFlags() const
10609 return Qt::NoTextInteraction;
10610 return dd->control->textInteractionFlags();
10616 If \a b is true, the \uicontrol Tab key will cause the widget to change focus;
10617 otherwise, the tab key will insert a tab into the document.
10619 In some occasions text edits should not allow the user to input tabulators
10620 or change indentation using the \uicontrol Tab key, as this breaks the focus
10621 chain. The default is false.
10623 \sa tabChangesFocus(), ItemIsFocusable, textInteractionFlags()
10625 void QGraphicsTextItem::setTabChangesFocus(bool b)
10627 dd->tabChangesFocus = b;
10633 Returns true if the \uicontrol Tab key will cause the widget to change focus;
10634 otherwise, false is returned.
10636 By default, this behavior is disabled, and this function will return false.
10638 \sa setTabChangesFocus()
10640 bool QGraphicsTextItem::tabChangesFocus() const
10642 return dd->tabChangesFocus;
10646 \property QGraphicsTextItem::openExternalLinks
10648 Specifies whether QGraphicsTextItem should automatically open links using
10649 QDesktopServices::openUrl() instead of emitting the
10650 linkActivated signal.
10652 The default value is false.
10654 void QGraphicsTextItem::setOpenExternalLinks(bool open)
10656 dd->textControl()->setOpenExternalLinks(open);
10659 bool QGraphicsTextItem::openExternalLinks() const
10663 return dd->control->openExternalLinks();
10667 \property QGraphicsTextItem::textCursor
10669 This property represents the visible text cursor in an editable
10672 By default, if the item's text has not been set, this property
10673 contains a null text cursor; otherwise it contains a text cursor
10674 placed at the start of the item's document.
10676 void QGraphicsTextItem::setTextCursor(const QTextCursor &cursor)
10678 dd->textControl()->setTextCursor(cursor);
10681 QTextCursor QGraphicsTextItem::textCursor() const
10684 return QTextCursor();
10685 return dd->control->textCursor();
10688 class QGraphicsSimpleTextItemPrivate : public QAbstractGraphicsShapeItemPrivate
10690 Q_DECLARE_PUBLIC(QGraphicsSimpleTextItem)
10692 inline QGraphicsSimpleTextItemPrivate() {
10693 pen.setStyle(Qt::NoPen);
10694 brush.setStyle(Qt::SolidPattern);
10698 QRectF boundingRect;
10700 void updateBoundingRect();
10703 static QRectF setupTextLayout(QTextLayout *layout)
10705 layout->setCacheEnabled(true);
10706 layout->beginLayout();
10707 while (layout->createLine().isValid())
10709 layout->endLayout();
10710 qreal maxWidth = 0;
10712 for (int i = 0; i < layout->lineCount(); ++i) {
10713 QTextLine line = layout->lineAt(i);
10714 maxWidth = qMax(maxWidth, line.naturalTextWidth());
10715 line.setPosition(QPointF(0, y));
10716 y += line.height();
10718 return QRectF(0, 0, maxWidth, y);
10721 void QGraphicsSimpleTextItemPrivate::updateBoundingRect()
10723 Q_Q(QGraphicsSimpleTextItem);
10725 if (text.isEmpty()) {
10728 QString tmp = text;
10729 tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
10730 QStackTextEngine engine(tmp, font);
10731 QTextLayout layout(&engine);
10732 br = setupTextLayout(&layout);
10734 if (br != boundingRect) {
10735 q->prepareGeometryChange();
10742 \class QGraphicsSimpleTextItem
10743 \brief The QGraphicsSimpleTextItem class provides a simple text path item
10744 that you can add to a QGraphicsScene.
10746 \ingroup graphicsview-api
10747 \inmodule QtWidgets
10749 To set the item's text, you can either pass a QString to
10750 QGraphicsSimpleTextItem's constructor, or call setText() to change the
10751 text later. To set the text fill color, call setBrush().
10753 The simple text item can have both a fill and an outline; setBrush() will
10754 set the text fill (i.e., text color), and setPen() sets the pen that will
10755 be used to draw the text outline. (The latter can be slow, especially for
10756 complex pens, and items with long text content.) If all you want is to
10757 draw a simple line of text, you should call setBrush() only, and leave the
10758 pen unset; QGraphicsSimpleTextItem's pen is by default Qt::NoPen.
10760 QGraphicsSimpleTextItem uses the text's formatted size and the associated
10761 font to provide a reasonable implementation of boundingRect(), shape(),
10762 and contains(). You can set the font by calling setFont().
10764 QGraphicsSimpleText does not display rich text; instead, you can use
10765 QGraphicsTextItem, which provides full text control capabilities.
10767 \img graphicsview-simpletextitem.png
10769 \sa QGraphicsTextItem, QGraphicsPathItem, QGraphicsRectItem,
10770 QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
10771 QGraphicsLineItem, {Graphics View Framework}
10775 Constructs a QGraphicsSimpleTextItem.
10777 \a parent is passed to QGraphicsItem's constructor.
10779 \sa QGraphicsScene::addItem()
10781 QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(QGraphicsItem *parent
10783 // obsolete argument
10784 , QGraphicsScene *scene
10787 : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
10792 Constructs a QGraphicsSimpleTextItem, using \a text as the default plain text.
10794 \a parent is passed to QGraphicsItem's constructor.
10796 \sa QGraphicsScene::addItem()
10798 QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent
10800 // obsolete argument
10801 , QGraphicsScene *scene
10804 : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
10810 Destroys the QGraphicsSimpleTextItem.
10812 QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem()
10817 Sets the item's text to \a text. The text will be displayed as
10818 plain text. Newline characters ('\n') as well as characters of
10819 type QChar::LineSeparator will cause item to break the text into
10822 void QGraphicsSimpleTextItem::setText(const QString &text)
10824 Q_D(QGraphicsSimpleTextItem);
10825 if (d->text == text)
10828 d->updateBoundingRect();
10833 Returns the item's text.
10835 QString QGraphicsSimpleTextItem::text() const
10837 Q_D(const QGraphicsSimpleTextItem);
10842 Sets the font that is used to draw the item's text to \a font.
10844 void QGraphicsSimpleTextItem::setFont(const QFont &font)
10846 Q_D(QGraphicsSimpleTextItem);
10848 d->updateBoundingRect();
10852 Returns the font that is used to draw the item's text.
10854 QFont QGraphicsSimpleTextItem::font() const
10856 Q_D(const QGraphicsSimpleTextItem);
10863 QRectF QGraphicsSimpleTextItem::boundingRect() const
10865 Q_D(const QGraphicsSimpleTextItem);
10866 return d->boundingRect;
10872 QPainterPath QGraphicsSimpleTextItem::shape() const
10874 Q_D(const QGraphicsSimpleTextItem);
10876 path.addRect(d->boundingRect);
10883 bool QGraphicsSimpleTextItem::contains(const QPointF &point) const
10885 Q_D(const QGraphicsSimpleTextItem);
10886 return d->boundingRect.contains(point);
10892 void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
10895 Q_D(QGraphicsSimpleTextItem);
10897 painter->setFont(d->font);
10899 QString tmp = d->text;
10900 tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
10901 QStackTextEngine engine(tmp, d->font);
10902 QTextLayout layout(&engine);
10903 setupTextLayout(&layout);
10906 p.setBrush(d->brush);
10907 painter->setPen(p);
10908 if (d->pen.style() == Qt::NoPen && d->brush.style() == Qt::SolidPattern) {
10909 painter->setBrush(Qt::NoBrush);
10911 QTextLayout::FormatRange range;
10913 range.length = layout.text().length();
10914 range.format.setTextOutline(d->pen);
10915 QList<QTextLayout::FormatRange> formats;
10916 formats.append(range);
10917 layout.setAdditionalFormats(formats);
10920 layout.draw(painter, QPointF(0, 0));
10922 if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
10923 qt_graphicsItem_highlightSelected(this, painter, option);
10929 bool QGraphicsSimpleTextItem::isObscuredBy(const QGraphicsItem *item) const
10931 return QAbstractGraphicsShapeItem::isObscuredBy(item);
10937 QPainterPath QGraphicsSimpleTextItem::opaqueArea() const
10939 return QAbstractGraphicsShapeItem::opaqueArea();
10945 int QGraphicsSimpleTextItem::type() const
10953 bool QGraphicsSimpleTextItem::supportsExtension(Extension extension) const
10955 Q_UNUSED(extension);
10962 void QGraphicsSimpleTextItem::setExtension(Extension extension, const QVariant &variant)
10964 Q_UNUSED(extension);
10971 QVariant QGraphicsSimpleTextItem::extension(const QVariant &variant) const
10978 \class QGraphicsItemGroup
10979 \brief The QGraphicsItemGroup class provides a container that treats
10980 a group of items as a single item.
10982 \ingroup graphicsview-api
10983 \inmodule QtWidgets
10985 A QGraphicsItemGroup is a special type of compound item that
10986 treats itself and all its children as one item (i.e., all events
10987 and geometries for all children are merged together). It's common
10988 to use item groups in presentation tools, when the user wants to
10989 group several smaller items into one big item in order to simplify
10990 moving and copying of items.
10992 If all you want is to store items inside other items, you can use
10993 any QGraphicsItem directly by passing a suitable parent to
10996 The boundingRect() function of QGraphicsItemGroup returns the
10997 bounding rectangle of all items in the item group.
10998 QGraphicsItemGroup ignores the ItemIgnoresTransformations flag on
10999 its children (i.e., with respect to the geometry of the group
11000 item, the children are treated as if they were transformable).
11002 There are two ways to construct an item group. The easiest and
11003 most common approach is to pass a list of items (e.g., all
11004 selected items) to QGraphicsScene::createItemGroup(), which
11005 returns a new QGraphicsItemGroup item. The other approach is to
11006 manually construct a QGraphicsItemGroup item, add it to the scene
11007 calling QGraphicsScene::addItem(), and then add items to the group
11008 manually, one at a time by calling addToGroup(). To dismantle
11009 ("ungroup") an item group, you can either call
11010 QGraphicsScene::destroyItemGroup(), or you can manually remove all
11011 items from the group by calling removeFromGroup().
11013 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 17
11015 The operation of adding and removing items preserves the items'
11016 scene-relative position and transformation, as opposed to calling
11017 setParentItem(), where only the child item's parent-relative
11018 position and transformation are kept.
11020 The addtoGroup() function reparents the target item to this item
11021 group, keeping the item's position and transformation intact
11022 relative to the scene. Visually, this means that items added via
11023 addToGroup() will remain completely unchanged as a result of this
11024 operation, regardless of the item or the group's current position
11025 or transformation; although the item's position and matrix are
11028 The removeFromGroup() function has similar semantics to
11029 setParentItem(); it reparents the item to the parent item of the
11030 item group. As with addToGroup(), the item's scene-relative
11031 position and transformation remain intact.
11033 \sa QGraphicsItem, {Graphics View Framework}
11036 class QGraphicsItemGroupPrivate : public QGraphicsItemPrivate
11039 QRectF itemsBoundingRect;
11043 Constructs a QGraphicsItemGroup. \a parent is passed to QGraphicsItem's
11046 \sa QGraphicsScene::addItem()
11048 QGraphicsItemGroup::QGraphicsItemGroup(QGraphicsItem *parent
11050 // obsolete argument
11051 , QGraphicsScene *scene
11054 : QGraphicsItem(*new QGraphicsItemGroupPrivate, parent, scene)
11056 setHandlesChildEvents(true);
11060 Destroys the QGraphicsItemGroup.
11062 QGraphicsItemGroup::~QGraphicsItemGroup()
11067 Adds the given \a item and item's child items to this item group.
11068 The item and child items will be reparented to this group, but its
11069 position and transformation relative to the scene will stay intact.
11071 \sa removeFromGroup(), QGraphicsScene::createItemGroup()
11073 void QGraphicsItemGroup::addToGroup(QGraphicsItem *item)
11075 Q_D(QGraphicsItemGroup);
11077 qWarning("QGraphicsItemGroup::addToGroup: cannot add null item");
11080 if (item == this) {
11081 qWarning("QGraphicsItemGroup::addToGroup: cannot add a group to itself");
11087 QTransform itemTransform = item->itemTransform(this, &ok);
11090 qWarning("QGraphicsItemGroup::addToGroup: could not find a valid transformation from item to group coordinates");
11094 QTransform newItemTransform(itemTransform);
11095 item->setPos(mapFromItem(item, 0, 0));
11096 item->setParentItem(this);
11098 // removing position from translation component of the new transform
11099 if (!item->pos().isNull())
11100 newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
11102 // removing additional transformations properties applied with itemTransform()
11103 QPointF origin = item->transformOriginPoint();
11105 QList<QGraphicsTransform*> transformList = item->transformations();
11106 for (int i = 0; i < transformList.size(); ++i)
11107 transformList.at(i)->applyTo(&m);
11108 newItemTransform *= m.toTransform().inverted();
11109 newItemTransform.translate(origin.x(), origin.y());
11110 newItemTransform.rotate(-item->rotation());
11111 newItemTransform.scale(1/item->scale(), 1/item->scale());
11112 newItemTransform.translate(-origin.x(), -origin.y());
11114 // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
11116 item->setTransform(newItemTransform);
11117 item->d_func()->setIsMemberOfGroup(true);
11118 prepareGeometryChange();
11119 d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
11124 Removes the specified \a item from this group. The item will be
11125 reparented to this group's parent item, or to 0 if this group has
11126 no parent. Its position and transformation relative to the scene
11129 \sa addToGroup(), QGraphicsScene::destroyItemGroup()
11131 void QGraphicsItemGroup::removeFromGroup(QGraphicsItem *item)
11133 Q_D(QGraphicsItemGroup);
11135 qWarning("QGraphicsItemGroup::removeFromGroup: cannot remove null item");
11139 QGraphicsItem *newParent = d_ptr->parent;
11143 QTransform itemTransform;
11145 itemTransform = item->itemTransform(newParent, &ok);
11147 itemTransform = item->sceneTransform();
11149 QPointF oldPos = item->mapToItem(newParent, 0, 0);
11150 item->setParentItem(newParent);
11151 item->setPos(oldPos);
11153 // removing position from translation component of the new transform
11154 if (!item->pos().isNull())
11155 itemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
11157 // removing additional transformations properties applied
11158 // with itemTransform() or sceneTransform()
11159 QPointF origin = item->transformOriginPoint();
11161 QList<QGraphicsTransform*> transformList = item->transformations();
11162 for (int i = 0; i < transformList.size(); ++i)
11163 transformList.at(i)->applyTo(&m);
11164 itemTransform *= m.toTransform().inverted();
11165 itemTransform.translate(origin.x(), origin.y());
11166 itemTransform.rotate(-item->rotation());
11167 itemTransform.scale(1 / item->scale(), 1 / item->scale());
11168 itemTransform.translate(-origin.x(), -origin.y());
11170 // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
11172 item->setTransform(itemTransform);
11173 item->d_func()->setIsMemberOfGroup(item->group() != 0);
11175 // ### Quite expensive. But removeFromGroup() isn't called very often.
11176 prepareGeometryChange();
11177 d->itemsBoundingRect = childrenBoundingRect();
11183 Returns the bounding rect of this group item, and all its children.
11185 QRectF QGraphicsItemGroup::boundingRect() const
11187 Q_D(const QGraphicsItemGroup);
11188 return d->itemsBoundingRect;
11194 void QGraphicsItemGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
11198 if (option->state & QStyle::State_Selected) {
11199 Q_D(QGraphicsItemGroup);
11200 painter->setBrush(Qt::NoBrush);
11201 painter->drawRect(d->itemsBoundingRect);
11208 bool QGraphicsItemGroup::isObscuredBy(const QGraphicsItem *item) const
11210 return QGraphicsItem::isObscuredBy(item);
11216 QPainterPath QGraphicsItemGroup::opaqueArea() const
11218 return QGraphicsItem::opaqueArea();
11224 int QGraphicsItemGroup::type() const
11229 #ifndef QT_NO_GRAPHICSEFFECT
11230 QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
11232 const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
11233 if (!info && deviceCoordinates) {
11234 // Device coordinates without info not yet supported.
11235 qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
11239 QRectF rect = item->boundingRect();
11240 if (!item->d_ptr->children.isEmpty())
11241 rect |= item->childrenBoundingRect();
11243 if (deviceCoordinates) {
11244 Q_ASSERT(info->painter);
11245 rect = info->painter->worldTransform().mapRect(rect);
11251 void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter)
11254 qWarning("QGraphicsEffectSource::draw: Can only begin as a result of QGraphicsEffect::draw");
11258 Q_ASSERT(item->d_ptr->scene);
11259 QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
11260 if (painter == info->painter) {
11261 scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
11262 info->widget, info->opacity, info->effectTransform, info->wasDirtySceneTransform,
11265 QTransform effectTransform = info->painter->worldTransform().inverted();
11266 effectTransform *= painter->worldTransform();
11267 scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
11268 info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
11273 // sourceRect must be in the given coordinate system
11274 QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
11276 QRectF effectRectF;
11281 if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
11283 QRectF deviceRect = system == Qt::DeviceCoordinates ? sourceRect : info->painter->worldTransform().mapRect(sourceRect);
11284 effectRectF = item->graphicsEffect()->boundingRectFor(deviceRect);
11286 *unpadded = (effectRectF.size() == sourceRect.size());
11287 if (info && system == Qt::LogicalCoordinates)
11288 effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
11290 // no choice but to send a logical coordinate bounding rect to boundingRectFor
11291 effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect);
11293 } else if (mode == QGraphicsEffect::PadToTransparentBorder) {
11294 // adjust by 1.5 to account for cosmetic pens
11295 effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
11297 effectRectF = sourceRect;
11302 return effectRectF.toAlignedRect();
11305 QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
11306 QGraphicsEffect::PixmapPadMode mode) const
11308 const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
11309 if (!info && deviceCoordinates) {
11310 // Device coordinates without info not yet supported.
11311 qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
11314 if (!item->d_ptr->scene)
11316 QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
11319 const QRectF sourceRect = boundingRect(system);
11320 QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded);
11323 *offset = effectRect.topLeft();
11325 bool untransformed = !deviceCoordinates
11326 || info->painter->worldTransform().type() <= QTransform::TxTranslate;
11327 if (untransformed && unpadded && isPixmap()) {
11329 *offset = boundingRect(system).topLeft().toPoint();
11330 return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
11333 if (effectRect.isEmpty())
11336 QPixmap pixmap(effectRect.size());
11337 pixmap.fill(Qt::transparent);
11338 QPainter pixmapPainter(&pixmap);
11339 pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing);
11341 QTransform effectTransform = QTransform::fromTranslate(-effectRect.x(), -effectRect.y());
11342 if (deviceCoordinates && info->effectTransform)
11343 effectTransform *= *info->effectTransform;
11346 // Logical coordinates without info.
11347 QTransform sceneTransform = item->sceneTransform();
11348 QTransform newEffectTransform = sceneTransform.inverted();
11349 newEffectTransform *= effectTransform;
11350 scened->draw(item, &pixmapPainter, 0, &sceneTransform, 0, 0, qreal(1.0),
11351 &newEffectTransform, false, true);
11352 } else if (deviceCoordinates) {
11353 // Device coordinates with info.
11354 scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
11355 info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
11358 // Item coordinates with info.
11359 QTransform newEffectTransform = info->transformPtr->inverted();
11360 newEffectTransform *= effectTransform;
11361 scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
11362 info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform,
11366 pixmapPainter.end();
11370 #endif //QT_NO_GRAPHICSEFFECT
11372 #ifndef QT_NO_DEBUG_STREAM
11373 QDebug operator<<(QDebug debug, QGraphicsItem *item)
11376 debug << "QGraphicsItem(0)";
11380 if (QGraphicsObject *o = item->toGraphicsObject())
11381 debug << o->metaObject()->className();
11383 debug << "QGraphicsItem";
11384 debug << "(this =" << (void*)item
11385 << ", parent =" << (void*)item->parentItem()
11386 << ", pos =" << item->pos()
11387 << ", z =" << item->zValue() << ", flags = "
11388 << item->flags() << ")";
11392 QDebug operator<<(QDebug debug, QGraphicsObject *item)
11395 debug << "QGraphicsObject(0)";
11399 debug.nospace() << item->metaObject()->className() << '(' << (void*)item;
11400 if (!item->objectName().isEmpty())
11401 debug << ", name = " << item->objectName();
11402 debug.nospace() << ", parent = " << ((void*)item->parentItem())
11403 << ", pos = " << item->pos()
11404 << ", z = " << item->zValue() << ", flags = "
11405 << item->flags() << ')';
11406 return debug.space();
11409 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change)
11411 const char *str = "UnknownChange";
11413 case QGraphicsItem::ItemChildAddedChange:
11414 str = "ItemChildAddedChange";
11416 case QGraphicsItem::ItemChildRemovedChange:
11417 str = "ItemChildRemovedChange";
11419 case QGraphicsItem::ItemCursorChange:
11420 str = "ItemCursorChange";
11422 case QGraphicsItem::ItemCursorHasChanged:
11423 str = "ItemCursorHasChanged";
11425 case QGraphicsItem::ItemEnabledChange:
11426 str = "ItemEnabledChange";
11428 case QGraphicsItem::ItemEnabledHasChanged:
11429 str = "ItemEnabledHasChanged";
11431 case QGraphicsItem::ItemFlagsChange:
11432 str = "ItemFlagsChange";
11434 case QGraphicsItem::ItemFlagsHaveChanged:
11435 str = "ItemFlagsHaveChanged";
11437 case QGraphicsItem::ItemMatrixChange:
11438 str = "ItemMatrixChange";
11440 case QGraphicsItem::ItemParentChange:
11441 str = "ItemParentChange";
11443 case QGraphicsItem::ItemParentHasChanged:
11444 str = "ItemParentHasChanged";
11446 case QGraphicsItem::ItemPositionChange:
11447 str = "ItemPositionChange";
11449 case QGraphicsItem::ItemPositionHasChanged:
11450 str = "ItemPositionHasChanged";
11452 case QGraphicsItem::ItemSceneChange:
11453 str = "ItemSceneChange";
11455 case QGraphicsItem::ItemSceneHasChanged:
11456 str = "ItemSceneHasChanged";
11458 case QGraphicsItem::ItemSelectedChange:
11459 str = "ItemSelectedChange";
11461 case QGraphicsItem::ItemSelectedHasChanged:
11462 str = "ItemSelectedHasChanged";
11464 case QGraphicsItem::ItemToolTipChange:
11465 str = "ItemToolTipChange";
11467 case QGraphicsItem::ItemToolTipHasChanged:
11468 str = "ItemToolTipHasChanged";
11470 case QGraphicsItem::ItemTransformChange:
11471 str = "ItemTransformChange";
11473 case QGraphicsItem::ItemTransformHasChanged:
11474 str = "ItemTransformHasChanged";
11476 case QGraphicsItem::ItemVisibleChange:
11477 str = "ItemVisibleChange";
11479 case QGraphicsItem::ItemVisibleHasChanged:
11480 str = "ItemVisibleHasChanged";
11482 case QGraphicsItem::ItemZValueChange:
11483 str = "ItemZValueChange";
11485 case QGraphicsItem::ItemZValueHasChanged:
11486 str = "ItemZValueHasChanged";
11488 case QGraphicsItem::ItemOpacityChange:
11489 str = "ItemOpacityChange";
11491 case QGraphicsItem::ItemOpacityHasChanged:
11492 str = "ItemOpacityHasChanged";
11494 case QGraphicsItem::ItemScenePositionHasChanged:
11495 str = "ItemScenePositionHasChanged";
11497 case QGraphicsItem::ItemRotationChange:
11498 str = "ItemRotationChange";
11500 case QGraphicsItem::ItemRotationHasChanged:
11501 str = "ItemRotationHasChanged";
11503 case QGraphicsItem::ItemScaleChange:
11504 str = "ItemScaleChange";
11506 case QGraphicsItem::ItemScaleHasChanged:
11507 str = "ItemScaleHasChanged";
11509 case QGraphicsItem::ItemTransformOriginPointChange:
11510 str = "ItemTransformOriginPointChange";
11512 case QGraphicsItem::ItemTransformOriginPointHasChanged:
11513 str = "ItemTransformOriginPointHasChanged";
11520 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
11522 const char *str = "UnknownFlag";
11524 case QGraphicsItem::ItemIsMovable:
11525 str = "ItemIsMovable";
11527 case QGraphicsItem::ItemIsSelectable:
11528 str = "ItemIsSelectable";
11530 case QGraphicsItem::ItemIsFocusable:
11531 str = "ItemIsFocusable";
11533 case QGraphicsItem::ItemClipsToShape:
11534 str = "ItemClipsToShape";
11536 case QGraphicsItem::ItemClipsChildrenToShape:
11537 str = "ItemClipsChildrenToShape";
11539 case QGraphicsItem::ItemIgnoresTransformations:
11540 str = "ItemIgnoresTransformations";
11542 case QGraphicsItem::ItemIgnoresParentOpacity:
11543 str = "ItemIgnoresParentOpacity";
11545 case QGraphicsItem::ItemDoesntPropagateOpacityToChildren:
11546 str = "ItemDoesntPropagateOpacityToChildren";
11548 case QGraphicsItem::ItemStacksBehindParent:
11549 str = "ItemStacksBehindParent";
11551 case QGraphicsItem::ItemUsesExtendedStyleOption:
11552 str = "ItemUsesExtendedStyleOption";
11554 case QGraphicsItem::ItemHasNoContents:
11555 str = "ItemHasNoContents";
11557 case QGraphicsItem::ItemSendsGeometryChanges:
11558 str = "ItemSendsGeometryChanges";
11560 case QGraphicsItem::ItemAcceptsInputMethod:
11561 str = "ItemAcceptsInputMethod";
11563 case QGraphicsItem::ItemNegativeZStacksBehindParent:
11564 str = "ItemNegativeZStacksBehindParent";
11566 case QGraphicsItem::ItemIsPanel:
11567 str = "ItemIsPanel";
11569 case QGraphicsItem::ItemIsFocusScope:
11570 str = "ItemIsFocusScope";
11572 case QGraphicsItem::ItemSendsScenePositionChanges:
11573 str = "ItemSendsScenePositionChanges";
11575 case QGraphicsItem::ItemStopsClickFocusPropagation:
11576 str = "ItemStopsClickFocusPropagation";
11578 case QGraphicsItem::ItemStopsFocusHandling:
11579 str = "ItemStopsFocusHandling";
11586 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags)
11590 for (int i = 0; i < 17; ++i) {
11591 if (flags & (1 << i)) {
11595 debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i)));
11606 #include "moc_qgraphicsitem.cpp"
11608 #endif // QT_NO_GRAPHICSVIEW