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 Make sure not to trigger any pure virtual function calls (e.g.,
1081 prepareGeometryChange) if the item is in its destructor, i.e.
1084 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant,
1085 const QVariant *thisPointerVariant)
1088 if (newParent == parent)
1092 static_cast<QGraphicsWidgetPrivate *>(this)->fixFocusChainBeforeReparenting((newParent &&
1093 newParent->isWidget()) ? static_cast<QGraphicsWidget *>(newParent) : 0,
1096 // Deliver the change to the index
1097 if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
1098 scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
1100 // Disable scene pos notifications for old ancestors
1101 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
1102 scene->d_func()->setScenePosItemEnabled(q, false);
1105 if (subFocusItem && parent) {
1106 // Make sure none of the old parents point to this guy.
1107 subFocusItem->d_ptr->clearSubFocus(parent);
1110 // We anticipate geometry changes. If the item is deleted, it will be
1111 // removed from the index at a later stage, and the whole scene will be
1114 q_ptr->prepareGeometryChange();
1117 // Remove from current parent
1118 parent->d_ptr->removeChild(q);
1119 if (thisPointerVariant)
1120 parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant);
1123 // Update toplevelitem list. If this item is being deleted, its parent
1124 // will be 0 but we don't want to register/unregister it in the TLI list.
1125 if (scene && !inDestructor) {
1126 if (parent && !newParent) {
1127 scene->d_func()->registerTopLevelItem(q);
1128 } else if (!parent && newParent) {
1129 scene->d_func()->unregisterTopLevelItem(q);
1133 // Ensure any last parent focus scope does not point to this item or any of
1135 QGraphicsItem *p = parent;
1136 QGraphicsItem *parentFocusScopeItem = 0;
1138 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
1139 // If this item's focus scope's focus scope item points
1140 // to this item or a descendent, then clear it.
1141 QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
1142 if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
1143 parentFocusScopeItem = fsi;
1144 p->d_ptr->focusScopeItem = 0;
1145 fsi->d_ptr->focusScopeItemChange(false);
1149 p = p->d_ptr->parent;
1152 // Update graphics effect optimization flag
1153 if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect))
1154 newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
1156 // Update focus scope item ptr in new scope.
1157 QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
1158 if (newFocusScopeItem && newParent) {
1159 QGraphicsItem *p = newParent;
1161 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
1162 if (subFocusItem && subFocusItem != q_ptr) {
1163 // Find the subFocusItem's topmost focus scope within the new parent's focusscope
1164 QGraphicsItem *ancestorScope = 0;
1165 QGraphicsItem *p2 = subFocusItem->d_ptr->parent;
1166 while (p2 && p2 != p) {
1167 if (p2->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
1169 if (p2->d_ptr->flags & QGraphicsItem::ItemIsPanel)
1173 p2 = p2->d_ptr->parent;
1176 newFocusScopeItem = ancestorScope;
1179 p->d_ptr->focusScopeItem = newFocusScopeItem;
1180 newFocusScopeItem->d_ptr->focusScopeItemChange(true);
1181 // Ensure the new item is no longer the subFocusItem. The
1182 // only way to set focus on a child of a focus scope is
1183 // by setting focus on the scope itself.
1184 if (subFocusItem && !p->focusItem())
1185 subFocusItem->d_ptr->clearSubFocus();
1188 p = p->d_ptr->parent;
1193 invalidateDepthRecursively();
1195 if ((parent = newParent)) {
1196 if (parent->d_func()->scene && parent->d_func()->scene != scene) {
1197 // Move this item to its new parent's scene
1198 parent->d_func()->scene->addItem(q);
1199 } else if (!parent->d_func()->scene && scene) {
1200 // Remove this item from its former scene
1201 scene->removeItem(q);
1204 parent->d_ptr->addChild(q);
1205 if (thisPointerVariant)
1206 parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant);
1208 // Re-enable scene pos notifications for new ancestors
1209 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
1210 scene->d_func()->setScenePosItemEnabled(q, true);
1213 // Propagate dirty flags to the new parent
1214 markParentDirty(/*updateBoundingRect=*/true);
1216 // Inherit ancestor flags from the new parent.
1217 updateAncestorFlags();
1219 // Update item visible / enabled.
1220 if (parent->d_ptr->visible != visible) {
1221 if (!parent->d_ptr->visible || !explicitlyHidden)
1222 setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false);
1224 if (parent->isEnabled() != enabled) {
1225 if (!parent->d_ptr->enabled || !explicitlyDisabled)
1226 setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false);
1229 // Auto-activate if visible and the parent is active.
1230 if (visible && parent->isActive())
1233 // Inherit ancestor flags from the new parent.
1234 updateAncestorFlags();
1236 if (!inDestructor) {
1237 // Update item visible / enabled.
1238 if (!visible && !explicitlyHidden)
1239 setVisibleHelper(true, /* explicit = */ false);
1240 if (!enabled && !explicitlyDisabled)
1241 setEnabledHelper(true, /* explicit = */ false);
1245 dirtySceneTransform = 1;
1246 if (!inDestructor && (transformData || (newParent && newParent->d_ptr->transformData)))
1249 // Restore the sub focus chain.
1251 subFocusItem->d_ptr->setSubFocus(newParent);
1252 if (parent && parent->isActive())
1253 subFocusItem->setFocus();
1256 // Deliver post-change notification
1257 if (newParentVariant)
1258 q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant);
1261 emit static_cast<QGraphicsObject *>(q)->parentChanged();
1267 Returns the bounding rect of this item's children (excluding itself).
1269 void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem)
1273 QRectF childrenRect;
1274 QRectF *result = rect;
1275 rect = &childrenRect;
1276 const bool setTopMostEffectItem = !topMostEffectItem;
1278 for (int i = 0; i < children.size(); ++i) {
1279 QGraphicsItem *child = children.at(i);
1280 QGraphicsItemPrivate *childd = child->d_ptr.data();
1281 if (setTopMostEffectItem)
1282 topMostEffectItem = child;
1283 bool hasPos = !childd->pos.isNull();
1284 if (hasPos || childd->transformData) {
1286 QTransform matrix = childd->transformToParent();
1289 *rect |= matrix.mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
1290 if (!childd->children.isEmpty())
1291 childd->childrenBoundingRectHelper(&matrix, rect, topMostEffectItem);
1294 *rect |= x->mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
1296 *rect |= child->d_ptr->effectiveBoundingRect(topMostEffectItem);
1297 if (!childd->children.isEmpty())
1298 childd->childrenBoundingRectHelper(x, rect, topMostEffectItem);
1302 if (flags & QGraphicsItem::ItemClipsChildrenToShape){
1304 *rect &= x->mapRect(q->boundingRect());
1306 *rect &= q->boundingRect();
1312 void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
1313 const QRegion &exposedRegion, bool allItems) const
1316 Q_Q(const QGraphicsItem);
1318 // Initialize standard QStyleOption values.
1319 const QRectF brect = q->boundingRect();
1320 option->state = QStyle::State_None;
1321 option->rect = brect.toRect();
1322 option->levelOfDetail = 1;
1323 option->exposedRect = brect;
1325 option->state |= QStyle::State_Selected;
1327 option->state |= QStyle::State_Enabled;
1329 option->state |= QStyle::State_HasFocus;
1331 if (scene->d_func()->hoverItems.contains(q_ptr))
1332 option->state |= QStyle::State_MouseOver;
1333 if (q == scene->mouseGrabberItem())
1334 option->state |= QStyle::State_Sunken;
1337 if (!(flags & QGraphicsItem::ItemUsesExtendedStyleOption))
1340 // Initialize QStyleOptionGraphicsItem specific values (matrix, exposedRect).
1341 option->matrix = worldTransform.toAffine(); //### discards perspective
1344 // Determine the item's exposed area
1345 option->exposedRect = QRectF();
1346 const QTransform reverseMap = worldTransform.inverted();
1347 const QVector<QRect> exposedRects(exposedRegion.rects());
1348 for (int i = 0; i < exposedRects.size(); ++i) {
1349 option->exposedRect |= reverseMap.mapRect(QRectF(exposedRects.at(i)));
1350 if (option->exposedRect.contains(brect))
1353 option->exposedRect &= brect;
1360 Empty all cached pixmaps from the pixmap cache.
1362 void QGraphicsItemCache::purge()
1364 QPixmapCache::remove(key);
1365 key = QPixmapCache::Key();
1366 QMutableHashIterator<QPaintDevice *, DeviceData> it(deviceData);
1367 while (it.hasNext()) {
1368 DeviceData &data = it.next().value();
1369 QPixmapCache::remove(data.key);
1370 data.cacheIndent = QPoint();
1378 Constructs a QGraphicsItem with the given \a parent item.
1379 It does not modify the parent object returned by QObject::parent().
1381 If \a parent is 0, you can add the item to a scene by calling
1382 QGraphicsScene::addItem(). The item will then become a top-level item.
1384 \sa QGraphicsScene::addItem(), setParentItem()
1386 QGraphicsItem::QGraphicsItem(QGraphicsItem *parent
1388 // obsolete argument
1389 , QGraphicsScene *scene
1392 : d_ptr(new QGraphicsItemPrivate)
1394 d_ptr->q_ptr = this;
1395 setParentItem(parent);
1397 if (scene && parent && parent->scene() != scene) {
1398 qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
1399 " different from parent's scene (%p)",
1400 scene, parent->scene());
1403 if (scene && !parent)
1404 scene->addItem(this);
1410 QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent,
1411 QGraphicsScene *scene)
1414 d_ptr->q_ptr = this;
1415 setParentItem(parent);
1417 if (scene && parent && parent->scene() != scene) {
1418 qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
1419 " different from parent's scene (%p)",
1420 scene, parent->scene());
1423 if (scene && !parent)
1424 scene->addItem(this);
1428 Destroys the QGraphicsItem and all its children. If this item is currently
1429 associated with a scene, the item will be removed from the scene before it
1432 \note It is more efficient to remove the item from the QGraphicsScene before
1433 destroying the item.
1435 QGraphicsItem::~QGraphicsItem()
1437 if (d_ptr->isObject) {
1438 QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
1439 QObjectPrivate *p = QObjectPrivate::get(o);
1440 p->wasDeleted = true;
1441 if (p->declarativeData) {
1442 QAbstractDeclarativeData::destroyed(p->declarativeData, o);
1443 p->declarativeData = 0;
1447 d_ptr->inDestructor = 1;
1448 d_ptr->removeExtraItemCache();
1450 #ifndef QT_NO_GESTURES
1451 if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) {
1452 QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
1453 if (QGestureManager *manager = QGestureManager::instance()) {
1454 foreach (Qt::GestureType type, d_ptr->gestureContext.keys())
1455 manager->cleanupCachedGestures(o, type);
1462 // Update focus scope item ptr.
1463 QGraphicsItem *p = d_ptr->parent;
1465 if (p->flags() & ItemIsFocusScope) {
1466 if (p->d_ptr->focusScopeItem == this)
1467 p->d_ptr->focusScopeItem = 0;
1470 p = p->d_ptr->parent;
1473 if (!d_ptr->children.isEmpty()) {
1474 while (!d_ptr->children.isEmpty())
1475 delete d_ptr->children.first();
1476 Q_ASSERT(d_ptr->children.isEmpty());
1480 d_ptr->scene->d_func()->removeItemHelper(this);
1482 d_ptr->resetFocusProxy();
1486 #ifndef QT_NO_GRAPHICSEFFECT
1487 delete d_ptr->graphicsEffect;
1488 #endif //QT_NO_GRAPHICSEFFECT
1489 if (d_ptr->transformData) {
1490 for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) {
1491 QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i);
1492 static_cast<QGraphicsTransformPrivate *>(t->d_ptr.data())->item = 0;
1496 delete d_ptr->transformData;
1498 if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore())
1499 dataStore->data.remove(this);
1503 Returns the current scene for the item, or 0 if the item is not stored in
1506 To add or move an item to a scene, call QGraphicsScene::addItem().
1508 QGraphicsScene *QGraphicsItem::scene() const
1510 return d_ptr->scene;
1514 Returns a pointer to this item's item group, or 0 if this item is not
1517 \sa QGraphicsItemGroup, QGraphicsScene::createItemGroup()
1519 QGraphicsItemGroup *QGraphicsItem::group() const
1521 if (!d_ptr->isMemberOfGroup)
1523 QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
1524 while ((parent = parent->d_ptr->parent)) {
1525 if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(parent))
1528 // Unreachable; if d_ptr->isMemberOfGroup is != 0, then one parent of this
1529 // item is a group item.
1534 Adds this item to the item group \a group. If \a group is 0, this item is
1535 removed from any current group and added as a child of the previous
1538 \sa group(), QGraphicsScene::createItemGroup()
1540 void QGraphicsItem::setGroup(QGraphicsItemGroup *group)
1543 if (QGraphicsItemGroup *group = this->group())
1544 group->removeFromGroup(this);
1546 group->addToGroup(this);
1551 Returns a pointer to this item's parent item. If this item does not have a
1552 parent, 0 is returned.
1554 \sa setParentItem(), childItems()
1556 QGraphicsItem *QGraphicsItem::parentItem() const
1558 return d_ptr->parent;
1562 Returns this item's top-level item. The top-level item is the item's
1563 topmost ancestor item whose parent is 0. If an item has no parent, its own
1564 pointer is returned (i.e., a top-level item is its own top-level item).
1568 QGraphicsItem *QGraphicsItem::topLevelItem() const
1570 QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
1571 while (QGraphicsItem *grandPa = parent->parentItem())
1579 Returns a pointer to the item's parent, cast to a QGraphicsObject. returns 0 if the parent item
1580 is not a QGraphicsObject.
1582 \sa parentItem(), childItems()
1584 QGraphicsObject *QGraphicsItem::parentObject() const
1586 QGraphicsItem *p = d_ptr->parent;
1587 return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : 0;
1593 Returns a pointer to the item's parent widget. The item's parent widget is
1594 the closest parent item that is a widget.
1596 \sa parentItem(), childItems()
1598 QGraphicsWidget *QGraphicsItem::parentWidget() const
1600 QGraphicsItem *p = parentItem();
1601 while (p && !p->isWidget())
1602 p = p->parentItem();
1603 return (p && p->isWidget()) ? static_cast<QGraphicsWidget *>(p) : 0;
1609 Returns a pointer to the item's top level widget (i.e., the item's
1610 ancestor whose parent is 0, or whose parent is not a widget), or 0 if this
1611 item does not have a top level widget. If the item is its own top level
1612 widget, this function returns a pointer to the item itself.
1614 QGraphicsWidget *QGraphicsItem::topLevelWidget() const
1616 if (const QGraphicsWidget *p = parentWidget())
1617 return p->topLevelWidget();
1618 return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : 0;
1624 Returns the item's window, or 0 if this item does not have a window. If
1625 the item is a window, it will return itself. Otherwise it will return the
1626 closest ancestor that is a window.
1628 \sa QGraphicsWidget::isWindow()
1630 QGraphicsWidget *QGraphicsItem::window() const
1632 QGraphicsItem *p = panel();
1633 if (p && p->isWindow())
1634 return static_cast<QGraphicsWidget *>(p);
1641 Returns the item's panel, or 0 if this item does not have a panel. If the
1642 item is a panel, it will return itself. Otherwise it will return the
1643 closest ancestor that is a panel.
1645 \sa isPanel(), ItemIsPanel
1647 QGraphicsItem *QGraphicsItem::panel() const
1649 if (d_ptr->flags & ItemIsPanel)
1650 return const_cast<QGraphicsItem *>(this);
1651 return d_ptr->parent ? d_ptr->parent->panel() : 0;
1657 Return the graphics item cast to a QGraphicsObject, if the class is actually a
1658 graphics object, 0 otherwise.
1660 QGraphicsObject *QGraphicsItem::toGraphicsObject()
1662 return d_ptr->isObject ? static_cast<QGraphicsObject *>(this) : 0;
1668 Return the graphics item cast to a QGraphicsObject, if the class is actually a
1669 graphics object, 0 otherwise.
1671 const QGraphicsObject *QGraphicsItem::toGraphicsObject() const
1673 return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0;
1677 Sets this item's parent item to \a newParent. If this item already
1678 has a parent, it is first removed from the previous parent. If \a
1679 newParent is 0, this item will become a top-level item.
1681 Note that this implicitly adds this graphics item to the scene of
1682 the parent. You should not \l{QGraphicsScene::addItem()}{add} the
1683 item to the scene yourself.
1685 Calling this function on an item that is an ancestor of \a newParent
1686 have undefined behaviour.
1688 \sa parentItem(), childItems()
1690 void QGraphicsItem::setParentItem(QGraphicsItem *newParent)
1692 if (newParent == this) {
1693 qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
1696 if (newParent == d_ptr->parent)
1699 const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange,
1700 QVariant::fromValue<QGraphicsItem *>(newParent)));
1701 newParent = qvariant_cast<QGraphicsItem *>(newParentVariant);
1702 if (newParent == d_ptr->parent)
1705 const QVariant thisPointerVariant(QVariant::fromValue<QGraphicsItem *>(this));
1706 d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant);
1712 Use childItems() instead.
1716 QList<QGraphicsItem *> QGraphicsItem::children() const
1718 return childItems();
1724 Returns a list of this item's children.
1726 The items are sorted by stacking order. This takes into account both the
1727 items' insertion order and their Z-values.
1729 \sa setParentItem(), zValue(), {QGraphicsItem#Sorting}{Sorting}
1731 QList<QGraphicsItem *> QGraphicsItem::childItems() const
1733 const_cast<QGraphicsItem *>(this)->d_ptr->ensureSortedChildren();
1734 return d_ptr->children;
1739 Returns true if this item is a widget (i.e., QGraphicsWidget); otherwise,
1742 bool QGraphicsItem::isWidget() const
1744 return d_ptr->isWidget;
1749 Returns true if the item is a QGraphicsWidget window, otherwise returns
1752 \sa QGraphicsWidget::windowFlags()
1754 bool QGraphicsItem::isWindow() const
1756 return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
1761 Returns true if the item is a panel; otherwise returns false.
1763 \sa QGraphicsItem::panel(), ItemIsPanel
1765 bool QGraphicsItem::isPanel() const
1767 return d_ptr->flags & ItemIsPanel;
1771 Returns this item's flags. The flags describe what configurable features
1772 of the item are enabled and not. For example, if the flags include
1773 ItemIsFocusable, the item can accept input focus.
1775 By default, no flags are enabled.
1777 \sa setFlags(), setFlag()
1779 QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const
1781 return GraphicsItemFlags(d_ptr->flags);
1785 If \a enabled is true, the item flag \a flag is enabled; otherwise, it is
1788 \sa flags(), setFlags()
1790 void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled)
1793 setFlags(GraphicsItemFlags(d_ptr->flags) | flag);
1795 setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag);
1801 Sets the flag \a flag on \a item and all its children, to \a enabled.
1803 static void _q_qgraphicsItemSetFlag(QGraphicsItem *item, QGraphicsItem::GraphicsItemFlag flag,
1806 if (item->flags() & flag) {
1807 // If this item already has the correct flag set, we don't have to
1811 item->setFlag(flag, enabled);
1812 foreach (QGraphicsItem *child, item->children())
1813 _q_qgraphicsItemSetFlag(child, flag, enabled);
1817 Sets the item flags to \a flags. All flags in \a flags are enabled; all
1818 flags not in \a flags are disabled.
1820 If the item had focus and \a flags does not enable ItemIsFocusable, the
1821 item loses focus as a result of calling this function. Similarly, if the
1822 item was selected, and \a flags does not enabled ItemIsSelectable, the
1823 item is automatically unselected.
1825 By default, no flags are enabled. (QGraphicsWidget enables the
1826 ItemSendsGeometryChanges flag by default in order to track position
1829 \sa flags(), setFlag()
1831 void QGraphicsItem::setFlags(GraphicsItemFlags flags)
1833 // Notify change and check for adjustment.
1834 if (quint32(d_ptr->flags) == quint32(flags))
1836 flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
1837 if (quint32(d_ptr->flags) == quint32(flags))
1839 if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
1840 d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags);
1842 // Flags that alter the geometry of the item (or its children).
1843 const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
1844 bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
1846 d_ptr->updatePaintedViewBoundingRects(/*children=*/true);
1848 // Keep the old flags to compare the diff.
1849 GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
1852 d_ptr->flags = flags;
1854 if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
1855 // Clear focus on the item if it has focus when the focusable flag
1860 if (!(d_ptr->flags & ItemIsSelectable) && isSelected()) {
1861 // Unselect the item if it is selected when the selectable flag is
1866 if ((flags & ItemClipsChildrenToShape) != (oldFlags & ItemClipsChildrenToShape)) {
1867 // Item children clipping changes. Propagate the ancestor flag to
1869 d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
1870 // The childrenBoundingRect is clipped to the boundingRect in case of ItemClipsChildrenToShape,
1871 // which means we have to invalidate the cached childrenBoundingRect whenever this flag changes.
1872 d_ptr->dirtyChildrenBoundingRect = 1;
1873 d_ptr->markParentDirty(true);
1876 if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
1877 // Item children clipping changes. Propagate the ancestor flag to
1879 d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
1882 if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
1883 // NB! We change the flags directly here, so we must also update d_ptr->flags.
1884 // Note that this has do be done before the ItemStacksBehindParent check
1885 // below; otherwise we will loose the change.
1887 // Update stack-behind.
1888 if (d_ptr->z < qreal(0.0))
1889 flags |= ItemStacksBehindParent;
1891 flags &= ~ItemStacksBehindParent;
1892 d_ptr->flags = flags;
1895 if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
1896 // NB! This check has to come after the ItemNegativeZStacksBehindParent
1897 // check above. Be careful.
1899 // Ensure child item sorting is up to date when toggling this flag.
1901 d_ptr->parent->d_ptr->needSortChildren = 1;
1902 else if (d_ptr->scene)
1903 d_ptr->scene->d_func()->needSortTopLevelItems = 1;
1906 if ((flags & ItemAcceptsInputMethod) != (oldFlags & ItemAcceptsInputMethod)) {
1907 // Update input method sensitivity in any views.
1909 d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
1913 if ((d_ptr->panelModality != NonModal)
1915 && (flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
1916 // update the panel's modal state
1917 if (flags & ItemIsPanel)
1918 d_ptr->scene->d_func()->enterModal(this);
1920 d_ptr->scene->d_func()->leaveModal(this);
1924 if ((flags & ItemSendsScenePositionChanges) != (oldFlags & ItemSendsScenePositionChanges)) {
1925 if (flags & ItemSendsScenePositionChanges)
1926 d_ptr->scene->d_func()->registerScenePosItem(this);
1928 d_ptr->scene->d_func()->unregisterScenePosItem(this);
1930 d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
1934 itemChange(ItemFlagsHaveChanged, quint32(flags));
1939 Returns the cache mode for this item. The default mode is NoCache (i.e.,
1940 cache is disabled and all painting is immediate).
1944 QGraphicsItem::CacheMode QGraphicsItem::cacheMode() const
1946 return QGraphicsItem::CacheMode(d_ptr->cacheMode);
1951 Sets the item's cache mode to \a mode.
1953 The optional \a logicalCacheSize argument is used only by
1954 ItemCoordinateCache mode, and describes the resolution of the cache
1955 buffer; if \a logicalCacheSize is (100, 100), QGraphicsItem will fit the
1956 item into 100x100 pixels in graphics memory, regardless of the logical
1957 size of the item itself. By default QGraphicsItem uses the size of
1958 boundingRect(). For all other cache modes than ItemCoordinateCache, \a
1959 logicalCacheSize is ignored.
1961 Caching can speed up rendering if your item spends a significant time
1962 redrawing itself. In some cases the cache can also slow down rendering, in
1963 particular when the item spends less time redrawing than QGraphicsItem
1964 spends redrawing from the cache. When enabled, the item's paint() function
1965 will be called only once for each call to update(); for any subsequent
1966 repaint requests, the Graphics View framework will redraw from the
1967 cache. This approach works particularly well with QGLWidget, which stores
1968 all the cache as OpenGL textures.
1970 Be aware that QPixmapCache's cache limit may need to be changed to obtain
1971 optimal performance.
1973 You can read more about the different cache modes in the CacheMode
1976 \sa CacheMode, QPixmapCache::setCacheLimit()
1978 void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize)
1980 CacheMode lastMode = CacheMode(d_ptr->cacheMode);
1981 d_ptr->cacheMode = mode;
1982 bool noVisualChange = (mode == NoCache && lastMode == NoCache)
1983 || (mode == NoCache && lastMode == DeviceCoordinateCache)
1984 || (mode == DeviceCoordinateCache && lastMode == NoCache)
1985 || (mode == DeviceCoordinateCache && lastMode == DeviceCoordinateCache);
1986 if (mode == NoCache) {
1987 d_ptr->removeExtraItemCache();
1989 QGraphicsItemCache *cache = d_ptr->extraItemCache();
1994 if (mode == ItemCoordinateCache) {
1995 if (lastMode == mode && cache->fixedSize == logicalCacheSize)
1996 noVisualChange = true;
1997 cache->fixedSize = logicalCacheSize;
2000 if (!noVisualChange)
2007 Returns the modality for this item.
2009 QGraphicsItem::PanelModality QGraphicsItem::panelModality() const
2011 return d_ptr->panelModality;
2017 Sets the modality for this item to \a panelModality.
2019 Changing the modality of a visible item takes effect immediately.
2021 void QGraphicsItem::setPanelModality(PanelModality panelModality)
2023 if (d_ptr->panelModality == panelModality)
2026 PanelModality previousModality = d_ptr->panelModality;
2027 bool enterLeaveModal = (isPanel() && d_ptr->scene && isVisible());
2028 if (enterLeaveModal && panelModality == NonModal)
2029 d_ptr->scene->d_func()->leaveModal(this);
2030 d_ptr->panelModality = panelModality;
2031 if (enterLeaveModal && d_ptr->panelModality != NonModal)
2032 d_ptr->scene->d_func()->enterModal(this, previousModality);
2038 Returns true if this item is blocked by a modal panel, false otherwise. If \a blockingPanel is
2039 non-zero, \a blockingPanel will be set to the modal panel that is blocking this item. If this
2040 item is not blocked, \a blockingPanel will not be set by this function.
2042 This function always returns false for items not in a scene.
2044 \sa panelModality(), setPanelModality(), PanelModality
2046 bool QGraphicsItem::isBlockedByModalPanel(QGraphicsItem **blockingPanel) const
2052 QGraphicsItem *dummy = 0;
2054 blockingPanel = &dummy;
2056 QGraphicsScenePrivate *scene_d = d_ptr->scene->d_func();
2057 if (scene_d->modalPanels.isEmpty())
2061 if (!scene_d->popupWidgets.isEmpty() && scene_d->popupWidgets.first() == this)
2064 for (int i = 0; i < scene_d->modalPanels.count(); ++i) {
2065 QGraphicsItem *modalPanel = scene_d->modalPanels.at(i);
2066 if (modalPanel->panelModality() == QGraphicsItem::SceneModal) {
2067 // Scene modal panels block all non-descendents.
2068 if (modalPanel != this && !modalPanel->isAncestorOf(this)) {
2069 *blockingPanel = modalPanel;
2073 // Window modal panels block ancestors and siblings/cousins.
2074 if (modalPanel != this
2075 && !modalPanel->isAncestorOf(this)
2076 && commonAncestorItem(modalPanel)) {
2077 *blockingPanel = modalPanel;
2085 #ifndef QT_NO_TOOLTIP
2087 Returns the item's tool tip, or an empty QString if no tool tip has been
2090 \sa setToolTip(), QToolTip
2092 QString QGraphicsItem::toolTip() const
2094 return d_ptr->extra(QGraphicsItemPrivate::ExtraToolTip).toString();
2098 Sets the item's tool tip to \a toolTip. If \a toolTip is empty, the item's
2099 tool tip is cleared.
2101 \sa toolTip(), QToolTip
2103 void QGraphicsItem::setToolTip(const QString &toolTip)
2105 const QVariant toolTipVariant(itemChange(ItemToolTipChange, toolTip));
2106 d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTipVariant.toString());
2107 itemChange(ItemToolTipHasChanged, toolTipVariant);
2109 #endif // QT_NO_TOOLTIP
2111 #ifndef QT_NO_CURSOR
2113 Returns the current cursor shape for the item. The mouse cursor
2114 will assume this shape when it's over this item. See the \link
2115 Qt::CursorShape list of predefined cursor objects\endlink for a
2116 range of useful shapes.
2118 An editor item might want to use an I-beam cursor:
2120 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 2
2122 If no cursor has been set, the cursor of the item beneath is used.
2124 \sa setCursor(), hasCursor(), unsetCursor(), QWidget::cursor,
2125 QApplication::overrideCursor()
2127 QCursor QGraphicsItem::cursor() const
2129 return qvariant_cast<QCursor>(d_ptr->extra(QGraphicsItemPrivate::ExtraCursor));
2133 Sets the current cursor shape for the item to \a cursor. The mouse cursor
2134 will assume this shape when it's over this item. See the \link
2135 Qt::CursorShape list of predefined cursor objects\endlink for a range of
2138 An editor item might want to use an I-beam cursor:
2140 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 3
2142 If no cursor has been set, the cursor of the item beneath is used.
2144 \sa cursor(), hasCursor(), unsetCursor(), QWidget::cursor,
2145 QApplication::overrideCursor()
2147 void QGraphicsItem::setCursor(const QCursor &cursor)
2149 const QVariant cursorVariant(itemChange(ItemCursorChange, QVariant::fromValue<QCursor>(cursor)));
2150 d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qvariant_cast<QCursor>(cursorVariant));
2151 d_ptr->hasCursor = 1;
2153 d_ptr->scene->d_func()->allItemsUseDefaultCursor = false;
2154 foreach (QGraphicsView *view, d_ptr->scene->views()) {
2155 view->viewport()->setMouseTracking(true);
2156 // Note: Some of this logic is duplicated in QGraphicsView's mouse events.
2157 if (view->underMouse()) {
2158 foreach (QGraphicsItem *itemUnderCursor, view->items(view->mapFromGlobal(QCursor::pos()))) {
2159 if (itemUnderCursor->hasCursor()) {
2160 QMetaObject::invokeMethod(view, "_q_setViewportCursor",
2161 Q_ARG(QCursor, itemUnderCursor->cursor()));
2169 itemChange(ItemCursorHasChanged, cursorVariant);
2173 Returns true if this item has a cursor set; otherwise, false is returned.
2175 By default, items don't have any cursor set. cursor() will return a
2176 standard pointing arrow cursor.
2180 bool QGraphicsItem::hasCursor() const
2182 return d_ptr->hasCursor;
2186 Clears the cursor from this item.
2188 \sa hasCursor(), setCursor()
2190 void QGraphicsItem::unsetCursor()
2192 d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraCursor);
2193 d_ptr->hasCursor = 0;
2195 foreach (QGraphicsView *view, d_ptr->scene->views()) {
2196 if (view->underMouse() && view->itemAt(view->mapFromGlobal(QCursor::pos())) == this) {
2197 QMetaObject::invokeMethod(view, "_q_unsetViewportCursor");
2204 #endif // QT_NO_CURSOR
2207 Returns true if the item is visible; otherwise, false is returned.
2209 Note that the item's general visibility is unrelated to whether or not it
2210 is actually being visualized by a QGraphicsView.
2214 bool QGraphicsItem::isVisible() const
2216 return d_ptr->visible;
2221 Returns true if the item is visible to \a parent; otherwise, false is
2222 returned. \a parent can be 0, in which case this function will return
2223 whether the item is visible to the scene or not.
2225 An item may not be visible to its ancestors even if isVisible() is true. It
2226 may also be visible to its ancestors even if isVisible() is false. If
2227 any ancestor is hidden, the item itself will be implicitly hidden, in which
2228 case this function will return false.
2230 \sa isVisible(), setVisible()
2232 bool QGraphicsItem::isVisibleTo(const QGraphicsItem *parent) const
2234 const QGraphicsItem *p = this;
2235 if (d_ptr->explicitlyHidden)
2240 if (p->d_ptr->explicitlyHidden)
2242 } while ((p = p->d_ptr->parent));
2249 Sets this item's visibility to \a newVisible. If \a explicitly is true,
2250 this item will be "explicitly" \a newVisible; otherwise, it.. will not be.
2252 void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bool update)
2256 // Update explicit bit.
2258 explicitlyHidden = newVisible ? 0 : 1;
2260 // Check if there's nothing to do.
2261 if (visible == quint32(newVisible))
2264 // Don't show child if parent is not visible
2265 if (parent && newVisible && !parent->d_ptr->visible)
2268 // Modify the property.
2269 const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange,
2270 quint32(newVisible)));
2271 newVisible = newVisibleVariant.toBool();
2272 if (visible == quint32(newVisible))
2274 visible = newVisible;
2276 // Schedule redrawing
2278 QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
2282 #ifndef QT_NO_GRAPHICSEFFECT
2283 invalidateParentGraphicsEffectsRecursively();
2284 #endif //QT_NO_GRAPHICSEFFECT
2285 scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
2289 // Certain properties are dropped as an item becomes invisible.
2290 bool hasFocus = q_ptr->hasFocus();
2293 if (scene->d_func()->mouseGrabberItems.contains(q))
2295 if (scene->d_func()->keyboardGrabberItems.contains(q))
2296 q->ungrabKeyboard();
2297 if (q->isPanel() && panelModality != QGraphicsItem::NonModal)
2298 scene->d_func()->leaveModal(q_ptr);
2300 if (hasFocus && scene) {
2301 // Hiding the closest non-panel ancestor of the focus item
2302 QGraphicsItem *focusItem = scene->focusItem();
2304 if (isWidget && !focusItem->isPanel()) {
2306 if (focusItem == q_ptr) {
2307 clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
2310 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
2313 clearFocusHelper(/* giveFocusToParent = */ false);
2315 if (q_ptr->isSelected())
2316 q_ptr->setSelected(false);
2318 geometryChanged = 1;
2319 paintedViewBoundingRectsNeedRepaint = 1;
2322 QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
2323 if (widget->windowType() == Qt::Popup)
2324 scene->d_func()->addPopup(widget);
2326 if (q->isPanel() && panelModality != QGraphicsItem::NonModal) {
2327 scene->d_func()->enterModal(q_ptr);
2332 // Update children with explicitly = false.
2333 const bool updateChildren = update && !(flags & QGraphicsItem::ItemClipsChildrenToShape);
2334 foreach (QGraphicsItem *child, children) {
2335 if (!newVisible || !child->d_ptr->explicitlyHidden)
2336 child->d_ptr->setVisibleHelper(newVisible, false, updateChildren);
2339 // Update activation
2340 if (scene && q->isPanel()) {
2342 if (parent && parent->isActive())
2346 scene->setActivePanel(parent);
2354 QGraphicsItem *p = parent;
2357 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
2358 QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
2359 if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
2361 while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
2362 fsi = fsi->d_ptr->focusScopeItem;
2363 fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
2364 /* focusFromHide = */ false);
2368 p = p->d_ptr->parent;
2371 QGraphicsItem *fi = subFocusItem;
2372 if (fi && fi != scene->focusItem()) {
2373 scene->setFocusItem(fi);
2374 } else if (flags & QGraphicsItem::ItemIsFocusScope &&
2375 !scene->focusItem() &&
2376 q->isAncestorOf(scene->d_func()->lastFocusItem)) {
2383 QGraphicsItem *p = parent;
2385 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
2386 if (p->d_ptr->visible) {
2387 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
2388 /* focusFromHide = */ true);
2392 p = p->d_ptr->parent;
2398 // Deliver post-change notification.
2399 q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, newVisibleVariant);
2402 emit static_cast<QGraphicsObject *>(q_ptr)->visibleChanged();
2406 If \a visible is true, the item is made visible. Otherwise, the item is
2407 made invisible. Invisible items are not painted, nor do they receive any
2408 events. In particular, mouse events pass right through invisible items,
2409 and are delivered to any item that may be behind. Invisible items are also
2410 unselectable, they cannot take input focus, and are not detected by
2411 QGraphicsScene's item location functions.
2413 If an item becomes invisible while grabbing the mouse, (i.e., while it is
2414 receiving mouse events,) it will automatically lose the mouse grab, and
2415 the grab is not regained by making the item visible again; it must receive
2416 a new mouse press to regain the mouse grab.
2418 Similarly, an invisible item cannot have focus, so if the item has focus
2419 when it becomes invisible, it will lose focus, and the focus is not
2420 regained by simply making the item visible again.
2422 If you hide a parent item, all its children will also be hidden. If you
2423 show a parent item, all children will be shown, unless they have been
2424 explicitly hidden (i.e., if you call setVisible(false) on a child, it will
2425 not be reshown even if its parent is hidden, and then shown again).
2427 Items are visible by default; it is unnecessary to call
2428 setVisible() on a new item.
2430 \sa isVisible(), show(), hide()
2432 void QGraphicsItem::setVisible(bool visible)
2434 d_ptr->setVisibleHelper(visible, /* explicit = */ true);
2438 \fn void QGraphicsItem::hide()
2440 Hides the item. (Items are visible by default.)
2442 This convenience function is equivalent to calling \c setVisible(false).
2444 \sa show(), setVisible()
2448 \fn void QGraphicsItem::show()
2450 Shows the item. (Items are visible by default.)
2452 This convenience function is equivalent to calling \c setVisible(true).
2454 \sa hide(), setVisible()
2458 Returns true if the item is enabled; otherwise, false is returned.
2462 bool QGraphicsItem::isEnabled() const
2464 return d_ptr->enabled;
2470 Sets this item's visibility to \a newEnabled. If \a explicitly is true,
2471 this item will be "explicitly" \a newEnabled; otherwise, it.. will not be.
2473 void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bool update)
2475 // Update explicit bit.
2477 explicitlyDisabled = newEnabled ? 0 : 1;
2479 // Check if there's nothing to do.
2480 if (enabled == quint32(newEnabled))
2483 // Certain properties are dropped when an item is disabled.
2485 if (scene && scene->mouseGrabberItem() == q_ptr)
2486 q_ptr->ungrabMouse();
2487 if (q_ptr->hasFocus()) {
2488 // Disabling the closest non-panel ancestor of the focus item
2489 // causes focus to pop to the next item, otherwise it's cleared.
2490 QGraphicsItem *focusItem = scene->focusItem();
2492 if (isWidget && !focusItem->isPanel() && q_ptr->isAncestorOf(focusItem)) {
2494 if (focusItem == q_ptr) {
2495 clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
2498 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
2501 q_ptr->clearFocus();
2503 if (q_ptr->isSelected())
2504 q_ptr->setSelected(false);
2507 // Modify the property.
2508 const QVariant newEnabledVariant(q_ptr->itemChange(QGraphicsItem::ItemEnabledChange,
2509 quint32(newEnabled)));
2510 enabled = newEnabledVariant.toBool();
2516 foreach (QGraphicsItem *child, children) {
2517 if (!newEnabled || !child->d_ptr->explicitlyDisabled)
2518 child->d_ptr->setEnabledHelper(newEnabled, /* explicitly = */ false);
2521 // Deliver post-change notification.
2522 q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, newEnabledVariant);
2525 emit static_cast<QGraphicsObject *>(q_ptr)->enabledChanged();
2529 If \a enabled is true, the item is enabled; otherwise, it is disabled.
2531 Disabled items are visible, but they do not receive any events, and cannot
2532 take focus nor be selected. Mouse events are discarded; they are not
2533 propagated unless the item is also invisible, or if it does not accept
2534 mouse events (see acceptedMouseButtons()). A disabled item cannot become the
2535 mouse grabber, and as a result of this, an item loses the grab if it
2536 becomes disabled when grabbing the mouse, just like it loses focus if it
2537 had focus when it was disabled.
2539 Disabled items are traditionally drawn using grayed-out colors (see \l
2540 QPalette::Disabled).
2542 If you disable a parent item, all its children will also be disabled. If
2543 you enable a parent item, all children will be enabled, unless they have
2544 been explicitly disabled (i.e., if you call setEnabled(false) on a child,
2545 it will not be reenabled if its parent is disabled, and then enabled
2548 Items are enabled by default.
2550 \note If you install an event filter, you can still intercept events
2551 before they are delivered to items; this mechanism disregards the item's
2556 void QGraphicsItem::setEnabled(bool enabled)
2558 d_ptr->setEnabledHelper(enabled, /* explicitly = */ true);
2562 Returns true if this item is selected; otherwise, false is returned.
2564 Items that are in a group inherit the group's selected state.
2566 Items are not selected by default.
2568 \sa setSelected(), QGraphicsScene::setSelectionArea()
2570 bool QGraphicsItem::isSelected() const
2572 if (QGraphicsItemGroup *group = this->group())
2573 return group->isSelected();
2574 return d_ptr->selected;
2578 If \a selected is true and this item is selectable, this item is selected;
2579 otherwise, it is unselected.
2581 If the item is in a group, the whole group's selected state is toggled by
2582 this function. If the group is selected, all items in the group are also
2583 selected, and if the group is not selected, no item in the group is
2586 Only visible, enabled, selectable items can be selected. If \a selected
2587 is true and this item is either invisible or disabled or unselectable,
2588 this function does nothing.
2590 By default, items cannot be selected. To enable selection, set the
2591 ItemIsSelectable flag.
2593 This function is provided for convenience, allowing individual toggling of
2594 the selected state of an item. However, a more common way of selecting
2595 items is to call QGraphicsScene::setSelectionArea(), which will call this
2596 function for all visible, enabled, and selectable items within a specified
2599 \sa isSelected(), QGraphicsScene::selectedItems()
2601 void QGraphicsItem::setSelected(bool selected)
2603 if (QGraphicsItemGroup *group = this->group()) {
2604 group->setSelected(selected);
2608 if (!(d_ptr->flags & ItemIsSelectable) || !d_ptr->enabled || !d_ptr->visible)
2610 if (d_ptr->selected == selected)
2612 const QVariant newSelectedVariant(itemChange(ItemSelectedChange, quint32(selected)));
2613 bool newSelected = newSelectedVariant.toBool();
2614 if (d_ptr->selected == newSelected)
2616 d_ptr->selected = newSelected;
2620 QGraphicsScenePrivate *sceneD = d_ptr->scene->d_func();
2622 sceneD->selectedItems << this;
2624 // QGraphicsScene::selectedItems() lazily pulls out all items that are
2625 // no longer selected.
2627 if (!sceneD->selectionChanging)
2628 emit d_ptr->scene->selectionChanged();
2631 // Deliver post-change notification.
2632 itemChange(QGraphicsItem::ItemSelectedHasChanged, newSelectedVariant);
2638 Returns this item's local opacity, which is between 0.0 (transparent) and
2639 1.0 (opaque). This value is combined with parent and ancestor values into
2640 the effectiveOpacity(). The effective opacity decides how the item is
2643 The opacity property decides the state of the painter passed to the
2644 paint() function. If the item is cached, i.e., ItemCoordinateCache or
2645 DeviceCoordinateCache, the effective property will be applied to the item's
2646 cache as it is rendered.
2648 The default opacity is 1.0; fully opaque.
2650 \sa setOpacity(), paint(), ItemIgnoresParentOpacity,
2651 ItemDoesntPropagateOpacityToChildren
2653 qreal QGraphicsItem::opacity() const
2655 return d_ptr->opacity;
2661 Returns this item's \e effective opacity, which is between 0.0
2662 (transparent) and 1.0 (opaque). This value is a combination of this item's
2663 local opacity, and its parent and ancestors' opacities. The effective
2664 opacity decides how the item is rendered.
2666 \sa opacity(), setOpacity(), paint(), ItemIgnoresParentOpacity,
2667 ItemDoesntPropagateOpacityToChildren
2669 qreal QGraphicsItem::effectiveOpacity() const
2671 return d_ptr->effectiveOpacity();
2677 Sets this item's local \a opacity, between 0.0 (transparent) and 1.0
2678 (opaque). The item's local opacity is combined with parent and ancestor
2679 opacities into the effectiveOpacity().
2681 By default, opacity propagates from parent to child, so if a parent's
2682 opacity is 0.5 and the child is also 0.5, the child's effective opacity
2685 The opacity property decides the state of the painter passed to the
2686 paint() function. If the item is cached, i.e., ItemCoordinateCache or
2687 DeviceCoordinateCache, the effective property will be applied to the
2688 item's cache as it is rendered.
2690 There are two item flags that affect how the item's opacity is combined
2691 with the parent: ItemIgnoresParentOpacity and
2692 ItemDoesntPropagateOpacityToChildren.
2694 \sa opacity(), effectiveOpacity()
2696 void QGraphicsItem::setOpacity(qreal opacity)
2699 const QVariant newOpacityVariant(itemChange(ItemOpacityChange, opacity));
2701 // Normalized opacity
2702 qreal newOpacity = qBound(qreal(0), newOpacityVariant.toReal(), qreal(1));
2705 if (newOpacity == d_ptr->opacity)
2708 bool wasFullyTransparent = d_ptr->isOpacityNull();
2709 d_ptr->opacity = newOpacity;
2712 itemChange(ItemOpacityHasChanged, newOpacityVariant);
2716 #ifndef QT_NO_GRAPHICSEFFECT
2717 d_ptr->invalidateParentGraphicsEffectsRecursively();
2718 if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren))
2719 d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged);
2720 #endif //QT_NO_GRAPHICSEFFECT
2721 d_ptr->scene->d_func()->markDirty(this, QRectF(),
2722 /*invalidateChildren=*/true,
2724 /*ignoreOpacity=*/d_ptr->isOpacityNull());
2725 if (wasFullyTransparent)
2726 d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
2729 if (d_ptr->isObject)
2730 emit static_cast<QGraphicsObject *>(this)->opacityChanged();
2734 Returns a pointer to this item's effect if it has one; otherwise 0.
2738 #ifndef QT_NO_GRAPHICSEFFECT
2739 QGraphicsEffect *QGraphicsItem::graphicsEffect() const
2741 return d_ptr->graphicsEffect;
2745 Sets \a effect as the item's effect. If there already is an effect installed
2746 on this item, QGraphicsItem will delete the existing effect before installing
2749 If \a effect is the installed on a different item, setGraphicsEffect() will remove
2750 the effect from the item and install it on this item.
2752 QGraphicsItem takes ownership of \a effect.
2754 \note This function will apply the effect on itself and all its children.
2758 void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
2760 if (d_ptr->graphicsEffect == effect)
2763 if (d_ptr->graphicsEffect) {
2764 delete d_ptr->graphicsEffect;
2765 d_ptr->graphicsEffect = 0;
2766 } else if (d_ptr->parent) {
2767 d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
2772 QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
2773 QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
2774 d_ptr->graphicsEffect = effect;
2775 effect->d_func()->setGraphicsEffectSource(source);
2776 prepareGeometryChange();
2779 #endif //QT_NO_GRAPHICSEFFECT
2781 void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively()
2783 #ifndef QT_NO_GRAPHICSEFFECT
2784 QGraphicsItemPrivate *itemPrivate = this;
2786 // parent chain already notified?
2787 if (itemPrivate->mayHaveChildWithGraphicsEffect)
2789 itemPrivate->mayHaveChildWithGraphicsEffect = 1;
2790 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
2797 Returns the effective bounding rect of the given item space rect.
2798 If the item has no effect, the rect is returned unmodified.
2799 If the item has an effect, the effective rect can be extend beyond the
2800 item's bounding rect, depending on the effect.
2804 QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
2806 #ifndef QT_NO_GRAPHICSEFFECT
2807 Q_Q(const QGraphicsItem);
2808 QGraphicsEffect *effect = graphicsEffect;
2809 if (scene && effect && effect->isEnabled()) {
2810 if (scene->d_func()->views.isEmpty())
2811 return effect->boundingRectFor(rect);
2812 QRectF sceneRect = q->mapRectToScene(rect);
2813 QRectF sceneEffectRect;
2814 foreach (QGraphicsView *view, scene->views()) {
2815 QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect);
2816 QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect();
2817 sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect);
2819 return q->mapRectFromScene(sceneEffectRect);
2821 #endif //QT_NO_GRAPHICSEFFECT
2828 Returns the effective bounding rect of the item.
2829 If the item has no effect, this is the same as the item's bounding rect.
2830 If the item has an effect, the effective rect can be larger than the item's
2831 bouding rect, depending on the effect.
2835 QRectF QGraphicsItemPrivate::effectiveBoundingRect(QGraphicsItem *topMostEffectItem) const
2837 #ifndef QT_NO_GRAPHICSEFFECT
2838 Q_Q(const QGraphicsItem);
2839 QRectF brect = effectiveBoundingRect(q_ptr->boundingRect());
2840 if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren || topMostEffectItem == q)
2843 const QGraphicsItem *effectParent = parent;
2844 while (effectParent) {
2845 QGraphicsEffect *effect = effectParent->d_ptr->graphicsEffect;
2846 if (scene && effect && effect->isEnabled()) {
2847 const QRectF brectInParentSpace = q->mapRectToItem(effectParent, brect);
2848 const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace);
2849 brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
2851 if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
2852 || topMostEffectItem == effectParent) {
2855 effectParent = effectParent->d_ptr->parent;
2859 #else //QT_NO_GRAPHICSEFFECT
2860 return q_ptr->boundingRect();
2861 #endif //QT_NO_GRAPHICSEFFECT
2868 Returns the effective bounding rect of this item in scene coordinates,
2869 by combining sceneTransform() with boundingRect(), taking into account
2870 the effect that the item might have.
2872 If the item has no effect, this is the same as sceneBoundingRect().
2874 \sa effectiveBoundingRect(), sceneBoundingRect()
2876 QRectF QGraphicsItemPrivate::sceneEffectiveBoundingRect() const
2878 // Find translate-only offset
2881 const QGraphicsItem *parentItem = q_ptr;
2882 const QGraphicsItemPrivate *itemd;
2884 itemd = parentItem->d_ptr.data();
2885 if (itemd->transformData)
2887 offset += itemd->pos;
2888 } while ((parentItem = itemd->parent));
2890 QRectF br = effectiveBoundingRect();
2891 br.translate(offset);
2892 return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
2896 Returns true if this item can accept drag and drop events; otherwise,
2897 returns false. By default, items do not accept drag and drop events; items
2898 are transparent to drag and drop.
2900 \sa setAcceptDrops()
2902 bool QGraphicsItem::acceptDrops() const
2904 return d_ptr->acceptDrops;
2908 If \a on is true, this item will accept drag and drop events; otherwise,
2909 it is transparent for drag and drop events. By default, items do not
2910 accept drag and drop events.
2914 void QGraphicsItem::setAcceptDrops(bool on)
2916 d_ptr->acceptDrops = on;
2920 Returns the mouse buttons that this item accepts mouse events for. By
2921 default, all mouse buttons are accepted.
2923 If an item accepts a mouse button, it will become the mouse
2924 grabber item when a mouse press event is delivered for that mouse
2925 button. However, if the item does not accept the button,
2926 QGraphicsScene will forward the mouse events to the first item
2927 beneath it that does.
2929 \sa setAcceptedMouseButtons(), mousePressEvent()
2931 Qt::MouseButtons QGraphicsItem::acceptedMouseButtons() const
2933 return Qt::MouseButtons(d_ptr->acceptedMouseButtons);
2937 Sets the mouse \a buttons that this item accepts mouse events for.
2939 By default, all mouse buttons are accepted. If an item accepts a
2940 mouse button, it will become the mouse grabber item when a mouse
2941 press event is delivered for that button. However, if the item
2942 does not accept the mouse button, QGraphicsScene will forward the
2943 mouse events to the first item beneath it that does.
2945 To disable mouse events for an item (i.e., make it transparent for mouse
2946 events), call setAcceptedMouseButtons(0).
2948 \sa acceptedMouseButtons(), mousePressEvent()
2950 void QGraphicsItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
2952 if (Qt::MouseButtons(d_ptr->acceptedMouseButtons) != buttons) {
2953 if (buttons == 0 && d_ptr->scene && d_ptr->scene->mouseGrabberItem() == this
2954 && d_ptr->scene->d_func()->lastMouseGrabberItemHasImplicitMouseGrab) {
2957 d_ptr->acceptedMouseButtons = quint32(buttons);
2964 Returns true if an item accepts hover events
2965 (QGraphicsSceneHoverEvent); otherwise, returns false. By default,
2966 items do not accept hover events.
2968 \sa setAcceptedMouseButtons()
2970 bool QGraphicsItem::acceptHoverEvents() const
2972 return d_ptr->acceptsHover;
2978 Call acceptHoverEvents() instead.
2980 bool QGraphicsItem::acceptsHoverEvents() const
2982 return d_ptr->acceptsHover;
2988 If \a enabled is true, this item will accept hover events;
2989 otherwise, it will ignore them. By default, items do not accept
2992 Hover events are delivered when there is no current mouse grabber
2993 item. They are sent when the mouse cursor enters an item, when it
2994 moves around inside the item, and when the cursor leaves an
2995 item. Hover events are commonly used to highlight an item when
2996 it's entered, and for tracking the mouse cursor as it hovers over
2997 the item (equivalent to QWidget::mouseTracking).
2999 Parent items receive hover enter events before their children, and
3000 leave events after their children. The parent does not receive a
3001 hover leave event if the cursor enters a child, though; the parent
3002 stays "hovered" until the cursor leaves its area, including its
3005 If a parent item handles child events, it will receive hover move,
3006 drag move, and drop events as the cursor passes through its
3007 children, but it does not receive hover enter and hover leave, nor
3008 drag enter and drag leave events on behalf of its children.
3010 A QGraphicsWidget with window decorations will accept hover events
3011 regardless of the value of acceptHoverEvents().
3013 \sa acceptHoverEvents(), hoverEnterEvent(), hoverMoveEvent(),
3016 void QGraphicsItem::setAcceptHoverEvents(bool enabled)
3018 if (d_ptr->acceptsHover == quint32(enabled))
3020 d_ptr->acceptsHover = quint32(enabled);
3021 if (d_ptr->acceptsHover && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreHoverEvents) {
3022 d_ptr->scene->d_func()->allItemsIgnoreHoverEvents = false;
3023 d_ptr->scene->d_func()->enableMouseTrackingOnViews();
3030 Use setAcceptHoverEvents(\a enabled) instead.
3032 void QGraphicsItem::setAcceptsHoverEvents(bool enabled)
3034 setAcceptHoverEvents(enabled);
3039 Returns true if an item accepts \l{QTouchEvent}{touch events};
3040 otherwise, returns false. By default, items do not accept touch events.
3042 \sa setAcceptTouchEvents()
3044 bool QGraphicsItem::acceptTouchEvents() const
3046 return d_ptr->acceptTouchEvents;
3052 If \a enabled is true, this item will accept \l{QTouchEvent}{touch events};
3053 otherwise, it will ignore them. By default, items do not accept
3056 void QGraphicsItem::setAcceptTouchEvents(bool enabled)
3058 if (d_ptr->acceptTouchEvents == quint32(enabled))
3060 d_ptr->acceptTouchEvents = quint32(enabled);
3061 if (d_ptr->acceptTouchEvents && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreTouchEvents) {
3062 d_ptr->scene->d_func()->allItemsIgnoreTouchEvents = false;
3063 d_ptr->scene->d_func()->enableTouchEventsOnViews();
3070 Returns true if this item filters child events (i.e., all events
3071 intended for any of its children are instead sent to this item);
3072 otherwise, false is returned.
3074 The default value is false; child events are not filtered.
3076 \sa setFiltersChildEvents()
3078 bool QGraphicsItem::filtersChildEvents() const
3080 return d_ptr->filtersDescendantEvents;
3086 If \a enabled is true, this item is set to filter all events for
3087 all its children (i.e., all events intented for any of its
3088 children are instead sent to this item); otherwise, if \a enabled
3089 is false, this item will only handle its own events. The default
3092 \sa filtersChildEvents()
3094 void QGraphicsItem::setFiltersChildEvents(bool enabled)
3096 if (d_ptr->filtersDescendantEvents == enabled)
3099 d_ptr->filtersDescendantEvents = enabled;
3100 d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
3106 Returns true if this item handles child events (i.e., all events
3107 intended for any of its children are instead sent to this item);
3108 otherwise, false is returned.
3110 This property is useful for item groups; it allows one item to
3111 handle events on behalf of its children, as opposed to its
3112 children handling their events individually.
3114 The default is to return false; children handle their own events.
3115 The exception for this is if the item is a QGraphicsItemGroup, then
3116 it defaults to return true.
3118 \sa setHandlesChildEvents()
3120 bool QGraphicsItem::handlesChildEvents() const
3122 return d_ptr->handlesChildEvents;
3128 If \a enabled is true, this item is set to handle all events for
3129 all its children (i.e., all events intented for any of its
3130 children are instead sent to this item); otherwise, if \a enabled
3131 is false, this item will only handle its own events. The default
3134 This property is useful for item groups; it allows one item to
3135 handle events on behalf of its children, as opposed to its
3136 children handling their events individually.
3138 If a child item accepts hover events, its parent will receive
3139 hover move events as the cursor passes through the child, but it
3140 does not receive hover enter and hover leave events on behalf of
3143 \sa handlesChildEvents()
3145 void QGraphicsItem::setHandlesChildEvents(bool enabled)
3147 if (d_ptr->handlesChildEvents == enabled)
3150 d_ptr->handlesChildEvents = enabled;
3151 d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
3155 Returns true if this item is active; otherwise returns false.
3157 An item can only be active if the scene is active. An item is active
3158 if it is, or is a descendent of, an active panel. Items in non-active
3159 panels are not active.
3161 Items that are not part of a panel follow scene activation when the
3162 scene has no active panel.
3164 Only active items can gain input focus.
3166 \sa QGraphicsScene::isActive(), QGraphicsScene::activePanel(), panel(), isPanel()
3168 bool QGraphicsItem::isActive() const
3170 if (!d_ptr->scene || !d_ptr->scene->isActive())
3172 return panel() == d_ptr->scene->activePanel();
3178 If \a active is true, and the scene is active, this item's panel will be
3179 activated. Otherwise, the panel is deactivated.
3181 If the item is not part of an active scene, \a active will decide what
3182 happens to the panel when the scene becomes active or the item is added to
3183 the scene. If true, the item's panel will be activated when the item is
3184 either added to the scene or the scene is activated. Otherwise, the item
3185 will stay inactive independent of the scene's activated state.
3187 \sa isPanel(), QGraphicsScene::setActivePanel(), QGraphicsScene::isActive()
3189 void QGraphicsItem::setActive(bool active)
3191 d_ptr->explicitActivate = 1;
3192 d_ptr->wantsActive = active;
3195 // Activate this item.
3196 d_ptr->scene->setActivePanel(this);
3198 // Deactivate this item, and reactivate the last active item
3200 QGraphicsItem *lastActive = d_ptr->scene->d_func()->lastActivePanel;
3201 d_ptr->scene->setActivePanel(lastActive != this ? lastActive : 0);
3207 Returns true if this item is active, and it or its \l{focusProxy()}{focus
3208 proxy} has keyboard input focus; otherwise, returns false.
3210 \sa focusItem(), setFocus(), QGraphicsScene::setFocusItem(), isActive()
3212 bool QGraphicsItem::hasFocus() const
3214 if (!d_ptr->scene || !d_ptr->scene->isActive())
3217 if (d_ptr->focusProxy)
3218 return d_ptr->focusProxy->hasFocus();
3220 if (d_ptr->scene->d_func()->focusItem != this)
3223 return panel() == d_ptr->scene->d_func()->activePanel;
3227 Gives keyboard input focus to this item. The \a focusReason argument will
3228 be passed into any \l{QFocusEvent}{focus event} generated by this function;
3229 it is used to give an explanation of what caused the item to get focus.
3231 Only enabled items that set the ItemIsFocusable flag can accept keyboard
3234 If this item is not visible, not active, or not associated with a scene,
3235 it will not gain immediate input focus. However, it will be registered as
3236 the preferred focus item for its subtree of items, should it later become
3239 As a result of calling this function, this item will receive a
3240 \l{focusInEvent()}{focus in event} with \a focusReason. If another item
3241 already has focus, that item will first receive a \l{focusOutEvent()}
3242 {focus out event} indicating that it has lost input focus.
3244 \sa clearFocus(), hasFocus(), focusItem(), focusProxy()
3246 void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
3248 d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromHide = */ false);
3254 void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide)
3256 // Disabled / unfocusable items cannot accept focus.
3257 if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
3260 // Find focus proxy.
3261 QGraphicsItem *f = q_ptr;
3262 while (f->d_ptr->focusProxy)
3263 f = f->d_ptr->focusProxy;
3265 // Return if it already has focus.
3266 if (scene && scene->focusItem() == f)
3269 // Update focus scope item ptr.
3270 QGraphicsItem *p = parent;
3272 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3273 QGraphicsItem *oldFocusScopeItem = p->d_ptr->focusScopeItem;
3274 p->d_ptr->focusScopeItem = q_ptr;
3275 if (!p->focusItem() && !focusFromHide) {
3276 if (oldFocusScopeItem)
3277 oldFocusScopeItem->d_ptr->focusScopeItemChange(false);
3278 focusScopeItemChange(true);
3279 // If you call setFocus on a child of a focus scope that
3280 // doesn't currently have a focus item, then stop.
3285 p = p->d_ptr->parent;
3289 while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible())
3290 f = f->d_ptr->focusScopeItem;
3293 // Update the child focus chain.
3294 QGraphicsItem *commonAncestor = 0;
3295 if (scene && scene->focusItem()) {
3296 commonAncestor = scene->focusItem()->commonAncestorItem(f);
3297 scene->focusItem()->d_ptr->clearSubFocus(scene->focusItem(), commonAncestor);
3300 f->d_ptr->setSubFocus(f, commonAncestor);
3302 // Update the scene's focus item.
3304 QGraphicsItem *p = q_ptr->panel();
3305 if ((!p && scene->isActive()) || (p && p->isActive())) {
3306 // Visible items immediately gain focus from scene.
3307 scene->d_func()->setFocusItemHelper(f, focusReason);
3313 Takes keyboard input focus from the item.
3315 If it has focus, a \l{focusOutEvent()}{focus out event} is sent to this
3316 item to tell it that it is about to lose the focus.
3318 Only items that set the ItemIsFocusable flag, or widgets that set an
3319 appropriate focus policy, can accept keyboard focus.
3321 \sa setFocus(), hasFocus(), QGraphicsWidget::focusPolicy
3323 void QGraphicsItem::clearFocus()
3325 d_ptr->clearFocusHelper(/* giveFocusToParent = */ true);
3331 void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent)
3333 if (giveFocusToParent) {
3334 // Pass focus to the closest parent focus scope
3335 if (!inDestructor) {
3336 QGraphicsItem *p = parent;
3338 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3339 if (p->d_ptr->focusScopeItem == q_ptr) {
3340 p->d_ptr->focusScopeItem = 0;
3341 if (!q_ptr->hasFocus()) //if it has focus, focusScopeItemChange is called elsewhere
3342 focusScopeItemChange(false);
3344 if (q_ptr->hasFocus())
3345 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false,
3346 /* focusFromHide = */ false);
3349 p = p->d_ptr->parent;
3354 if (q_ptr->hasFocus()) {
3355 // Invisible items with focus must explicitly clear subfocus.
3356 clearSubFocus(q_ptr);
3358 // If this item has the scene's input focus, clear it.
3359 scene->setFocusItem(0);
3366 Returns this item's focus proxy, or 0 if this item has no
3369 \sa setFocusProxy(), setFocus(), hasFocus()
3371 QGraphicsItem *QGraphicsItem::focusProxy() const
3373 return d_ptr->focusProxy;
3379 Sets the item's focus proxy to \a item.
3381 If an item has a focus proxy, the focus proxy will receive
3382 input focus when the item gains input focus. The item itself
3383 will still have focus (i.e., hasFocus() will return true),
3384 but only the focus proxy will receive the keyboard input.
3386 A focus proxy can itself have a focus proxy, and so on. In
3387 such case, keyboard input will be handled by the outermost
3390 The focus proxy \a item must belong to the same scene as
3393 \sa focusProxy(), setFocus(), hasFocus()
3395 void QGraphicsItem::setFocusProxy(QGraphicsItem *item)
3397 if (item == d_ptr->focusProxy)
3400 qWarning("QGraphicsItem::setFocusProxy: cannot assign self as focus proxy");
3404 if (item->d_ptr->scene != d_ptr->scene) {
3405 qWarning("QGraphicsItem::setFocusProxy: focus proxy must be in same scene");
3408 for (QGraphicsItem *f = item->focusProxy(); f != 0; f = f->focusProxy()) {
3410 qWarning("QGraphicsItem::setFocusProxy: %p is already in the focus proxy chain", item);
3416 QGraphicsItem *lastFocusProxy = d_ptr->focusProxy;
3418 lastFocusProxy->d_ptr->focusProxyRefs.removeOne(&d_ptr->focusProxy);
3419 d_ptr->focusProxy = item;
3421 item->d_ptr->focusProxyRefs << &d_ptr->focusProxy;
3427 If this item, a child or descendant of this item currently has input
3428 focus, this function will return a pointer to that item. If
3429 no descendant has input focus, 0 is returned.
3431 \sa hasFocus(), setFocus(), QWidget::focusWidget()
3433 QGraphicsItem *QGraphicsItem::focusItem() const
3435 return d_ptr->subFocusItem;
3441 Returns this item's focus scope item.
3443 QGraphicsItem *QGraphicsItem::focusScopeItem() const
3445 return d_ptr->focusScopeItem;
3450 Grabs the mouse input.
3452 This item will receive all mouse events for the scene until any of the
3453 following events occurs:
3456 \li The item becomes invisible
3457 \li The item is removed from the scene
3458 \li The item is deleted
3459 \li The item call ungrabMouse()
3460 \li Another item calls grabMouse(); the item will regain the mouse grab
3461 when the other item calls ungrabMouse().
3464 When an item gains the mouse grab, it receives a QEvent::GrabMouse
3465 event. When it loses the mouse grab, it receives a QEvent::UngrabMouse
3466 event. These events can be used to detect when your item gains or loses
3467 the mouse grab through other means than receiving mouse button events.
3469 It is almost never necessary to explicitly grab the mouse in Qt, as Qt
3470 grabs and releases it sensibly. In particular, Qt grabs the mouse when you
3471 press a mouse button, and keeps the mouse grabbed until you release the
3472 last mouse button. Also, Qt::Popup widgets implicitly call grabMouse()
3473 when shown, and ungrabMouse() when hidden.
3475 Note that only visible items can grab mouse input. Calling grabMouse() on
3476 an invisible item has no effect.
3478 Keyboard events are not affected.
3480 \sa QGraphicsScene::mouseGrabberItem(), ungrabMouse(), grabKeyboard()
3482 void QGraphicsItem::grabMouse()
3484 if (!d_ptr->scene) {
3485 qWarning("QGraphicsItem::grabMouse: cannot grab mouse without scene");
3488 if (!d_ptr->visible) {
3489 qWarning("QGraphicsItem::grabMouse: cannot grab mouse while invisible");
3492 d_ptr->scene->d_func()->grabMouse(this);
3497 Releases the mouse grab.
3499 \sa grabMouse(), ungrabKeyboard()
3501 void QGraphicsItem::ungrabMouse()
3503 if (!d_ptr->scene) {
3504 qWarning("QGraphicsItem::ungrabMouse: cannot ungrab mouse without scene");
3507 d_ptr->scene->d_func()->ungrabMouse(this);
3512 Grabs the keyboard input.
3514 The item will receive all keyboard input to the scene until one of the
3515 following events occur:
3518 \li The item becomes invisible
3519 \li The item is removed from the scene
3520 \li The item is deleted
3521 \li The item calls ungrabKeyboard()
3522 \li Another item calls grabKeyboard(); the item will regain the keyboard grab
3523 when the other item calls ungrabKeyboard().
3526 When an item gains the keyboard grab, it receives a QEvent::GrabKeyboard
3527 event. When it loses the keyboard grab, it receives a
3528 QEvent::UngrabKeyboard event. These events can be used to detect when your
3529 item gains or loses the keyboard grab through other means than gaining
3532 It is almost never necessary to explicitly grab the keyboard in Qt, as Qt
3533 grabs and releases it sensibly. In particular, Qt grabs the keyboard when
3534 your item gains input focus, and releases it when your item loses input
3535 focus, or when the item is hidden.
3537 Note that only visible items can grab keyboard input. Calling
3538 grabKeyboard() on an invisible item has no effect.
3540 Keyboard events are not affected.
3542 \sa ungrabKeyboard(), grabMouse(), setFocus()
3544 void QGraphicsItem::grabKeyboard()
3546 if (!d_ptr->scene) {
3547 qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard without scene");
3550 if (!d_ptr->visible) {
3551 qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard while invisible");
3554 d_ptr->scene->d_func()->grabKeyboard(this);
3559 Releases the keyboard grab.
3561 \sa grabKeyboard(), ungrabMouse()
3563 void QGraphicsItem::ungrabKeyboard()
3565 if (!d_ptr->scene) {
3566 qWarning("QGraphicsItem::ungrabKeyboard: cannot ungrab keyboard without scene");
3569 d_ptr->scene->d_func()->ungrabKeyboard(this);
3573 Returns the position of the item in parent coordinates. If the item has no
3574 parent, its position is given in scene coordinates.
3576 The position of the item describes its origin (local coordinate
3577 (0, 0)) in parent coordinates; this function returns the same as
3580 For convenience, you can also call scenePos() to determine the
3581 item's position in scene coordinates, regardless of its parent.
3583 \sa x(), y(), setPos(), transform(), {The Graphics View Coordinate System}
3585 QPointF QGraphicsItem::pos() const
3591 \fn QGraphicsItem::x() const
3593 This convenience function is equivalent to calling pos().x().
3601 Set's the \a x coordinate of the item's position. Equivalent to
3602 calling setPos(x, y()).
3606 void QGraphicsItem::setX(qreal x)
3608 if (d_ptr->inDestructor)
3614 setPos(QPointF(x, d_ptr->pos.y()));
3618 \fn QGraphicsItem::y() const
3620 This convenience function is equivalent to calling pos().y().
3628 Set's the \a y coordinate of the item's position. Equivalent to
3629 calling setPos(x(), y).
3633 void QGraphicsItem::setY(qreal y)
3635 if (d_ptr->inDestructor)
3641 setPos(QPointF(d_ptr->pos.x(), y));
3645 Returns the item's position in scene coordinates. This is
3646 equivalent to calling \c mapToScene(0, 0).
3648 \sa pos(), sceneTransform(), {The Graphics View Coordinate System}
3650 QPointF QGraphicsItem::scenePos() const
3652 return mapToScene(0, 0);
3658 Sets the position \a pos.
3660 void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
3665 q->prepareGeometryChange();
3666 QPointF oldPos = this->pos;
3668 dirtySceneTransform = 1;
3671 if (pos.x() != oldPos.x())
3672 emit static_cast<QGraphicsObject *>(q_ptr)->xChanged();
3673 if (pos.y() != oldPos.y())
3674 emit static_cast<QGraphicsObject *>(q_ptr)->yChanged();
3681 Sets the transform \a transform.
3683 void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
3685 q_ptr->prepareGeometryChange();
3686 transformData->transform = transform;
3687 dirtySceneTransform = 1;
3692 Sets the position of the item to \a pos, which is in parent
3693 coordinates. For items with no parent, \a pos is in scene
3696 The position of the item describes its origin (local coordinate
3697 (0, 0)) in parent coordinates.
3699 \sa pos(), scenePos(), {The Graphics View Coordinate System}
3701 void QGraphicsItem::setPos(const QPointF &pos)
3703 if (d_ptr->pos == pos)
3706 if (d_ptr->inDestructor)
3709 // Update and repositition.
3710 if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
3711 d_ptr->setPosHelper(pos);
3712 if (d_ptr->isWidget)
3713 static_cast<QGraphicsWidget *>(this)->d_func()->setGeometryFromSetPos();
3714 if (d_ptr->scenePosDescendants)
3715 d_ptr->sendScenePosChange();
3719 // Notify the item that the position is changing.
3720 const QVariant newPosVariant(itemChange(ItemPositionChange, QVariant::fromValue<QPointF>(pos)));
3721 QPointF newPos = newPosVariant.toPointF();
3722 if (newPos == d_ptr->pos)
3725 // Update and repositition.
3726 d_ptr->setPosHelper(newPos);
3728 // Send post-notification.
3729 itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
3730 d_ptr->sendScenePosChange();
3734 \fn void QGraphicsItem::setPos(qreal x, qreal y)
3737 This convenience function is equivalent to calling setPos(QPointF(\a x, \a
3742 \fn void QGraphicsItem::moveBy(qreal dx, qreal dy)
3744 Moves the item by \a dx points horizontally, and \a dy point
3745 vertically. This function is equivalent to calling setPos(pos() +
3746 QPointF(\a dx, \a dy)).
3750 If this item is part of a scene that is viewed by a QGraphicsView, this
3751 convenience function will attempt to scroll the view to ensure that \a
3752 rect is visible inside the view's viewport. If \a rect is a null rect (the
3753 default), QGraphicsItem will default to the item's bounding rect. \a xmargin
3754 and \a ymargin are the number of pixels the view should use for margins.
3756 If the specified rect cannot be reached, the contents are scrolled to the
3757 nearest valid position.
3759 If this item is not viewed by a QGraphicsView, this function does nothing.
3761 \sa QGraphicsView::ensureVisible()
3763 void QGraphicsItem::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
3768 sceneRect = sceneTransform().mapRect(rect);
3770 sceneRect = sceneBoundingRect();
3771 foreach (QGraphicsView *view, d_ptr->scene->d_func()->views)
3772 view->ensureVisible(sceneRect, xmargin, ymargin);
3777 \fn void QGraphicsItem::ensureVisible(qreal x, qreal y, qreal w, qreal h,
3778 int xmargin = 50, int ymargin = 50)
3780 This convenience function is equivalent to calling
3781 ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin):
3787 Returns the item's affine transformation matrix. This is a subset or the
3788 item's full transformation matrix, and might not represent the item's full
3791 Use transform() instead.
3793 \sa setTransform(), sceneTransform()
3795 QMatrix QGraphicsItem::matrix() const
3797 return transform().toAffine();
3803 Returns this item's transformation matrix.
3805 The transformation matrix is combined with the item's rotation(), scale()
3806 and transformations() into a combined transformations for the item.
3808 The default transformation matrix is an identity matrix.
3810 \sa setTransform(), sceneTransform()
3812 QTransform QGraphicsItem::transform() const
3814 if (!d_ptr->transformData)
3815 return QTransform();
3816 return d_ptr->transformData->transform;
3822 Returns the clockwise rotation, in degrees, around the Z axis. The default
3823 value is 0 (i.e., the item is not rotated).
3825 The rotation is combined with the item's scale(), transform() and
3826 transformations() to map the item's coordinate system to the parent item.
3828 \sa setRotation(), transformOriginPoint(), {Transformations}
3830 qreal QGraphicsItem::rotation() const
3832 if (!d_ptr->transformData)
3834 return d_ptr->transformData->rotation;
3840 Sets the clockwise rotation \a angle, in degrees, around the Z axis. The
3841 default value is 0 (i.e., the item is not rotated). Assigning a negative
3842 value will rotate the item counter-clockwise. Normally the rotation angle
3843 is in the range (-360, 360), but it's also possible to assign values
3844 outside of this range (e.g., a rotation of 370 degrees is the same as a
3845 rotation of 10 degrees).
3847 The item is rotated around its transform origin point, which by default
3848 is (0, 0). You can select a different transformation origin by calling
3849 setTransformOriginPoint().
3851 The rotation is combined with the item's scale(), transform() and
3852 transformations() to map the item's coordinate system to the parent item.
3854 \sa rotation(), setTransformOriginPoint(), {Transformations}
3856 void QGraphicsItem::setRotation(qreal angle)
3858 prepareGeometryChange();
3859 qreal newRotation = angle;
3861 if (d_ptr->flags & ItemSendsGeometryChanges) {
3862 // Notify the item that the rotation is changing.
3863 const QVariant newRotationVariant(itemChange(ItemRotationChange, angle));
3864 newRotation = newRotationVariant.toReal();
3867 if (!d_ptr->transformData)
3868 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
3870 if (d_ptr->transformData->rotation == newRotation)
3873 d_ptr->transformData->rotation = newRotation;
3874 d_ptr->transformData->onlyTransform = false;
3875 d_ptr->dirtySceneTransform = 1;
3877 // Send post-notification.
3878 if (d_ptr->flags & ItemSendsGeometryChanges)
3879 itemChange(ItemRotationHasChanged, newRotation);
3881 if (d_ptr->isObject)
3882 emit static_cast<QGraphicsObject *>(this)->rotationChanged();
3884 d_ptr->transformChanged();
3890 Returns the scale factor of the item. The default scale factor is 1.0
3891 (i.e., the item is not scaled).
3893 The scale is combined with the item's rotation(), transform() and
3894 transformations() to map the item's coordinate system to the parent item.
3896 \sa setScale(), rotation(), {Transformations}
3898 qreal QGraphicsItem::scale() const
3900 if (!d_ptr->transformData)
3902 return d_ptr->transformData->scale;
3908 Sets the scale \a factor of the item. The default scale factor is 1.0
3909 (i.e., the item is not scaled). A scale factor of 0.0 will collapse the
3910 item to a single point. If you provide a negative scale factor, the
3911 item will be flipped and mirrored (i.e., rotated 180 degrees).
3913 The item is scaled around its transform origin point, which by default
3914 is (0, 0). You can select a different transformation origin by calling
3915 setTransformOriginPoint().
3917 The scale is combined with the item's rotation(), transform() and
3918 transformations() to map the item's coordinate system to the parent item.
3920 \sa scale(), setTransformOriginPoint(), {Transformations Example}
3922 void QGraphicsItem::setScale(qreal factor)
3924 prepareGeometryChange();
3925 qreal newScale = factor;
3927 if (d_ptr->flags & ItemSendsGeometryChanges) {
3928 // Notify the item that the scale is changing.
3929 const QVariant newScaleVariant(itemChange(ItemScaleChange, factor));
3930 newScale = newScaleVariant.toReal();
3933 if (!d_ptr->transformData)
3934 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
3936 if (d_ptr->transformData->scale == newScale)
3939 d_ptr->transformData->scale = newScale;
3940 d_ptr->transformData->onlyTransform = false;
3941 d_ptr->dirtySceneTransform = 1;
3943 // Send post-notification.
3944 if (d_ptr->flags & ItemSendsGeometryChanges)
3945 itemChange(ItemScaleHasChanged, newScale);
3947 if (d_ptr->isObject)
3948 emit static_cast<QGraphicsObject *>(this)->scaleChanged();
3950 d_ptr->transformChanged();
3957 Returns a list of graphics transforms that currently apply to this item.
3959 QGraphicsTransform is for applying and controlling a chain of individual
3960 transformation operations on an item. It's particularly useful in
3961 animations, where each transform operation needs to be interpolated
3962 independently, or differently.
3964 The transformations are combined with the item's rotation(), scale() and
3965 transform() to map the item's coordinate system to the parent item.
3967 \sa scale(), rotation(), transformOriginPoint(), {Transformations}
3969 QList<QGraphicsTransform *> QGraphicsItem::transformations() const
3971 if (!d_ptr->transformData)
3972 return QList<QGraphicsTransform *>();
3973 return d_ptr->transformData->graphicsTransforms;
3979 Sets a list of graphics \a transformations (QGraphicsTransform) that
3980 currently apply to this item.
3982 If all you want is to rotate or scale an item, you should call setRotation()
3983 or setScale() instead. If you want to set an arbitrary transformation on
3984 an item, you can call setTransform().
3986 QGraphicsTransform is for applying and controlling a chain of individual
3987 transformation operations on an item. It's particularly useful in
3988 animations, where each transform operation needs to be interpolated
3989 independently, or differently.
3991 The transformations are combined with the item's rotation(), scale() and
3992 transform() to map the item's coordinate system to the parent item.
3994 \sa scale(), setTransformOriginPoint(), {Transformations}
3996 void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transformations)
3998 prepareGeometryChange();
3999 if (!d_ptr->transformData)
4000 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4001 d_ptr->transformData->graphicsTransforms = transformations;
4002 for (int i = 0; i < transformations.size(); ++i)
4003 transformations.at(i)->d_func()->setItem(this);
4004 d_ptr->transformData->onlyTransform = false;
4005 d_ptr->dirtySceneTransform = 1;
4006 d_ptr->transformChanged();
4012 void QGraphicsItemPrivate::prependGraphicsTransform(QGraphicsTransform *t)
4015 transformData = new QGraphicsItemPrivate::TransformData;
4016 if (!transformData->graphicsTransforms.contains(t))
4017 transformData->graphicsTransforms.prepend(t);
4020 t->d_func()->setItem(q);
4021 transformData->onlyTransform = false;
4022 dirtySceneTransform = 1;
4029 void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t)
4032 transformData = new QGraphicsItemPrivate::TransformData;
4033 if (!transformData->graphicsTransforms.contains(t))
4034 transformData->graphicsTransforms.append(t);
4037 t->d_func()->setItem(q);
4038 transformData->onlyTransform = false;
4039 dirtySceneTransform = 1;
4046 Returns the origin point for the transformation in item coordinates.
4048 The default is QPointF(0,0).
4050 \sa setTransformOriginPoint(), {Transformations}
4052 QPointF QGraphicsItem::transformOriginPoint() const
4054 if (!d_ptr->transformData)
4055 return QPointF(0,0);
4056 return QPointF(d_ptr->transformData->xOrigin, d_ptr->transformData->yOrigin);
4062 Sets the \a origin point for the transformation in item coordinates.
4064 \sa transformOriginPoint(), {Transformations}
4066 void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
4068 prepareGeometryChange();
4069 QPointF newOrigin = origin;
4071 if (d_ptr->flags & ItemSendsGeometryChanges) {
4072 // Notify the item that the origin point is changing.
4073 const QVariant newOriginVariant(itemChange(ItemTransformOriginPointChange,
4074 QVariant::fromValue<QPointF>(origin)));
4075 newOrigin = newOriginVariant.toPointF();
4078 if (!d_ptr->transformData)
4079 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4081 if (d_ptr->transformData->xOrigin == newOrigin.x()
4082 && d_ptr->transformData->yOrigin == newOrigin.y()) {
4086 d_ptr->transformData->xOrigin = newOrigin.x();
4087 d_ptr->transformData->yOrigin = newOrigin.y();
4088 d_ptr->transformData->onlyTransform = false;
4089 d_ptr->dirtySceneTransform = 1;
4091 // Send post-notification.
4092 if (d_ptr->flags & ItemSendsGeometryChanges)
4093 itemChange(ItemTransformOriginPointHasChanged, QVariant::fromValue<QPointF>(newOrigin));
4097 \fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y)
4102 Sets the origin point for the transformation in item coordinates.
4103 This is equivalent to calling setTransformOriginPoint(QPointF(\a x, \a y)).
4105 \sa setTransformOriginPoint(), {Transformations}
4112 Use sceneTransform() instead.
4114 \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}
4116 QMatrix QGraphicsItem::sceneMatrix() const
4118 d_ptr->ensureSceneTransform();
4119 return d_ptr->sceneTransform.toAffine();
4126 Returns this item's scene transformation matrix. This matrix can be used
4127 to map coordinates and geometrical shapes from this item's local
4128 coordinate system to the scene's coordinate system. To map coordinates
4129 from the scene, you must first invert the returned matrix.
4133 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 4
4135 Unlike transform(), which returns only an item's local transformation, this
4136 function includes the item's (and any parents') position, and all the transfomation properties.
4138 \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}, {Transformations}
4140 QTransform QGraphicsItem::sceneTransform() const
4142 d_ptr->ensureSceneTransform();
4143 return d_ptr->sceneTransform;
4149 Returns this item's device transformation matrix, using \a
4150 viewportTransform to map from scene to device coordinates. This matrix can
4151 be used to map coordinates and geometrical shapes from this item's local
4152 coordinate system to the viewport's (or any device's) coordinate
4153 system. To map coordinates from the viewport, you must first invert the
4158 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 5
4160 This function is the same as combining this item's scene transform with
4161 the view's viewport transform, but it also understands the
4162 ItemIgnoresTransformations flag. The device transform can be used to do
4163 accurate coordinate mapping (and collision detection) for untransformable
4166 \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate
4167 System}, itemTransform()
4169 QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) const
4171 // Ensure we return the standard transform if we're not untransformable.
4172 if (!d_ptr->itemIsUntransformable()) {
4173 d_ptr->ensureSceneTransform();
4174 return d_ptr->sceneTransform * viewportTransform;
4177 // Find the topmost item that ignores view transformations.
4178 const QGraphicsItem *untransformedAncestor = this;
4179 QList<const QGraphicsItem *> parents;
4180 while (untransformedAncestor && ((untransformedAncestor->d_ptr->ancestorFlags
4181 & QGraphicsItemPrivate::AncestorIgnoresTransformations))) {
4182 parents.prepend(untransformedAncestor);
4183 untransformedAncestor = untransformedAncestor->parentItem();
4186 if (!untransformedAncestor) {
4187 // Assert in debug mode, continue in release.
4188 Q_ASSERT_X(untransformedAncestor, "QGraphicsItem::deviceTransform",
4189 "Invalid object structure!");
4190 return QTransform();
4193 // First translate the base untransformable item.
4194 untransformedAncestor->d_ptr->ensureSceneTransform();
4195 QPointF mappedPoint = (untransformedAncestor->d_ptr->sceneTransform * viewportTransform).map(QPointF(0, 0));
4198 QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y());
4199 if (untransformedAncestor->d_ptr->transformData)
4200 matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform(&matrix);
4202 // Then transform and translate all children.
4203 for (int i = 0; i < parents.size(); ++i) {
4204 const QGraphicsItem *parent = parents.at(i);
4205 parent->d_ptr->combineTransformFromParent(&matrix);
4214 Returns a QTransform that maps coordinates from this item to \a other. If
4215 \a ok is not null, and if there is no such transform, the boolean pointed
4216 to by \a ok will be set to false; otherwise it will be set to true.
4218 This transform provides an alternative to the mapToItem() or mapFromItem()
4219 functions, by returning the appropriate transform so that you can map
4220 shapes and coordinates yourself. It also helps you write more efficient
4221 code when repeatedly mapping between the same two items.
4223 \note In rare circumstances, there is no transform that maps between two
4226 \sa mapToItem(), mapFromItem(), deviceTransform()
4228 QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) const
4230 // Catch simple cases first.
4232 qWarning("QGraphicsItem::itemTransform: null pointer passed");
4233 return QTransform();
4235 if (other == this) {
4238 return QTransform();
4241 QGraphicsItem *parent = d_ptr->parent;
4242 const QGraphicsItem *otherParent = other->d_ptr->parent;
4244 // This is other's child
4245 if (parent == other) {
4249 d_ptr->combineTransformFromParent(&x);
4253 // This is other's parent
4254 if (otherParent == this) {
4255 const QPointF &otherPos = other->d_ptr->pos;
4256 if (other->d_ptr->transformData) {
4257 QTransform otherToParent;
4258 other->d_ptr->combineTransformFromParent(&otherToParent);
4259 return otherToParent.inverted(ok);
4263 return QTransform::fromTranslate(-otherPos.x(), -otherPos.y());
4267 if (parent == otherParent) {
4269 const QPointF &itemPos = d_ptr->pos;
4270 const QPointF &otherPos = other->d_ptr->pos;
4271 if (!d_ptr->transformData && !other->d_ptr->transformData) {
4272 QPointF delta = itemPos - otherPos;
4275 return QTransform::fromTranslate(delta.x(), delta.y());
4278 QTransform itemToParent;
4279 d_ptr->combineTransformFromParent(&itemToParent);
4280 QTransform otherToParent;
4281 other->d_ptr->combineTransformFromParent(&otherToParent);
4282 return itemToParent * otherToParent.inverted(ok);
4285 // Find the closest common ancestor. If the two items don't share an
4286 // ancestor, then the only way is to combine their scene transforms.
4287 const QGraphicsItem *commonAncestor = commonAncestorItem(other);
4288 if (!commonAncestor) {
4289 d_ptr->ensureSceneTransform();
4290 other->d_ptr->ensureSceneTransform();
4291 return d_ptr->sceneTransform * other->d_ptr->sceneTransform.inverted(ok);
4294 // If the two items are cousins (in sibling branches), map both to the
4295 // common ancestor, and combine the two transforms.
4296 bool cousins = other != commonAncestor && this != commonAncestor;
4299 QTransform thisToScene = itemTransform(commonAncestor, &good);
4300 QTransform otherToScene(Qt::Uninitialized);
4302 otherToScene = other->itemTransform(commonAncestor, &good);
4306 return QTransform();
4308 return thisToScene * otherToScene.inverted(ok);
4311 // One is an ancestor of the other; walk the chain.
4312 bool parentOfOther = isAncestorOf(other);
4313 const QGraphicsItem *child = parentOfOther ? other : this;
4314 const QGraphicsItem *root = parentOfOther ? this : other;
4317 const QGraphicsItem *p = child;
4319 p->d_ptr.data()->combineTransformToParent(&x);
4320 } while ((p = p->d_ptr->parent) && p != root);
4322 return x.inverted(ok);
4331 Sets the item's affine transformation matrix. This is a subset or the
4332 item's full transformation matrix, and might not represent the item's full
4335 Use setTransform() instead.
4337 \sa transform(), {The Graphics View Coordinate System}
4339 void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
4341 if (!d_ptr->transformData)
4342 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4344 QTransform newTransform(combine ? QTransform(matrix) * d_ptr->transformData->transform : QTransform(matrix));
4345 if (d_ptr->transformData->transform == newTransform)
4348 // Update and set the new transformation.
4349 if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
4350 d_ptr->setTransformHelper(newTransform);
4354 // Notify the item that the transformation matrix is changing.
4355 const QVariant newMatrixVariant = QVariant::fromValue<QMatrix>(newTransform.toAffine());
4356 newTransform = QTransform(qvariant_cast<QMatrix>(itemChange(ItemMatrixChange, newMatrixVariant)));
4357 if (d_ptr->transformData->transform == newTransform)
4360 // Update and set the new transformation.
4361 d_ptr->setTransformHelper(newTransform);
4363 // Send post-notification.
4364 itemChange(ItemTransformHasChanged, QVariant::fromValue<QTransform>(newTransform));
4370 Sets the item's current transformation matrix to \a matrix.
4372 If \a combine is true, then \a matrix is combined with the current matrix;
4373 otherwise, \a matrix \e replaces the current matrix. \a combine is false
4376 To simplify interation with items using a transformed view, QGraphicsItem
4377 provides mapTo... and mapFrom... functions that can translate between
4378 items' and the scene's coordinates. For example, you can call mapToScene()
4379 to map an item coordiate to a scene coordinate, or mapFromScene() to map
4380 from scene coordinates to item coordinates.
4382 The transformation matrix is combined with the item's rotation(), scale()
4383 and transformations() into a combined transformation that maps the item's
4384 coordinate system to its parent.
4386 \sa transform(), setRotation(), setScale(), setTransformOriginPoint(), {The Graphics View Coordinate System}, {Transformations}
4388 void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
4390 if (!d_ptr->transformData)
4391 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4393 QTransform newTransform(combine ? matrix * d_ptr->transformData->transform : matrix);
4394 if (d_ptr->transformData->transform == newTransform)
4397 // Update and set the new transformation.
4398 if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
4399 d_ptr->setTransformHelper(newTransform);
4400 if (d_ptr->scenePosDescendants)
4401 d_ptr->sendScenePosChange();
4405 // Notify the item that the transformation matrix is changing.
4406 const QVariant newTransformVariant(itemChange(ItemTransformChange,
4407 QVariant::fromValue<QTransform>(newTransform)));
4408 newTransform = qvariant_cast<QTransform>(newTransformVariant);
4409 if (d_ptr->transformData->transform == newTransform)
4412 // Update and set the new transformation.
4413 d_ptr->setTransformHelper(newTransform);
4415 // Send post-notification.
4416 itemChange(ItemTransformHasChanged, newTransformVariant);
4417 d_ptr->sendScenePosChange();
4423 Use resetTransform() instead.
4425 void QGraphicsItem::resetMatrix()
4433 Resets this item's transformation matrix to the identity matrix or
4434 all the transformation properties to their default values.
4435 This is equivalent to calling \c setTransform(QTransform()).
4437 \sa setTransform(), transform()
4439 void QGraphicsItem::resetTransform()
4441 setTransform(QTransform(), false);
4450 setRotation(rotation() + angle);
4455 Rotates the current item transformation \a angle degrees clockwise around
4456 its origin. To translate around an arbitrary point (x, y), you need to
4457 combine translation and rotation with setTransform().
4461 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 6
4463 \sa setTransform(), transform(), scale(), shear(), translate()
4465 void QGraphicsItem::rotate(qreal angle)
4467 setTransform(QTransform().rotate(angle), true);
4476 setTransform(QTransform::fromScale(sx, sy), true);
4481 Scales the current item transformation by (\a sx, \a sy) around its
4482 origin. To scale from an arbitrary point (x, y), you need to combine
4483 translation and scaling with setTransform().
4487 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 7
4489 \sa setTransform(), transform()
4491 void QGraphicsItem::scale(qreal sx, qreal sy)
4493 setTransform(QTransform::fromScale(sx, sy), true);
4502 setTransform(QTransform().shear(sh, sv), true);
4507 Shears the current item transformation by (\a sh, \a sv).
4509 \sa setTransform(), transform()
4511 void QGraphicsItem::shear(qreal sh, qreal sv)
4513 setTransform(QTransform().shear(sh, sv), true);
4519 Use setPos() or setTransformOriginPoint() instead. For identical
4523 setTransform(QTransform::fromTranslate(dx, dy), true);
4526 Translates the current item transformation by (\a dx, \a dy).
4528 If all you want is to move an item, you should call moveBy() or
4529 setPos() instead; this function changes the item's translation,
4530 which is conceptually separate from its position.
4532 \sa setTransform(), transform()
4534 void QGraphicsItem::translate(qreal dx, qreal dy)
4536 setTransform(QTransform::fromTranslate(dx, dy), true);
4540 This virtual function is called twice for all items by the
4541 QGraphicsScene::advance() slot. In the first phase, all items are called
4542 with \a phase == 0, indicating that items on the scene are about to
4543 advance, and then all items are called with \a phase == 1. Reimplement
4544 this function to update your item if you need simple scene-controlled
4547 The default implementation does nothing.
4549 For individual item animation, an alternative to this function is to
4550 either use QGraphicsItemAnimation, or to multiple-inherit from QObject and
4551 QGraphicsItem, and animate your item using QObject::startTimer() and
4552 QObject::timerEvent().
4554 \sa QGraphicsItemAnimation, QTimeLine
4556 void QGraphicsItem::advance(int phase)
4562 Returns the Z-value of the item. The Z-value affects the stacking order of
4563 sibling (neighboring) items.
4565 The default Z-value is 0.
4567 \sa setZValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
4569 qreal QGraphicsItem::zValue() const
4575 Sets the Z-value of the item to \a z. The Z value decides the stacking
4576 order of sibling (neighboring) items. A sibling item of high Z value will
4577 always be drawn on top of another sibling item with a lower Z value.
4579 If you restore the Z value, the item's insertion order will decide its
4582 The Z-value does not affect the item's size in any way.
4584 The default Z-value is 0.
4586 \sa zValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
4588 void QGraphicsItem::setZValue(qreal z)
4590 const QVariant newZVariant(itemChange(ItemZValueChange, z));
4591 qreal newZ = newZVariant.toReal();
4592 if (newZ == d_ptr->z)
4595 if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
4596 // Z Value has changed, we have to notify the index.
4597 d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
4602 d_ptr->parent->d_ptr->needSortChildren = 1;
4603 else if (d_ptr->scene)
4604 d_ptr->scene->d_func()->needSortTopLevelItems = 1;
4607 d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
4609 itemChange(ItemZValueHasChanged, newZVariant);
4611 if (d_ptr->flags & ItemNegativeZStacksBehindParent)
4612 setFlag(QGraphicsItem::ItemStacksBehindParent, z < qreal(0.0));
4614 if (d_ptr->isObject)
4615 emit static_cast<QGraphicsObject *>(this)->zChanged();
4621 Ensures that the list of children is sorted by insertion order, and that
4622 the siblingIndexes are packed (no gaps), and start at 0.
4624 ### This function is almost identical to
4625 QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes().
4627 void QGraphicsItemPrivate::ensureSequentialSiblingIndex()
4629 if (!sequentialOrdering) {
4630 qSort(children.begin(), children.end(), insertionOrder);
4631 sequentialOrdering = 1;
4632 needSortChildren = 1;
4634 if (holesInSiblingIndex) {
4635 holesInSiblingIndex = 0;
4636 for (int i = 0; i < children.size(); ++i)
4637 children[i]->d_ptr->siblingIndex = i;
4644 inline void QGraphicsItemPrivate::sendScenePosChange()
4648 if (flags & QGraphicsItem::ItemSendsScenePositionChanges)
4649 q->itemChange(QGraphicsItem::ItemScenePositionHasChanged, q->scenePos());
4650 if (scenePosDescendants) {
4651 foreach (QGraphicsItem *item, scene->d_func()->scenePosItems) {
4652 if (q->isAncestorOf(item))
4653 item->itemChange(QGraphicsItem::ItemScenePositionHasChanged, item->scenePos());
4662 Stacks this item before \a sibling, which must be a sibling item (i.e., the
4663 two items must share the same parent item, or must both be toplevel items).
4664 The \a sibling must have the same Z value as this item, otherwise calling
4665 this function will have no effect.
4667 By default, all sibling items are stacked by insertion order (i.e., the
4668 first item you add is drawn before the next item you add). If two items' Z
4669 values are different, then the item with the highest Z value is drawn on
4670 top. When the Z values are the same, the insertion order will decide the
4673 \sa setZValue(), ItemStacksBehindParent, {QGraphicsItem#Sorting}{Sorting}
4675 void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
4677 if (sibling == this)
4679 if (!sibling || d_ptr->parent != sibling->parentItem()) {
4680 qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
4683 QList<QGraphicsItem *> *siblings = d_ptr->parent
4684 ? &d_ptr->parent->d_ptr->children
4685 : (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0);
4687 qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
4691 // First, make sure that the sibling indexes have no holes. This also
4692 // marks the children list for sorting.
4694 d_ptr->parent->d_ptr->ensureSequentialSiblingIndex();
4696 d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
4698 // Only move items with the same Z value, and that need moving.
4699 int siblingIndex = sibling->d_ptr->siblingIndex;
4700 int myIndex = d_ptr->siblingIndex;
4701 if (myIndex >= siblingIndex) {
4702 siblings->move(myIndex, siblingIndex);
4703 // Fixup the insertion ordering.
4704 for (int i = 0; i < siblings->size(); ++i) {
4705 int &index = siblings->at(i)->d_ptr->siblingIndex;
4706 if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
4709 d_ptr->siblingIndex = siblingIndex;
4710 for (int i = 0; i < siblings->size(); ++i) {
4711 int &index = siblings->at(i)->d_ptr->siblingIndex;
4712 if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
4713 siblings->at(i)->d_ptr->siblingOrderChange();
4715 d_ptr->siblingOrderChange();
4720 Returns the bounding rect of this item's descendants (i.e., its
4721 children, their children, etc.) in local coordinates. The
4722 rectangle will contain all descendants after they have been mapped
4723 to local coordinates. If the item has no children, this function
4724 returns an empty QRectF.
4726 This does not include this item's own bounding rect; it only returns
4727 its descendants' accumulated bounding rect. If you need to include this
4728 item's bounding rect, you can add boundingRect() to childrenBoundingRect()
4729 using QRectF::operator|().
4731 This function is linear in complexity; it determines the size of the
4732 returned bounding rect by iterating through all descendants.
4734 \sa boundingRect(), sceneBoundingRect()
4736 QRectF QGraphicsItem::childrenBoundingRect() const
4738 if (!d_ptr->dirtyChildrenBoundingRect)
4739 return d_ptr->childrenBoundingRect;
4741 d_ptr->childrenBoundingRect = QRectF();
4742 d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect, 0);
4743 d_ptr->dirtyChildrenBoundingRect = 0;
4744 return d_ptr->childrenBoundingRect;
4748 \fn virtual QRectF QGraphicsItem::boundingRect() const = 0
4750 This pure virtual function defines the outer bounds of the item as
4751 a rectangle; all painting must be restricted to inside an item's
4752 bounding rect. QGraphicsView uses this to determine whether the
4753 item requires redrawing.
4755 Although the item's shape can be arbitrary, the bounding rect is
4756 always rectangular, and it is unaffected by the items'
4759 If you want to change the item's bounding rectangle, you must first call
4760 prepareGeometryChange(). This notifies the scene of the imminent change,
4761 so that its can update its item geometry index; otherwise, the scene will
4762 be unaware of the item's new geometry, and the results are undefined
4763 (typically, rendering artifacts are left around in the view).
4765 Reimplement this function to let QGraphicsView determine what
4766 parts of the widget, if any, need to be redrawn.
4768 Note: For shapes that paint an outline / stroke, it is important
4769 to include half the pen width in the bounding rect. It is not
4770 necessary to compensate for antialiasing, though.
4774 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 8
4776 \sa boundingRegion(), shape(), contains(), {The Graphics View Coordinate
4777 System}, prepareGeometryChange()
4781 Returns the bounding rect of this item in scene coordinates, by combining
4782 sceneTransform() with boundingRect().
4784 \sa boundingRect(), {The Graphics View Coordinate System}
4786 QRectF QGraphicsItem::sceneBoundingRect() const
4788 // Find translate-only offset
4791 const QGraphicsItem *parentItem = this;
4792 const QGraphicsItemPrivate *itemd;
4794 itemd = parentItem->d_ptr.data();
4795 if (itemd->transformData)
4797 offset += itemd->pos;
4798 } while ((parentItem = itemd->parent));
4800 QRectF br = boundingRect();
4801 br.translate(offset);
4804 if (parentItem->d_ptr->hasTranslateOnlySceneTransform()) {
4805 br.translate(parentItem->d_ptr->sceneTransform.dx(), parentItem->d_ptr->sceneTransform.dy());
4808 return parentItem->d_ptr->sceneTransform.mapRect(br);
4812 Returns the shape of this item as a QPainterPath in local
4813 coordinates. The shape is used for many things, including collision
4814 detection, hit tests, and for the QGraphicsScene::items() functions.
4816 The default implementation calls boundingRect() to return a simple
4817 rectangular shape, but subclasses can reimplement this function to return
4818 a more accurate shape for non-rectangular items. For example, a round item
4819 may choose to return an elliptic shape for better collision detection. For
4822 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 9
4824 The outline of a shape can vary depending on the width and style of the
4825 pen used when drawing. If you want to include this outline in the item's
4826 shape, you can create a shape from the stroke using QPainterPathStroker.
4828 This function is called by the default implementations of contains() and
4831 \sa boundingRect(), contains(), prepareGeometryChange(), QPainterPathStroker
4833 QPainterPath QGraphicsItem::shape() const
4836 path.addRect(boundingRect());
4841 Returns true if this item is clipped. An item is clipped if it has either
4842 set the \l ItemClipsToShape flag, or if it or any of its ancestors has set
4843 the \l ItemClipsChildrenToShape flag.
4845 Clipping affects the item's appearance (i.e., painting), as well as mouse
4846 and hover event delivery.
4848 \sa clipPath(), shape(), setFlags()
4850 bool QGraphicsItem::isClipped() const
4852 Q_D(const QGraphicsItem);
4853 return (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
4854 || (d->flags & QGraphicsItem::ItemClipsToShape);
4860 Returns this item's clip path, or an empty QPainterPath if this item is
4861 not clipped. The clip path constrains the item's appearance and
4862 interaction (i.e., restricts the area the item can draw, and it also
4863 restricts the area that the item receives events).
4865 You can enable clipping by setting the ItemClipsToShape or
4866 ItemClipsChildrenToShape flags. The item's clip path is calculated by
4867 intersecting all clipping ancestors' shapes. If the item sets
4868 ItemClipsToShape, the final clip is intersected with the item's own shape.
4870 \note Clipping introduces a performance penalty for all items involved;
4871 you should generally avoid using clipping if you can (e.g., if your items
4872 always draw inside boundingRect() or shape() boundaries, clipping is not
4875 \sa isClipped(), shape(), setFlags()
4877 QPainterPath QGraphicsItem::clipPath() const
4879 Q_D(const QGraphicsItem);
4881 return QPainterPath();
4883 const QRectF thisBoundingRect(boundingRect());
4884 if (thisBoundingRect.isEmpty())
4885 return QPainterPath();
4888 // Start with the item's bounding rect.
4889 clip.addRect(thisBoundingRect);
4891 if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
4892 const QGraphicsItem *parent = this;
4893 const QGraphicsItem *lastParent = this;
4895 // Intersect any in-between clips starting at the top and moving downwards.
4896 while ((parent = parent->d_ptr->parent)) {
4897 if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
4898 // Map clip to the current parent and intersect with its shape/clipPath
4899 clip = lastParent->itemTransform(parent).map(clip);
4900 clip = clip.intersected(parent->shape());
4903 lastParent = parent;
4906 if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
4910 if (lastParent != this) {
4911 // Map clip back to the item's transform.
4912 // ### what if itemtransform fails
4913 clip = lastParent->itemTransform(this).map(clip);
4917 if (d->flags & ItemClipsToShape)
4918 clip = clip.intersected(shape());
4924 Returns true if this item contains \a point, which is in local
4925 coordinates; otherwise, false is returned. It is most often called from
4926 QGraphicsView to determine what item is under the cursor, and for that
4927 reason, the implementation of this function should be as light-weight as
4930 By default, this function calls shape(), but you can reimplement it in a
4931 subclass to provide a (perhaps more efficient) implementation.
4933 \sa shape(), boundingRect(), collidesWithPath()
4935 bool QGraphicsItem::contains(const QPointF &point) const
4937 return isClipped() ? clipPath().contains(point) : shape().contains(point);
4942 Returns true if this item collides with \a other; otherwise
4945 The \a mode is applied to \a other, and the resulting shape or
4946 bounding rectangle is then compared to this item's shape. The
4947 default value for \a mode is Qt::IntersectsItemShape; \a other
4948 collides with this item if it either intersects, contains, or is
4949 contained by this item's shape (see Qt::ItemSelectionMode for
4952 The default implementation is based on shape intersection, and it calls
4953 shape() on both items. Because the complexity of arbitrary shape-shape
4954 intersection grows with an order of magnitude when the shapes are complex,
4955 this operation can be noticably time consuming. You have the option of
4956 reimplementing this function in a subclass of QGraphicsItem to provide a
4957 custom algorithm. This allows you to make use of natural constraints in
4958 the shapes of your own items, in order to improve the performance of the
4959 collision detection. For instance, two untransformed perfectly circular
4960 items' collision can be determined very efficiently by comparing their
4961 positions and radii.
4963 Keep in mind that when reimplementing this function and calling shape() or
4964 boundingRect() on \a other, the returned coordinates must be mapped to
4965 this item's coordinate system before any intersection can take place.
4967 \sa contains(), shape()
4969 bool QGraphicsItem::collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode) const
4975 // The items share the same clip if their closest clipper is the same, or
4976 // if one clips the other.
4977 bool clips = (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
4978 bool otherClips = (other->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
4979 if (clips || otherClips) {
4980 const QGraphicsItem *closestClipper = isAncestorOf(other) ? this : parentItem();
4981 while (closestClipper && !(closestClipper->flags() & ItemClipsChildrenToShape))
4982 closestClipper = closestClipper->parentItem();
4983 const QGraphicsItem *otherClosestClipper = other->isAncestorOf(this) ? other : other->parentItem();
4984 while (otherClosestClipper && !(otherClosestClipper->flags() & ItemClipsChildrenToShape))
4985 otherClosestClipper = otherClosestClipper->parentItem();
4986 if (closestClipper == otherClosestClipper) {
4987 d_ptr->localCollisionHack = 1;
4988 bool res = collidesWithPath(mapFromItem(other, other->shape()), mode);
4989 d_ptr->localCollisionHack = 0;
4994 QPainterPath otherShape = other->isClipped() ? other->clipPath() : other->shape();
4995 return collidesWithPath(mapFromItem(other, otherShape), mode);
4999 Returns true if this item collides with \a path.
5001 The collision is determined by \a mode. The default value for \a mode is
5002 Qt::IntersectsItemShape; \a path collides with this item if it either
5003 intersects, contains, or is contained by this item's shape.
5005 Note that this function checks whether the item's shape or
5006 bounding rectangle (depending on \a mode) is contained within \a
5007 path, and not whether \a path is contained within the items shape
5008 or bounding rectangle.
5010 \sa collidesWithItem(), contains(), shape()
5012 bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelectionMode mode) const
5014 if (path.isEmpty()) {
5015 // No collision with empty paths.
5019 QRectF rectA(boundingRect());
5020 _q_adjustRect(&rectA);
5021 QRectF rectB(path.controlPointRect());
5022 _q_adjustRect(&rectB);
5023 if (!rectA.intersects(rectB)) {
5024 // This we can determine efficiently. If the two rects neither
5025 // intersect nor contain eachother, then the two items do not collide.
5029 // For further testing, we need this item's shape or bounding rect.
5030 QPainterPath thisShape;
5031 if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape)
5032 thisShape = (isClipped() && !d_ptr->localCollisionHack) ? clipPath() : shape();
5034 thisShape.addRect(rectA);
5036 if (thisShape == QPainterPath()) {
5037 // Empty shape? No collision.
5041 // Use QPainterPath boolean operations to determine the collision, O(N*logN).
5042 if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
5043 return path.intersects(thisShape);
5044 return path.contains(thisShape);
5048 Returns a list of all items that collide with this item.
5050 The way collisions are detected is determined by applying \a mode
5051 to items that are compared to this item, i.e., each item's shape
5052 or bounding rectangle is checked against this item's shape. The
5053 default value for \a mode is Qt::IntersectsItemShape.
5055 \sa collidesWithItem()
5057 QList<QGraphicsItem *> QGraphicsItem::collidingItems(Qt::ItemSelectionMode mode) const
5060 return d_ptr->scene->collidingItems(this, mode);
5061 return QList<QGraphicsItem *>();
5065 Returns true if this item's bounding rect is completely obscured by the
5066 opaque shape of any of colliding items above it (i.e., with a higher Z
5067 value than this item).
5069 Its implementation is based on calling isObscuredBy(), which you can
5070 reimplement to provide a custom obscurity algorithm.
5074 bool QGraphicsItem::isObscured() const
5076 return isObscured(QRectF());
5082 Item obscurity helper function.
5084 Returns true if the subrect \a rect of \a item's bounding rect is obscured
5085 by \a other (i.e., \a other's opaque area covers \a item's \a rect
5086 completely. \a other is assumed to already be "on top of" \a item
5087 wrt. stacking order.
5089 static bool qt_QGraphicsItem_isObscured(const QGraphicsItem *item,
5090 const QGraphicsItem *other,
5093 return other->mapToItem(item, other->opaqueArea()).contains(rect);
5100 Returns true if \a rect is completely obscured by the opaque shape of any
5101 of colliding items above it (i.e., with a higher Z value than this item).
5103 Unlike the default isObscured() function, this function does not call
5108 bool QGraphicsItem::isObscured(const QRectF &rect) const
5110 Q_D(const QGraphicsItem);
5114 QRectF br = boundingRect();
5115 QRectF testRect = rect.isNull() ? br : rect;
5117 foreach (QGraphicsItem *item, d->scene->items(mapToScene(br), Qt::IntersectsItemBoundingRect)) {
5120 if (qt_QGraphicsItem_isObscured(this, item, testRect))
5127 \fn bool QGraphicsItem::isObscured(qreal x, qreal y, qreal w, qreal h) const
5130 This convenience function is equivalent to calling isObscured(QRectF(\a x, \a y, \a w, \a h)).
5134 Returns true if this item's bounding rect is completely obscured by the
5135 opaque shape of \a item.
5137 The base implementation maps \a item's opaqueArea() to this item's
5138 coordinate system, and then checks if this item's boundingRect() is fully
5139 contained within the mapped shape.
5141 You can reimplement this function to provide a custom algorithm for
5142 determining whether this item is obscured by \a item.
5144 \sa opaqueArea(), isObscured()
5146 bool QGraphicsItem::isObscuredBy(const QGraphicsItem *item) const
5150 return qt_closestItemFirst(item, this)
5151 && qt_QGraphicsItem_isObscured(this, item, boundingRect());
5155 This virtual function returns a shape representing the area where this
5156 item is opaque. An area is opaque if it is filled using an opaque brush or
5157 color (i.e., not transparent).
5159 This function is used by isObscuredBy(), which is called by underlying
5160 items to determine if they are obscured by this item.
5162 The default implementation returns an empty QPainterPath, indicating that
5163 this item is completely transparent and does not obscure any other items.
5165 \sa isObscuredBy(), isObscured(), shape()
5167 QPainterPath QGraphicsItem::opaqueArea() const
5169 return QPainterPath();
5175 Returns the bounding region for this item. The coordinate space of the
5176 returned region depends on \a itemToDeviceTransform. If you pass an
5177 identity QTransform as a parameter, this function will return a local
5180 The bounding region describes a coarse outline of the item's visual
5181 contents. Although it's expensive to calculate, it's also more precise
5182 than boundingRect(), and it can help to avoid unnecessary repainting when
5183 an item is updated. This is particularly efficient for thin items (e.g.,
5184 lines or simple polygons). You can tune the granularity for the bounding
5185 region by calling setBoundingRegionGranularity(). The default granularity
5186 is 0; in which the item's bounding region is the same as its bounding
5189 \a itemToDeviceTransform is the transformation from item coordinates to
5190 device coordinates. If you want this function to return a QRegion in scene
5191 coordinates, you can pass sceneTransform() as an argument.
5193 \sa boundingRegionGranularity()
5195 QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) const
5197 // ### Ideally we would have a better way to generate this region,
5198 // preferably something in the lines of QPainterPath::toRegion(QTransform)
5199 // coupled with a way to generate a painter path from a set of painter
5200 // operations (e.g., QPicture::toPainterPath() or so). The current
5201 // approach generates a bitmap with the size of the item's bounding rect
5202 // in device coordinates, scaled by b.r.granularity, then paints the item
5203 // into the bitmap, converts the result to a QRegion and scales the region
5204 // back to device space with inverse granularity.
5205 qreal granularity = boundingRegionGranularity();
5206 QRect deviceRect = itemToDeviceTransform.mapRect(boundingRect()).toRect();
5207 _q_adjustRect(&deviceRect);
5208 if (granularity == 0.0)
5209 return QRegion(deviceRect);
5212 QSize bitmapSize(qMax(1, int(deviceRect.width() * granularity) + pad * 2),
5213 qMax(1, int(deviceRect.height() * granularity) + pad * 2));
5214 QImage mask(bitmapSize, QImage::Format_ARGB32_Premultiplied);
5217 p.setRenderHints(QPainter::Antialiasing);
5219 // Transform painter (### this code is from QGraphicsScene::drawItemHelper
5220 // and doesn't work properly with perspective transformations).
5221 QPointF viewOrigo = itemToDeviceTransform.map(QPointF(0, 0));
5222 QPointF offset = viewOrigo - deviceRect.topLeft();
5223 p.scale(granularity, granularity);
5224 p.translate(offset);
5225 p.translate(pad, pad);
5226 p.setWorldTransform(itemToDeviceTransform, true);
5227 p.translate(itemToDeviceTransform.inverted().map(QPointF(0, 0)));
5230 QStyleOptionGraphicsItem option;
5231 const_cast<QGraphicsItem *>(this)->paint(&p, &option, 0);
5234 // Transform QRegion back to device space
5235 QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity);
5237 QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0));
5238 foreach (const QRect &rect, QRegion( colorMask ).rects()) {
5239 QRect xrect = unscale.mapRect(rect).translated(deviceRect.topLeft() - QPoint(pad, pad));
5240 r += xrect.adjusted(-1, -1, 1, 1) & deviceRect;
5248 Returns the item's bounding region granularity; a value between and
5249 including 0 and 1. The default value is 0 (i.e., the lowest granularity,
5250 where the bounding region corresponds to the item's bounding rectangle).
5256 \sa setBoundingRegionGranularity()
5258 qreal QGraphicsItem::boundingRegionGranularity() const
5260 return d_ptr->hasBoundingRegionGranularity
5261 ? qvariant_cast<qreal>(d_ptr->extra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity))
5267 Sets the bounding region granularity to \a granularity; a value between
5268 and including 0 and 1. The default value is 0 (i.e., the lowest
5269 granularity, where the bounding region corresponds to the item's bounding
5272 The granularity is used by boundingRegion() to calculate how fine the
5273 bounding region of the item should be. The highest achievable granularity
5274 is 1, where boundingRegion() will return the finest outline possible for
5275 the respective device (e.g., for a QGraphicsView viewport, this gives you
5276 a pixel-perfect bounding region). The lowest possible granularity is
5277 0. The value of \a granularity describes the ratio between device
5278 resolution and the resolution of the bounding region (e.g., a value of
5279 0.25 will provide a region where each chunk corresponds to 4x4 device
5282 \sa boundingRegionGranularity()
5284 void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
5286 if (granularity < 0.0 || granularity > 1.0) {
5287 qWarning("QGraphicsItem::setBoundingRegionGranularity: invalid granularity %g", granularity);
5290 if (granularity == 0.0) {
5291 d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity);
5292 d_ptr->hasBoundingRegionGranularity = 0;
5295 d_ptr->hasBoundingRegionGranularity = 1;
5296 d_ptr->setExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity,
5297 QVariant::fromValue<qreal>(granularity));
5301 \fn virtual void QGraphicsItem::paint(QPainter *painter, const
5302 QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0
5304 This function, which is usually called by QGraphicsView, paints the
5305 contents of an item in local coordinates.
5307 Reimplement this function in a QGraphicsItem subclass to provide the
5308 item's painting implementation, using \a painter. The \a option parameter
5309 provides style options for the item, such as its state, exposed area and
5310 its level-of-detail hints. The \a widget argument is optional. If
5311 provided, it points to the widget that is being painted on; otherwise, it
5312 is 0. For cached painting, \a widget is always 0.
5314 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 10
5316 The painter's pen is 0-width by default, and its pen is initialized to the
5317 QPalette::Text brush from the paint device's palette. The brush is
5318 initialized to QPalette::Window.
5320 Make sure to constrain all painting inside the boundaries of
5321 boundingRect() to avoid rendering artifacts (as QGraphicsView does not
5322 clip the painter for you). In particular, when QPainter renders the
5323 outline of a shape using an assigned QPen, half of the outline will be
5324 drawn outside, and half inside, the shape you're rendering (e.g., with a
5325 pen width of 2 units, you must draw outlines 1 unit inside
5326 boundingRect()). QGraphicsItem does not support use of cosmetic pens with
5329 All painting is done in local coordinates.
5331 \sa setCacheMode(), QPen::width(), {Item Coordinates}, ItemUsesExtendedStyleOption
5336 Returns true if we can discard an update request; otherwise false.
5338 bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreVisibleBit, bool ignoreDirtyBit,
5339 bool ignoreOpacity) const
5341 // No scene, or if the scene is updating everything, means we have nothing
5342 // to do. The only exception is if the scene tracks the growing scene rect.
5344 || (!visible && !ignoreVisibleBit && !this->ignoreVisible)
5345 || (!ignoreDirtyBit && fullUpdatePending)
5346 || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent());
5352 int QGraphicsItemPrivate::depth() const
5354 if (itemDepth == -1)
5355 const_cast<QGraphicsItemPrivate *>(this)->resolveDepth();
5363 #ifndef QT_NO_GRAPHICSEFFECT
5364 void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
5366 QGraphicsItemPrivate *itemPrivate = this;
5368 if (itemPrivate->graphicsEffect) {
5369 itemPrivate->notifyInvalidated = 1;
5371 if (!itemPrivate->updateDueToGraphicsEffect)
5372 static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
5374 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
5377 void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason)
5379 if (!mayHaveChildWithGraphicsEffect)
5382 for (int i = 0; i < children.size(); ++i) {
5383 QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data();
5384 if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity))
5386 if (childPrivate->graphicsEffect) {
5387 childPrivate->notifyInvalidated = 1;
5388 static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
5391 childPrivate->invalidateChildGraphicsEffectsRecursively(reason);
5394 #endif //QT_NO_GRAPHICSEFFECT
5399 void QGraphicsItemPrivate::invalidateDepthRecursively()
5401 if (itemDepth == -1)
5405 for (int i = 0; i < children.size(); ++i)
5406 children.at(i)->d_ptr->invalidateDepthRecursively();
5412 Resolves the stacking depth of this object and all its ancestors.
5414 void QGraphicsItemPrivate::resolveDepth()
5419 if (parent->d_ptr->itemDepth == -1)
5420 parent->d_ptr->resolveDepth();
5421 itemDepth = parent->d_ptr->itemDepth + 1;
5428 ### This function is almost identical to
5429 QGraphicsScenePrivate::registerTopLevelItem().
5431 void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
5433 // Remove all holes from the sibling index list. Now the max index
5434 // number is equal to the size of the children list.
5435 ensureSequentialSiblingIndex();
5436 needSortChildren = 1; // ### maybe 0
5437 child->d_ptr->siblingIndex = children.size();
5438 children.append(child);
5440 emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
5446 ### This function is almost identical to
5447 QGraphicsScenePrivate::unregisterTopLevelItem().
5449 void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
5451 // When removing elements in the middle of the children list,
5452 // there will be a "gap" in the list of sibling indexes (0,1,3,4).
5453 if (!holesInSiblingIndex)
5454 holesInSiblingIndex = child->d_ptr->siblingIndex != children.size() - 1;
5455 if (sequentialOrdering && !holesInSiblingIndex)
5456 children.removeAt(child->d_ptr->siblingIndex);
5458 children.removeOne(child);
5459 // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
5460 // the child is not guaranteed to be at the index after the list is sorted.
5461 // (see ensureSortedChildren()).
5462 child->d_ptr->siblingIndex = -1;
5464 emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
5470 QGraphicsItemCache *QGraphicsItemPrivate::maybeExtraItemCache() const
5472 return (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5478 QGraphicsItemCache *QGraphicsItemPrivate::extraItemCache() const
5480 QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5482 QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this);
5483 c = new QGraphicsItemCache;
5484 that->setExtra(ExtraCacheData, QVariant::fromValue<void *>(c));
5492 void QGraphicsItemPrivate::removeExtraItemCache()
5494 QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5499 unsetExtra(ExtraCacheData);
5502 void QGraphicsItemPrivate::updatePaintedViewBoundingRects(bool updateChildren)
5507 for (int i = 0; i < scene->d_func()->views.size(); ++i) {
5508 QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func();
5509 QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport);
5510 rect.translate(viewPrivate->dirtyScrollOffset);
5511 viewPrivate->updateRect(rect);
5514 if (updateChildren) {
5515 for (int i = 0; i < children.size(); ++i)
5516 children.at(i)->d_ptr->updatePaintedViewBoundingRects(true);
5520 // Traverses all the ancestors up to the top-level and updates the pointer to
5521 // always point to the top-most item that has a dirty scene transform.
5522 // It then backtracks to the top-most dirty item and start calculating the
5523 // scene transform by combining the item's transform (+pos) with the parent's
5524 // cached scene transform (which we at this point know for sure is valid).
5525 void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem)
5527 Q_ASSERT(topMostDirtyItem);
5529 if (dirtySceneTransform)
5530 *topMostDirtyItem = q_ptr;
5533 parent->d_ptr->ensureSceneTransformRecursive(topMostDirtyItem);
5535 if (*topMostDirtyItem == q_ptr) {
5536 if (!dirtySceneTransform)
5537 return; // OK, neither my ancestors nor I have dirty scene transforms.
5538 *topMostDirtyItem = 0;
5539 } else if (*topMostDirtyItem) {
5540 return; // Continue backtrack.
5543 // This item and all its descendants have dirty scene transforms.
5544 // We're about to validate this item's scene transform, so we have to
5545 // invalidate all the children; otherwise there's no way for the descendants
5546 // to detect that the ancestor has changed.
5547 invalidateChildrenSceneTransform();
5549 // COMBINE my transform with the parent's scene transform.
5550 updateSceneTransformFromParent();
5551 Q_ASSERT(!dirtySceneTransform);
5557 void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
5559 // Update focus child chain. Stop at panels, or if this item
5560 // is hidden, stop at the first item with a visible parent.
5561 QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
5562 if (parent->panel() != q_ptr->panel())
5566 // Clear any existing ancestor's subFocusItem.
5567 if (parent != q_ptr && parent->d_ptr->subFocusItem) {
5568 if (parent->d_ptr->subFocusItem == q_ptr)
5570 parent->d_ptr->subFocusItem->d_ptr->clearSubFocus(0, stopItem);
5572 parent->d_ptr->subFocusItem = q_ptr;
5573 parent->d_ptr->subFocusItemChange();
5574 } while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
5576 if (scene && !scene->isActive()) {
5577 scene->d_func()->passiveFocusItem = subFocusItem;
5578 scene->d_func()->lastFocusItem = subFocusItem;
5585 void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
5587 // Reset sub focus chain.
5588 QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
5590 if (parent->d_ptr->subFocusItem != q_ptr)
5592 parent->d_ptr->subFocusItem = 0;
5593 if (parent != stopItem && !parent->isAncestorOf(stopItem))
5594 parent->d_ptr->subFocusItemChange();
5595 } while (!parent->isPanel() && (parent = parent->d_ptr->parent));
5601 Sets the focusProxy pointer to 0 for all items that have this item as their
5602 focusProxy. ### Qt 5: Use QPointer instead.
5604 void QGraphicsItemPrivate::resetFocusProxy()
5606 for (int i = 0; i < focusProxyRefs.size(); ++i)
5607 *focusProxyRefs.at(i) = 0;
5608 focusProxyRefs.clear();
5614 Subclasses can reimplement this function to be notified when subFocusItem
5617 void QGraphicsItemPrivate::subFocusItemChange()
5624 Subclasses can reimplement this function to be notified when an item
5625 becomes a focusScopeItem (or is no longer a focusScopeItem).
5627 void QGraphicsItemPrivate::focusScopeItemChange(bool isSubFocusItem)
5629 Q_UNUSED(isSubFocusItem);
5635 Subclasses can reimplement this function to be notified when its
5636 siblingIndex order is changed.
5638 void QGraphicsItemPrivate::siblingOrderChange()
5645 Tells us if it is a proxy widget
5647 bool QGraphicsItemPrivate::isProxyWidget() const
5653 Schedules a redraw of the area covered by \a rect in this item. You can
5654 call this function whenever your item needs to be redrawn, such as if it
5655 changes appearance or size.
5657 This function does not cause an immediate paint; instead it schedules a
5658 paint request that is processed by QGraphicsView after control reaches the
5659 event loop. The item will only be redrawn if it is visible in any
5662 As a side effect of the item being repainted, other items that overlap the
5663 area \a rect may also be repainted.
5665 If the item is invisible (i.e., isVisible() returns false), this function
5668 \sa paint(), boundingRect()
5670 void QGraphicsItem::update(const QRectF &rect)
5672 if (rect.isEmpty() && !rect.isNull())
5675 // Make sure we notify effects about invalidated source.
5676 #ifndef QT_NO_GRAPHICSEFFECT
5677 d_ptr->invalidateParentGraphicsEffectsRecursively();
5678 #endif //QT_NO_GRAPHICSEFFECT
5680 if (CacheMode(d_ptr->cacheMode) != NoCache) {
5681 // Invalidate cache.
5682 QGraphicsItemCache *cache = d_ptr->extraItemCache();
5683 if (!cache->allExposed) {
5684 if (rect.isNull()) {
5685 cache->allExposed = true;
5686 cache->exposed.clear();
5688 cache->exposed.append(rect);
5691 // Only invalidate cache; item is already dirty.
5692 if (d_ptr->fullUpdatePending)
5697 d_ptr->scene->d_func()->markDirty(this, rect);
5702 Scrolls the contents of \a rect by \a dx, \a dy. If \a rect is a null rect
5703 (the default), the item's bounding rect is scrolled.
5705 Scrolling provides a fast alternative to simply redrawing when the
5706 contents of the item (or parts of the item) are shifted vertically or
5707 horizontally. Depending on the current transformation and the capabilities
5708 of the paint device (i.e., the viewport), this operation may consist of
5709 simply moving pixels from one location to another using memmove(). In most
5710 cases this is faster than rerendering the entire area.
5712 After scrolling, the item will issue an update for the newly exposed
5713 areas. If scrolling is not supported (e.g., you are rendering to an OpenGL
5714 viewport, which does not benefit from scroll optimizations), this function
5715 is equivalent to calling update(\a rect).
5717 \b{Note:} Scrolling is only supported when QGraphicsItem::ItemCoordinateCache
5718 is enabled; in all other cases calling this function is equivalent to calling
5719 update(\a rect). If you for sure know that the item is opaque and not overlapped
5720 by other items, you can map the \a rect to viewport coordinates and scroll the
5723 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 19
5727 void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
5730 if (dx == 0.0 && dy == 0.0)
5735 // Accelerated scrolling means moving pixels from one location to another
5736 // and only redraw the newly exposed area. The following requirements must
5737 // be fulfilled in order to do that:
5739 // 1) Item is opaque.
5740 // 2) Item is not overlapped by other items.
5742 // There's (yet) no way to detect whether an item is opaque or not, which means
5743 // we cannot do accelerated scrolling unless the cache is enabled. In case of using
5744 // DeviceCoordinate cache we also have to take the device transform into account in
5745 // order to determine whether we can do accelerated scrolling or not. That's left out
5746 // for simplicity here, but it is definitely something we can consider in the future
5747 // as a performance improvement.
5748 if (d->cacheMode != QGraphicsItem::ItemCoordinateCache
5749 || !qFuzzyIsNull(dx - int(dx)) || !qFuzzyIsNull(dy - int(dy))) {
5754 QGraphicsItemCache *cache = d->extraItemCache();
5755 if (cache->allExposed || cache->fixedSize.isValid()) {
5756 // Cache is either invalidated or item is scaled (see QGraphicsItem::setCacheMode).
5761 // Find pixmap in cache.
5762 QPixmap cachedPixmap;
5763 if (!QPixmapCache::find(cache->key, &cachedPixmap)) {
5768 QRect scrollRect = (rect.isNull() ? boundingRect() : rect).toAlignedRect();
5769 if (!scrollRect.intersects(cache->boundingRect))
5770 return; // Nothing to scroll.
5772 // Remove from cache to avoid deep copy when modifying.
5773 QPixmapCache::remove(cache->key);
5776 cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed);
5778 // Reinsert into cache.
5779 cache->key = QPixmapCache::insert(cachedPixmap);
5781 // Translate the existing expose.
5782 for (int i = 0; i < cache->exposed.size(); ++i) {
5783 QRectF &e = cache->exposed[i];
5784 if (!rect.isNull() && !e.intersects(rect))
5786 e.translate(dx, dy);
5789 // Append newly exposed areas. Note that the exposed region is currently
5790 // in pixmap coordinates, so we have to translate it to item coordinates.
5791 exposed.translate(cache->boundingRect.topLeft());
5792 const QVector<QRect> exposedRects = exposed.rects();
5793 for (int i = 0; i < exposedRects.size(); ++i)
5794 cache->exposed += exposedRects.at(i);
5796 // Trigger update. This will redraw the newly exposed area and make sure
5797 // the pixmap is re-blitted in case there are overlapping items.
5798 d->scene->d_func()->markDirty(this, rect);
5802 \fn void QGraphicsItem::update(qreal x, qreal y, qreal width, qreal height)
5805 This convenience function is equivalent to calling update(QRectF(\a x, \a
5806 y, \a width, \a height)).
5810 Maps the point \a point, which is in this item's coordinate system, to \a
5811 item's coordinate system, and returns the mapped coordinate.
5813 If \a item is 0, this function returns the same as mapToScene().
5815 \sa itemTransform(), mapToParent(), mapToScene(), transform(), mapFromItem(), {The Graphics
5816 View Coordinate System}
5818 QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF &point) const
5821 return itemTransform(item).map(point);
5822 return mapToScene(point);
5826 \fn QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y) const
5829 This convenience function is equivalent to calling mapToItem(\a item,
5830 QPointF(\a x, \a y)).
5834 Maps the point \a point, which is in this item's coordinate system, to its
5835 parent's coordinate system, and returns the mapped coordinate. If the item
5836 has no parent, \a point will be mapped to the scene's coordinate system.
5838 \sa mapToItem(), mapToScene(), transform(), mapFromParent(), {The Graphics
5839 View Coordinate System}
5841 QPointF QGraphicsItem::mapToParent(const QPointF &point) const
5844 if (!d_ptr->transformData)
5845 return point + d_ptr->pos;
5846 return d_ptr->transformToParent().map(point);
5850 \fn QPointF QGraphicsItem::mapToParent(qreal x, qreal y) const
5853 This convenience function is equivalent to calling mapToParent(QPointF(\a
5858 Maps the point \a point, which is in this item's coordinate system, to the
5859 scene's coordinate system, and returns the mapped coordinate.
5861 \sa mapToItem(), mapToParent(), transform(), mapFromScene(), {The Graphics
5862 View Coordinate System}
5864 QPointF QGraphicsItem::mapToScene(const QPointF &point) const
5866 if (d_ptr->hasTranslateOnlySceneTransform())
5867 return QPointF(point.x() + d_ptr->sceneTransform.dx(), point.y() + d_ptr->sceneTransform.dy());
5868 return d_ptr->sceneTransform.map(point);
5872 \fn QPointF QGraphicsItem::mapToScene(qreal x, qreal y) const
5875 This convenience function is equivalent to calling mapToScene(QPointF(\a
5880 Maps the rectangle \a rect, which is in this item's coordinate system, to
5881 \a item's coordinate system, and returns the mapped rectangle as a polygon.
5883 If \a item is 0, this function returns the same as mapToScene().
5885 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5886 Graphics View Coordinate System}
5888 QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect) const
5891 return itemTransform(item).map(rect);
5892 return mapToScene(rect);
5896 \fn QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
5899 This convenience function is equivalent to calling mapToItem(item, QRectF(\a x, \a y, \a w, \a h)).
5903 Maps the rectangle \a rect, which is in this item's coordinate system, to
5904 its parent's coordinate system, and returns the mapped rectangle as a
5905 polygon. If the item has no parent, \a rect will be mapped to the scene's
5908 \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
5911 QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
5914 if (!d_ptr->transformData)
5915 return rect.translated(d_ptr->pos);
5916 return d_ptr->transformToParent().map(rect);
5920 \fn QPolygonF QGraphicsItem::mapToParent(qreal x, qreal y, qreal w, qreal h) const
5923 This convenience function is equivalent to calling mapToParent(QRectF(\a x, \a y, \a w, \a h)).
5927 Maps the rectangle \a rect, which is in this item's coordinate system, to
5928 the scene's coordinate system, and returns the mapped rectangle as a polygon.
5930 \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
5933 QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const
5935 if (d_ptr->hasTranslateOnlySceneTransform())
5936 return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
5937 return d_ptr->sceneTransform.map(rect);
5941 \fn QPolygonF QGraphicsItem::mapToScene(qreal x, qreal y, qreal w, qreal h) const
5944 This convenience function is equivalent to calling mapToScene(QRectF(\a x, \a y, \a w, \a h)).
5950 Maps the rectangle \a rect, which is in this item's coordinate system, to
5951 \a item's coordinate system, and returns the mapped rectangle as a new
5952 rectangle (i.e., the bounding rectangle of the resulting polygon).
5954 If \a item is 0, this function returns the same as mapRectToScene().
5956 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5957 Graphics View Coordinate System}
5959 QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, const QRectF &rect) const
5962 return itemTransform(item).mapRect(rect);
5963 return mapRectToScene(rect);
5967 \fn QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
5970 This convenience function is equivalent to calling mapRectToItem(item, QRectF(\a x, \a y, \a w, \a h)).
5976 Maps the rectangle \a rect, which is in this item's coordinate system, to
5977 its parent's coordinate system, and returns the mapped rectangle as a new
5978 rectangle (i.e., the bounding rectangle of the resulting polygon).
5980 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5981 Graphics View Coordinate System}
5983 QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const
5986 if (!d_ptr->transformData)
5987 return rect.translated(d_ptr->pos);
5988 return d_ptr->transformToParent().mapRect(rect);
5992 \fn QRectF QGraphicsItem::mapRectToParent(qreal x, qreal y, qreal w, qreal h) const
5995 This convenience function is equivalent to calling mapRectToParent(QRectF(\a x, \a y, \a w, \a h)).
6001 Maps the rectangle \a rect, which is in this item's coordinate system, to
6002 the scene coordinate system, and returns the mapped rectangle as a new
6003 rectangle (i.e., the bounding rectangle of the resulting polygon).
6005 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6006 Graphics View Coordinate System}
6008 QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const
6010 if (d_ptr->hasTranslateOnlySceneTransform())
6011 return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6012 return d_ptr->sceneTransform.mapRect(rect);
6016 \fn QRectF QGraphicsItem::mapRectToScene(qreal x, qreal y, qreal w, qreal h) const
6019 This convenience function is equivalent to calling mapRectToScene(QRectF(\a x, \a y, \a w, \a h)).
6025 Maps the rectangle \a rect, which is in \a item's coordinate system, to
6026 this item's coordinate system, and returns the mapped rectangle as a new
6027 rectangle (i.e., the bounding rectangle of the resulting polygon).
6029 If \a item is 0, this function returns the same as mapRectFromScene().
6031 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6032 Graphics View Coordinate System}
6034 QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, const QRectF &rect) const
6037 return item->itemTransform(this).mapRect(rect);
6038 return mapRectFromScene(rect);
6042 \fn QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
6045 This convenience function is equivalent to calling mapRectFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
6051 Maps the rectangle \a rect, which is in this item's parent's coordinate
6052 system, to this item's coordinate system, and returns the mapped rectangle
6053 as a new rectangle (i.e., the bounding rectangle of the resulting
6056 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6057 Graphics View Coordinate System}
6059 QRectF QGraphicsItem::mapRectFromParent(const QRectF &rect) const
6062 if (!d_ptr->transformData)
6063 return rect.translated(-d_ptr->pos);
6064 return d_ptr->transformToParent().inverted().mapRect(rect);
6068 \fn QRectF QGraphicsItem::mapRectFromParent(qreal x, qreal y, qreal w, qreal h) const
6071 This convenience function is equivalent to calling mapRectFromParent(QRectF(\a x, \a y, \a w, \a h)).
6077 Maps the rectangle \a rect, which is in scene coordinates, to this item's
6078 coordinate system, and returns the mapped rectangle as a new rectangle
6079 (i.e., the bounding rectangle of the resulting polygon).
6081 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6082 Graphics View Coordinate System}
6084 QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const
6086 if (d_ptr->hasTranslateOnlySceneTransform())
6087 return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6088 return d_ptr->sceneTransform.inverted().mapRect(rect);
6092 \fn QRectF QGraphicsItem::mapRectFromScene(qreal x, qreal y, qreal w, qreal h) const
6095 This convenience function is equivalent to calling mapRectFromScene(QRectF(\a x, \a y, \a w, \a h)).
6099 Maps the polygon \a polygon, which is in this item's coordinate system, to
6100 \a item's coordinate system, and returns the mapped polygon.
6102 If \a item is 0, this function returns the same as mapToScene().
6104 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6105 Graphics View Coordinate System}
6107 QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &polygon) const
6110 return itemTransform(item).map(polygon);
6111 return mapToScene(polygon);
6115 Maps the polygon \a polygon, which is in this item's coordinate system, to
6116 its parent's coordinate system, and returns the mapped polygon. If the
6117 item has no parent, \a polygon will be mapped to the scene's coordinate
6120 \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
6123 QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
6126 if (!d_ptr->transformData)
6127 return polygon.translated(d_ptr->pos);
6128 return d_ptr->transformToParent().map(polygon);
6132 Maps the polygon \a polygon, which is in this item's coordinate system, to
6133 the scene's coordinate system, and returns the mapped polygon.
6135 \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
6138 QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const
6140 if (d_ptr->hasTranslateOnlySceneTransform())
6141 return polygon.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6142 return d_ptr->sceneTransform.map(polygon);
6146 Maps the path \a path, which is in this item's coordinate system, to
6147 \a item's coordinate system, and returns the mapped path.
6149 If \a item is 0, this function returns the same as mapToScene().
6151 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6152 Graphics View Coordinate System}
6154 QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterPath &path) const
6157 return itemTransform(item).map(path);
6158 return mapToScene(path);
6162 Maps the path \a path, which is in this item's coordinate system, to
6163 its parent's coordinate system, and returns the mapped path. If the
6164 item has no parent, \a path will be mapped to the scene's coordinate
6167 \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
6170 QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
6173 if (!d_ptr->transformData)
6174 return path.translated(d_ptr->pos);
6175 return d_ptr->transformToParent().map(path);
6179 Maps the path \a path, which is in this item's coordinate system, to
6180 the scene's coordinate system, and returns the mapped path.
6182 \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
6185 QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const
6187 if (d_ptr->hasTranslateOnlySceneTransform())
6188 return path.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6189 return d_ptr->sceneTransform.map(path);
6193 Maps the point \a point, which is in \a item's coordinate system, to this
6194 item's coordinate system, and returns the mapped coordinate.
6196 If \a item is 0, this function returns the same as mapFromScene().
6198 \sa itemTransform(), mapFromParent(), mapFromScene(), transform(), mapToItem(), {The Graphics
6199 View Coordinate System}
6201 QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &point) const
6204 return item->itemTransform(this).map(point);
6205 return mapFromScene(point);
6209 \fn QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y) const
6212 This convenience function is equivalent to calling mapFromItem(\a item,
6213 QPointF(\a x, \a y)).
6217 Maps the point \a point, which is in this item's parent's coordinate
6218 system, to this item's coordinate system, and returns the mapped
6221 \sa mapFromItem(), mapFromScene(), transform(), mapToParent(), {The Graphics
6222 View Coordinate System}
6224 QPointF QGraphicsItem::mapFromParent(const QPointF &point) const
6227 if (d_ptr->transformData)
6228 return d_ptr->transformToParent().inverted().map(point);
6229 return point - d_ptr->pos;
6233 \fn QPointF QGraphicsItem::mapFromParent(qreal x, qreal y) const
6236 This convenience function is equivalent to calling
6237 mapFromParent(QPointF(\a x, \a y)).
6241 Maps the point \a point, which is in this item's scene's coordinate
6242 system, to this item's coordinate system, and returns the mapped
6245 \sa mapFromItem(), mapFromParent(), transform(), mapToScene(), {The Graphics
6246 View Coordinate System}
6248 QPointF QGraphicsItem::mapFromScene(const QPointF &point) const
6250 if (d_ptr->hasTranslateOnlySceneTransform())
6251 return QPointF(point.x() - d_ptr->sceneTransform.dx(), point.y() - d_ptr->sceneTransform.dy());
6252 return d_ptr->sceneTransform.inverted().map(point);
6256 \fn QPointF QGraphicsItem::mapFromScene(qreal x, qreal y) const
6259 This convenience function is equivalent to calling mapFromScene(QPointF(\a
6264 Maps the rectangle \a rect, which is in \a item's coordinate system, to
6265 this item's coordinate system, and returns the mapped rectangle as a
6268 If \a item is 0, this function returns the same as mapFromScene()
6270 \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The Graphics View Coordinate
6273 QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QRectF &rect) const
6276 return item->itemTransform(this).map(rect);
6277 return mapFromScene(rect);
6281 \fn QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
6284 This convenience function is equivalent to calling mapFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
6288 Maps the rectangle \a rect, which is in this item's parent's coordinate
6289 system, to this item's coordinate system, and returns the mapped rectangle
6292 \sa mapToParent(), mapFromItem(), transform(), {The Graphics View Coordinate
6295 QPolygonF QGraphicsItem::mapFromParent(const QRectF &rect) const
6298 if (!d_ptr->transformData)
6299 return rect.translated(-d_ptr->pos);
6300 return d_ptr->transformToParent().inverted().map(rect);
6304 \fn QPolygonF QGraphicsItem::mapFromParent(qreal x, qreal y, qreal w, qreal h) const
6307 This convenience function is equivalent to calling mapFromItem(QRectF(\a x, \a y, \a w, \a h)).
6311 Maps the rectangle \a rect, which is in this item's scene's coordinate
6312 system, to this item's coordinate system, and returns the mapped rectangle
6315 \sa mapToScene(), mapFromItem(), transform(), {The Graphics View Coordinate
6318 QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const
6320 if (d_ptr->hasTranslateOnlySceneTransform())
6321 return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6322 return d_ptr->sceneTransform.inverted().map(rect);
6326 \fn QPolygonF QGraphicsItem::mapFromScene(qreal x, qreal y, qreal w, qreal h) const
6329 This convenience function is equivalent to calling mapFromScene(QRectF(\a x, \a y, \a w, \a h)).
6333 Maps the polygon \a polygon, which is in \a item's coordinate system, to
6334 this item's coordinate system, and returns the mapped polygon.
6336 If \a item is 0, this function returns the same as mapFromScene().
6338 \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The
6339 Graphics View Coordinate System}
6341 QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPolygonF &polygon) const
6344 return item->itemTransform(this).map(polygon);
6345 return mapFromScene(polygon);
6349 Maps the polygon \a polygon, which is in this item's parent's coordinate
6350 system, to this item's coordinate system, and returns the mapped polygon.
6352 \sa mapToParent(), mapToItem(), transform(), {The Graphics View Coordinate
6355 QPolygonF QGraphicsItem::mapFromParent(const QPolygonF &polygon) const
6358 if (!d_ptr->transformData)
6359 return polygon.translated(-d_ptr->pos);
6360 return d_ptr->transformToParent().inverted().map(polygon);
6364 Maps the polygon \a polygon, which is in this item's scene's coordinate
6365 system, to this item's coordinate system, and returns the mapped polygon.
6367 \sa mapToScene(), mapFromParent(), transform(), {The Graphics View Coordinate
6370 QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const
6372 if (d_ptr->hasTranslateOnlySceneTransform())
6373 return polygon.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6374 return d_ptr->sceneTransform.inverted().map(polygon);
6378 Maps the path \a path, which is in \a item's coordinate system, to
6379 this item's coordinate system, and returns the mapped path.
6381 If \a item is 0, this function returns the same as mapFromScene().
6383 \sa itemTransform(), mapFromParent(), mapFromScene(), mapToItem(), {The
6384 Graphics View Coordinate System}
6386 QPainterPath QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPainterPath &path) const
6389 return item->itemTransform(this).map(path);
6390 return mapFromScene(path);
6394 Maps the path \a path, which is in this item's parent's coordinate
6395 system, to this item's coordinate system, and returns the mapped path.
6397 \sa mapFromScene(), mapFromItem(), mapToParent(), {The Graphics View
6400 QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const
6403 if (!d_ptr->transformData)
6404 return path.translated(-d_ptr->pos);
6405 return d_ptr->transformToParent().inverted().map(path);
6409 Maps the path \a path, which is in this item's scene's coordinate
6410 system, to this item's coordinate system, and returns the mapped path.
6412 \sa mapFromParent(), mapFromItem(), mapToScene(), {The Graphics View
6415 QPainterPath QGraphicsItem::mapFromScene(const QPainterPath &path) const
6417 if (d_ptr->hasTranslateOnlySceneTransform())
6418 return path.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6419 return d_ptr->sceneTransform.inverted().map(path);
6423 Returns true if this item is an ancestor of \a child (i.e., if this item
6424 is \a child's parent, or one of \a child's parent's ancestors).
6428 bool QGraphicsItem::isAncestorOf(const QGraphicsItem *child) const
6430 if (!child || child == this)
6432 if (child->d_ptr->depth() < d_ptr->depth())
6434 const QGraphicsItem *ancestor = child;
6435 while ((ancestor = ancestor->d_ptr->parent)) {
6436 if (ancestor == this)
6445 Returns the closest common ancestor item of this item and \a other, or 0
6446 if either \a other is 0, or there is no common ancestor.
6450 QGraphicsItem *QGraphicsItem::commonAncestorItem(const QGraphicsItem *other) const
6455 return const_cast<QGraphicsItem *>(this);
6456 const QGraphicsItem *thisw = this;
6457 const QGraphicsItem *otherw = other;
6458 int thisDepth = d_ptr->depth();
6459 int otherDepth = other->d_ptr->depth();
6460 while (thisDepth > otherDepth) {
6461 thisw = thisw->d_ptr->parent;
6464 while (otherDepth > thisDepth) {
6465 otherw = otherw->d_ptr->parent;
6468 while (thisw && thisw != otherw) {
6469 thisw = thisw->d_ptr->parent;
6470 otherw = otherw->d_ptr->parent;
6472 return const_cast<QGraphicsItem *>(thisw);
6477 Returns true if this item is currently under the mouse cursor in one of
6478 the views; otherwise, false is returned.
6480 \sa QGraphicsScene::views(), QCursor::pos()
6482 bool QGraphicsItem::isUnderMouse() const
6484 Q_D(const QGraphicsItem);
6488 QPoint cursorPos = QCursor::pos();
6489 foreach (QGraphicsView *view, d->scene->views()) {
6490 if (contains(mapFromScene(view->mapToScene(view->mapFromGlobal(cursorPos)))))
6497 Returns this item's custom data for the key \a key as a QVariant.
6499 Custom item data is useful for storing arbitrary properties in any
6502 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 11
6504 Qt does not use this feature for storing data; it is provided solely
6505 for the convenience of the user.
6509 QVariant QGraphicsItem::data(int key) const
6511 QGraphicsItemCustomDataStore *store = qt_dataStore();
6512 if (!store->data.contains(this))
6514 return store->data.value(this).value(key);
6518 Sets this item's custom data for the key \a key to \a value.
6520 Custom item data is useful for storing arbitrary properties for any
6521 item. Qt does not use this feature for storing data; it is provided solely
6522 for the convenience of the user.
6526 void QGraphicsItem::setData(int key, const QVariant &value)
6528 qt_dataStore()->data[this][key] = value;
6532 \fn T qgraphicsitem_cast(QGraphicsItem *item)
6533 \relates QGraphicsItem
6536 Returns the given \a item cast to type T if \a item is of type T;
6537 otherwise, 0 is returned.
6539 \note To make this function work correctly with custom items, reimplement
6540 the \l{QGraphicsItem::}{type()} function for each custom QGraphicsItem
6543 \sa QGraphicsItem::type(), QGraphicsItem::UserType
6547 Returns the type of an item as an int. All standard graphicsitem classes
6548 are associated with a unique value; see QGraphicsItem::Type. This type
6549 information is used by qgraphicsitem_cast() to distinguish between types.
6551 The default implementation (in QGraphicsItem) returns UserType.
6553 To enable use of qgraphicsitem_cast() with a custom item, reimplement this
6554 function and declare a Type enum value equal to your custom item's type.
6555 Custom items must return a value larger than or equal to UserType (65536).
6559 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp QGraphicsItem type
6563 int QGraphicsItem::type() const
6565 return (int)UserType;
6569 Installs an event filter for this item on \a filterItem, causing
6570 all events for this item to first pass through \a filterItem's
6571 sceneEventFilter() function.
6573 To filter another item's events, install this item as an event filter
6574 for the other item. Example:
6576 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 12
6578 An item can only filter events for other items in the same
6579 scene. Also, an item cannot filter its own events; instead, you
6580 can reimplement sceneEvent() directly.
6582 Items must belong to a scene for scene event filters to be installed and
6585 \sa removeSceneEventFilter(), sceneEventFilter(), sceneEvent()
6587 void QGraphicsItem::installSceneEventFilter(QGraphicsItem *filterItem)
6589 if (!d_ptr->scene) {
6590 qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
6591 " on items in a scene.");
6594 if (d_ptr->scene != filterItem->scene()) {
6595 qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
6596 " on items in the same scene.");
6599 d_ptr->scene->d_func()->installSceneEventFilter(this, filterItem);
6603 Removes an event filter on this item from \a filterItem.
6605 \sa installSceneEventFilter()
6607 void QGraphicsItem::removeSceneEventFilter(QGraphicsItem *filterItem)
6609 if (!d_ptr->scene || d_ptr->scene != filterItem->scene())
6611 d_ptr->scene->d_func()->removeSceneEventFilter(this, filterItem);
6615 Filters events for the item \a watched. \a event is the filtered
6618 Reimplementing this function in a subclass makes it possible
6619 for the item to be used as an event filter for other items,
6620 intercepting all the events send to those items before they are
6623 Reimplementations must return true to prevent further processing of
6624 a given event, ensuring that it will not be delivered to the watched
6625 item, or return false to indicate that the event should be propagated
6626 further by the event system.
6628 \sa installSceneEventFilter()
6630 bool QGraphicsItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
6638 This virtual function receives events to this item. Reimplement
6639 this function to intercept events before they are dispatched to
6640 the specialized event handlers contextMenuEvent(), focusInEvent(),
6641 focusOutEvent(), hoverEnterEvent(), hoverMoveEvent(),
6642 hoverLeaveEvent(), keyPressEvent(), keyReleaseEvent(),
6643 mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent(), and
6644 mouseDoubleClickEvent().
6646 Returns true if the event was recognized and handled; otherwise, (e.g., if
6647 the event type was not recognized,) false is returned.
6649 \a event is the intercepted event.
6651 bool QGraphicsItem::sceneEvent(QEvent *event)
6653 if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents) {
6654 if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverLeave
6655 || event->type() == QEvent::DragEnter || event->type() == QEvent::DragLeave) {
6656 // Hover enter and hover leave events for children are ignored;
6657 // hover move events are forwarded.
6661 QGraphicsItem *handler = this;
6663 handler = handler->d_ptr->parent;
6665 } while (handler->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents);
6666 // Forward the event to the closest parent that handles child
6667 // events, mapping existing item-local coordinates to its
6668 // coordinate system.
6669 d_ptr->remapItemPos(event, handler);
6670 handler->sceneEvent(event);
6674 if (event->type() == QEvent::FocusOut) {
6675 focusOutEvent(static_cast<QFocusEvent *>(event));
6679 if (!d_ptr->visible) {
6684 switch (event->type()) {
6685 case QEvent::FocusIn:
6686 focusInEvent(static_cast<QFocusEvent *>(event));
6688 case QEvent::GraphicsSceneContextMenu:
6689 contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event));
6691 case QEvent::GraphicsSceneDragEnter:
6692 dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6694 case QEvent::GraphicsSceneDragMove:
6695 dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6697 case QEvent::GraphicsSceneDragLeave:
6698 dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6700 case QEvent::GraphicsSceneDrop:
6701 dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6703 case QEvent::GraphicsSceneHoverEnter:
6704 hoverEnterEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6706 case QEvent::GraphicsSceneHoverMove:
6707 hoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6709 case QEvent::GraphicsSceneHoverLeave:
6710 hoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6712 case QEvent::GraphicsSceneMouseMove:
6713 mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6715 case QEvent::GraphicsSceneMousePress:
6716 mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6718 case QEvent::GraphicsSceneMouseRelease:
6719 mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6721 case QEvent::GraphicsSceneMouseDoubleClick:
6722 mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6724 case QEvent::GraphicsSceneWheel:
6725 wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
6727 case QEvent::KeyPress: {
6728 QKeyEvent *k = static_cast<QKeyEvent *>(event);
6729 if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
6730 if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
6732 if (k->key() == Qt::Key_Backtab
6733 || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
6734 if (d_ptr->isWidget) {
6735 res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(false);
6736 } else if (d_ptr->scene) {
6737 res = d_ptr->scene->focusNextPrevChild(false);
6739 } else if (k->key() == Qt::Key_Tab) {
6740 if (d_ptr->isWidget) {
6741 res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(true);
6742 } else if (d_ptr->scene) {
6743 res = d_ptr->scene->focusNextPrevChild(true);
6751 keyPressEvent(static_cast<QKeyEvent *>(event));
6754 case QEvent::KeyRelease:
6755 keyReleaseEvent(static_cast<QKeyEvent *>(event));
6757 case QEvent::InputMethod:
6758 inputMethodEvent(static_cast<QInputMethodEvent *>(event));
6760 case QEvent::WindowActivate:
6761 case QEvent::WindowDeactivate:
6762 // Propagate panel activation.
6764 for (int i = 0; i < d_ptr->children.size(); ++i) {
6765 QGraphicsItem *child = d_ptr->children.at(i);
6766 if (child->isVisible() && !child->isPanel()) {
6767 if (!(child->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents))
6768 d_ptr->scene->sendEvent(child, event);
6781 This event handler can be reimplemented in a subclass to process context
6782 menu events. The \a event parameter contains details about the event to
6785 If you ignore the event, (i.e., by calling QEvent::ignore(),) \a event
6786 will propagate to any item beneath this item. If no items accept the
6787 event, it will be ignored by the scene, and propagate to the view.
6789 It's common to open a QMenu in response to receiving a context menu
6792 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 13
6794 The default implementation ignores the event.
6798 void QGraphicsItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
6804 This event handler, for event \a event, can be reimplemented to receive
6805 drag enter events for this item. Drag enter events are generated as the
6806 cursor enters the item's area.
6808 By accepting the event, (i.e., by calling QEvent::accept(),) the item will
6809 accept drop events, in addition to receiving drag move and drag
6810 leave. Otherwise, the event will be ignored and propagate to the item
6811 beneath. If the event is accepted, the item will receive a drag move event
6812 before control goes back to the event loop.
6814 A common implementation of dragEnterEvent accepts or ignores \a event
6815 depending on the associated mime data in \a event. Example:
6817 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 14
6819 Items do not receive drag and drop events by default; to enable this
6820 feature, call \c setAcceptDrops(true).
6822 The default implementation does nothing.
6824 \sa dropEvent(), dragMoveEvent(), dragLeaveEvent()
6826 void QGraphicsItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
6829 // binary compatibility workaround between 4.4 and 4.5
6830 if (d->isProxyWidget())
6831 static_cast<QGraphicsProxyWidget*>(this)->dragEnterEvent(event);
6835 This event handler, for event \a event, can be reimplemented to receive
6836 drag leave events for this item. Drag leave events are generated as the
6837 cursor leaves the item's area. Most often you will not need to reimplement
6838 this function, but it can be useful for resetting state in your item
6839 (e.g., highlighting).
6841 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6843 Items do not receive drag and drop events by default; to enable this
6844 feature, call \c setAcceptDrops(true).
6846 The default implementation does nothing.
6848 \sa dragEnterEvent(), dropEvent(), dragMoveEvent()
6850 void QGraphicsItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
6853 // binary compatibility workaround between 4.4 and 4.5
6854 if (d->isProxyWidget())
6855 static_cast<QGraphicsProxyWidget*>(this)->dragLeaveEvent(event);
6859 This event handler, for event \a event, can be reimplemented to receive
6860 drag move events for this item. Drag move events are generated as the
6861 cursor moves around inside the item's area. Most often you will not need
6862 to reimplement this function; it is used to indicate that only parts of
6863 the item can accept drops.
6865 Calling QEvent::ignore() or QEvent::accept() on \a event toggles whether
6866 or not the item will accept drops at the position from the event. By
6867 default, \a event is accepted, indicating that the item allows drops at
6868 the specified position.
6870 Items do not receive drag and drop events by default; to enable this
6871 feature, call \c setAcceptDrops(true).
6873 The default implementation does nothing.
6875 \sa dropEvent(), dragEnterEvent(), dragLeaveEvent()
6877 void QGraphicsItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
6880 // binary compatibility workaround between 4.4 and 4.5
6881 if (d->isProxyWidget())
6882 static_cast<QGraphicsProxyWidget*>(this)->dragMoveEvent(event);
6886 This event handler, for event \a event, can be reimplemented to receive
6887 drop events for this item. Items can only receive drop events if the last
6888 drag move event was accepted.
6890 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6892 Items do not receive drag and drop events by default; to enable this
6893 feature, call \c setAcceptDrops(true).
6895 The default implementation does nothing.
6897 \sa dragEnterEvent(), dragMoveEvent(), dragLeaveEvent()
6899 void QGraphicsItem::dropEvent(QGraphicsSceneDragDropEvent *event)
6902 // binary compatibility workaround between 4.4 and 4.5
6903 if (d->isProxyWidget())
6904 static_cast<QGraphicsProxyWidget*>(this)->dropEvent(event);
6908 This event handler, for event \a event, can be reimplemented to receive
6909 focus in events for this item. The default implementation calls
6912 \sa focusOutEvent(), sceneEvent(), setFocus()
6914 void QGraphicsItem::focusInEvent(QFocusEvent *event)
6921 This event handler, for event \a event, can be reimplemented to receive
6922 focus out events for this item. The default implementation does nothing.
6924 \sa focusInEvent(), sceneEvent(), setFocus()
6926 void QGraphicsItem::focusOutEvent(QFocusEvent *event)
6933 This event handler, for event \a event, can be reimplemented to receive
6934 hover enter events for this item. The default implementation calls
6935 update(); otherwise it does nothing.
6937 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6939 \sa hoverMoveEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
6941 void QGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
6948 This event handler, for event \a event, can be reimplemented to receive
6949 hover move events for this item. The default implementation does nothing.
6951 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6953 \sa hoverEnterEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
6955 void QGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
6961 This event handler, for event \a event, can be reimplemented to receive
6962 hover leave events for this item. The default implementation calls
6963 update(); otherwise it does nothing.
6965 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6967 \sa hoverEnterEvent(), hoverMoveEvent(), sceneEvent(), setAcceptHoverEvents()
6969 void QGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
6976 This event handler, for event \a event, can be reimplemented to
6977 receive key press events for this item. The default implementation
6978 ignores the event. If you reimplement this handler, the event will by
6979 default be accepted.
6981 Note that key events are only received for items that set the
6982 ItemIsFocusable flag, and that have keyboard input focus.
6984 \sa keyReleaseEvent(), setFocus(), QGraphicsScene::setFocusItem(),
6987 void QGraphicsItem::keyPressEvent(QKeyEvent *event)
6993 This event handler, for event \a event, can be reimplemented to receive
6994 key release events for this item. The default implementation
6995 ignores the event. If you reimplement this handler, the event will by
6996 default be accepted.
6998 Note that key events are only received for items that set the
6999 ItemIsFocusable flag, and that have keyboard input focus.
7001 \sa keyPressEvent(), setFocus(), QGraphicsScene::setFocusItem(),
7004 void QGraphicsItem::keyReleaseEvent(QKeyEvent *event)
7010 This event handler, for event \a event, can be reimplemented to
7011 receive mouse press events for this item. Mouse press events are
7012 only delivered to items that accept the mouse button that is
7013 pressed. By default, an item accepts all mouse buttons, but you
7014 can change this by calling setAcceptedMouseButtons().
7016 The mouse press event decides which item should become the mouse
7017 grabber (see QGraphicsScene::mouseGrabberItem()). If you do not
7018 reimplement this function, the press event will propagate to any
7019 topmost item beneath this item, and no other mouse events will be
7020 delivered to this item.
7022 If you do reimplement this function, \a event will by default be
7023 accepted (see QEvent::accept()), and this item is then the mouse
7024 grabber. This allows the item to receive future move, release and
7025 doubleclick events. If you call QEvent::ignore() on \a event, this
7026 item will lose the mouse grab, and \a event will propagate to any
7027 topmost item beneath. No further mouse events will be delivered to
7028 this item unless a new mouse press event is received.
7030 The default implementation handles basic item interaction, such as
7031 selection and moving. If you want to keep the base implementation
7032 when reimplementing this function, call
7033 QGraphicsItem::mousePressEvent() in your reimplementation.
7035 The event is \l{QEvent::ignore()}d for items that are neither
7036 \l{QGraphicsItem::ItemIsMovable}{movable} nor
7037 \l{QGraphicsItem::ItemIsSelectable}{selectable}.
7039 \sa mouseMoveEvent(), mouseReleaseEvent(),
7040 mouseDoubleClickEvent(), sceneEvent()
7042 void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
7044 if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
7045 bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
7047 if (!d_ptr->selected) {
7048 if (QGraphicsScene *scene = d_ptr->scene) {
7049 ++scene->d_func()->selectionChanging;
7050 scene->clearSelection();
7051 --scene->d_func()->selectionChanging;
7056 } else if (!(flags() & ItemIsMovable)) {
7059 if (d_ptr->isWidget) {
7060 // Qt::Popup closes when you click outside.
7061 QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
7062 if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
7064 if (!w->rect().contains(event->pos()))
7073 bool _qt_movableAncestorIsSelected(const QGraphicsItem *item)
7075 const QGraphicsItem *parent = item->parentItem();
7076 return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
7079 bool QGraphicsItemPrivate::movableAncestorIsSelected(const QGraphicsItem *item)
7081 const QGraphicsItem *parent = item->d_ptr->parent;
7082 return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
7086 This event handler, for event \a event, can be reimplemented to
7087 receive mouse move events for this item. If you do receive this
7088 event, you can be certain that this item also received a mouse
7089 press event, and that this item is the current mouse grabber.
7091 Calling QEvent::ignore() or QEvent::accept() on \a event has no
7094 The default implementation handles basic item interaction, such as
7095 selection and moving. If you want to keep the base implementation
7096 when reimplementing this function, call
7097 QGraphicsItem::mouseMoveEvent() in your reimplementation.
7099 Please note that mousePressEvent() decides which graphics item it
7100 is that receives mouse events. See the mousePressEvent()
7101 description for details.
7103 \sa mousePressEvent(), mouseReleaseEvent(),
7104 mouseDoubleClickEvent(), sceneEvent()
7106 void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
7108 if ((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) {
7109 // Determine the list of items that need to be moved.
7110 QList<QGraphicsItem *> selectedItems;
7111 QHash<QGraphicsItem *, QPointF> initialPositions;
7113 selectedItems = d_ptr->scene->selectedItems();
7114 initialPositions = d_ptr->scene->d_func()->movingItemsInitialPositions;
7115 if (initialPositions.isEmpty()) {
7116 foreach (QGraphicsItem *item, selectedItems)
7117 initialPositions[item] = item->pos();
7118 initialPositions[this] = pos();
7120 d_ptr->scene->d_func()->movingItemsInitialPositions = initialPositions;
7123 // Find the active view.
7124 QGraphicsView *view = 0;
7125 if (event->widget())
7126 view = qobject_cast<QGraphicsView *>(event->widget()->parentWidget());
7128 // Move all selected items
7130 bool movedMe = false;
7131 while (i <= selectedItems.size()) {
7132 QGraphicsItem *item = 0;
7133 if (i < selectedItems.size())
7134 item = selectedItems.at(i);
7138 // Slightly clumsy-looking way to ensure that "this" is part
7139 // of the list of items to move, this is to avoid allocations
7140 // (appending this item to the list of selected items causes a
7147 if ((item->flags() & ItemIsMovable) && !QGraphicsItemPrivate::movableAncestorIsSelected(item)) {
7148 QPointF currentParentPos;
7149 QPointF buttonDownParentPos;
7150 if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorIgnoresTransformations) {
7151 // Items whose ancestors ignore transformations need to
7152 // map screen coordinates to local coordinates, then map
7153 // those to the parent.
7154 QTransform viewToItemTransform = (item->deviceTransform(view->viewportTransform())).inverted();
7155 currentParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))));
7156 buttonDownParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))));
7157 } else if (item->flags() & ItemIgnoresTransformations) {
7158 // Root items that ignore transformations need to
7159 // calculate their diff by mapping viewport coordinates
7160 // directly to parent coordinates.
7162 QTransform itemTransform;
7163 if (item->d_ptr->transformData)
7164 itemTransform = item->d_ptr->transformData->computedFullTransform();
7165 itemTransform.translate(item->d_ptr->pos.x(), item->d_ptr->pos.y());
7166 QTransform viewToParentTransform = itemTransform
7167 * (item->sceneTransform() * view->viewportTransform()).inverted();
7168 currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos())));
7169 buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton))));
7171 // All other items simply map from the scene.
7172 currentParentPos = item->mapToParent(item->mapFromScene(event->scenePos()));
7173 buttonDownParentPos = item->mapToParent(item->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)));
7176 item->setPos(initialPositions.value(item) + currentParentPos - buttonDownParentPos);
7178 if (item->flags() & ItemIsSelectable)
7179 item->setSelected(true);
7190 This event handler, for event \a event, can be reimplemented to
7191 receive mouse release events for this item.
7193 Calling QEvent::ignore() or QEvent::accept() on \a event has no
7196 The default implementation handles basic item interaction, such as
7197 selection and moving. If you want to keep the base implementation
7198 when reimplementing this function, call
7199 QGraphicsItem::mouseReleaseEvent() in your reimplementation.
7201 Please note that mousePressEvent() decides which graphics item it
7202 is that receives mouse events. See the mousePressEvent()
7203 description for details.
7205 \sa mousePressEvent(), mouseMoveEvent(), mouseDoubleClickEvent(),
7208 void QGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
7210 if (flags() & ItemIsSelectable) {
7211 bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
7212 if (event->scenePos() == event->buttonDownScenePos(Qt::LeftButton)) {
7213 // The item didn't move
7215 setSelected(!isSelected());
7217 bool selectionChanged = false;
7218 if (QGraphicsScene *scene = d_ptr->scene) {
7219 ++scene->d_func()->selectionChanging;
7220 // Clear everything but this item. Bypass
7221 // QGraphicsScene::clearSelection()'s default behavior by
7222 // temporarily removing this item from the selection list.
7223 if (d_ptr->selected) {
7224 scene->d_func()->selectedItems.remove(this);
7225 foreach (QGraphicsItem *item, scene->d_func()->selectedItems) {
7226 if (item->isSelected()) {
7227 selectionChanged = true;
7232 scene->clearSelection();
7233 if (d_ptr->selected)
7234 scene->d_func()->selectedItems.insert(this);
7235 --scene->d_func()->selectionChanging;
7236 if (selectionChanged)
7237 emit d_ptr->scene->selectionChanged();
7243 if (d_ptr->scene && !event->buttons())
7244 d_ptr->scene->d_func()->movingItemsInitialPositions.clear();
7248 This event handler, for event \a event, can be reimplemented to
7249 receive mouse doubleclick events for this item.
7251 When doubleclicking an item, the item will first receive a mouse
7252 press event, followed by a release event (i.e., a click), then a
7253 doubleclick event, and finally a release event.
7255 Calling QEvent::ignore() or QEvent::accept() on \a event has no
7258 The default implementation calls mousePressEvent(). If you want to
7259 keep the base implementation when reimplementing this function,
7260 call QGraphicsItem::mouseDoubleClickEvent() in your
7263 Note that an item will not receive double click events if it is
7264 neither \l {QGraphicsItem::ItemIsSelectable}{selectable} nor
7265 \l{QGraphicsItem::ItemIsMovable}{movable} (single mouse clicks are
7266 ignored in this case, and that stops the generation of double
7269 \sa mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), sceneEvent()
7271 void QGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
7273 mousePressEvent(event);
7277 This event handler, for event \a event, can be reimplemented to receive
7278 wheel events for this item. If you reimplement this function, \a event
7279 will be accepted by default.
7281 If you ignore the event, (i.e., by calling QEvent::ignore(),) it will
7282 propagate to any item beneath this item. If no items accept the event, it
7283 will be ignored by the scene, and propagate to the view (e.g., the view's
7284 vertical scroll bar).
7286 The default implementation ignores the event.
7290 void QGraphicsItem::wheelEvent(QGraphicsSceneWheelEvent *event)
7296 This event handler, for event \a event, can be reimplemented to receive
7297 input method events for this item. The default implementation ignores the
7300 \sa inputMethodQuery(), sceneEvent()
7302 void QGraphicsItem::inputMethodEvent(QInputMethodEvent *event)
7308 This method is only relevant for input items. It is used by the
7309 input method to query a set of properties of the item to be able
7310 to support complex input method operations, such as support for
7311 surrounding text and reconversions. \a query specifies which
7312 property is queried.
7314 \sa inputMethodEvent(), QInputMethodEvent
7316 QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const
7323 Returns the current input method hints of this item.
7325 Input method hints are only relevant for input items.
7326 The hints are used by the input method to indicate how it should operate.
7327 For example, if the Qt::ImhNumbersOnly flag is set, the input method may change
7328 its visual components to reflect that only numbers can be entered.
7330 The effect may vary between input method implementations.
7334 \sa setInputMethodHints(), inputMethodQuery()
7336 Qt::InputMethodHints QGraphicsItem::inputMethodHints() const
7338 Q_D(const QGraphicsItem);
7343 Sets the current input method hints of this item to \a hints.
7347 \sa inputMethodHints(), inputMethodQuery()
7349 void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
7355 d->scene->d_func()->updateInputMethodSensitivityInViews();
7356 QWidget *fw = QApplication::focusWidget();
7359 qApp->inputMethod()->update(Qt::ImHints);
7363 Updates the item's micro focus.
7369 void QGraphicsItem::updateMicroFocus()
7371 #if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS))
7372 if (QWidget *fw = QApplication::focusWidget()) {
7374 for (int i = 0 ; i < scene()->views().count() ; ++i) {
7375 if (scene()->views().at(i) == fw) {
7377 qApp->inputMethod()->update(Qt::ImQueryAll);
7379 #ifndef QT_NO_ACCESSIBILITY
7380 // ##### is this correct
7381 if (toGraphicsObject())
7382 QAccessible::updateAccessibility(toGraphicsObject(), 0, QAccessible::StateChanged);
7394 This virtual function is called by QGraphicsItem to notify custom items
7395 that some part of the item's state changes. By reimplementing this
7396 function, your can react to a change, and in some cases, (depending on \a
7397 change,) adjustments can be made.
7399 \a change is the parameter of the item that is changing. \a value is the
7400 new value; the type of the value depends on \a change.
7404 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 15
7406 The default implementation does nothing, and returns \a value.
7408 Note: Certain QGraphicsItem functions cannot be called in a
7409 reimplementation of this function; see the GraphicsItemChange
7410 documentation for details.
7412 \sa GraphicsItemChange
7414 QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value)
7423 Note: This is provided as a hook to avoid future problems related
7424 to adding virtual functions.
7426 bool QGraphicsItem::supportsExtension(Extension extension) const
7428 Q_UNUSED(extension);
7435 Note: This is provided as a hook to avoid future problems related
7436 to adding virtual functions.
7438 void QGraphicsItem::setExtension(Extension extension, const QVariant &variant)
7440 Q_UNUSED(extension);
7447 Note: This is provided as a hook to avoid future problems related
7448 to adding virtual functions.
7450 QVariant QGraphicsItem::extension(const QVariant &variant) const
7459 Adds this item to the scene's index. Called in conjunction with
7460 removeFromIndex() to ensure the index bookkeeping is correct when
7461 the item's position, transformation or shape changes.
7463 void QGraphicsItem::addToIndex()
7465 if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
7466 // ### add to child index only if applicable
7470 d_ptr->scene->d_func()->index->addItem(this);
7476 Removes this item from the scene's index. Called in conjunction
7477 with addToIndex() to ensure the index bookkeeping is correct when
7478 the item's position, transformation or shape changes.
7480 void QGraphicsItem::removeFromIndex()
7482 if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
7483 // ### remove from child index only if applicable
7487 d_ptr->scene->d_func()->index->removeItem(this);
7491 Prepares the item for a geometry change. Call this function before
7492 changing the bounding rect of an item to keep QGraphicsScene's index up to
7495 prepareGeometryChange() will call update() if this is necessary.
7499 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 16
7503 void QGraphicsItem::prepareGeometryChange()
7505 if (d_ptr->inDestructor)
7508 d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true;
7509 d_ptr->geometryChanged = 1;
7510 d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
7511 d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper;
7513 QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
7514 scenePrivate->index->prepareBoundingRectChange(this);
7515 scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false,
7516 /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false,
7517 /*updateBoundingRect=*/true);
7519 // For compatibility reasons, we have to update the item's old geometry
7520 // if someone is connected to the changed signal or the scene has no views.
7521 // Note that this has to be done *after* markDirty to ensure that
7522 // _q_processDirtyItems is called before _q_emitUpdated.
7523 if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
7524 || scenePrivate->views.isEmpty()) {
7525 if (d_ptr->hasTranslateOnlySceneTransform()) {
7526 d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
7527 d_ptr->sceneTransform.dy()));
7529 d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect()));
7534 d_ptr->markParentDirty(/*updateBoundingRect=*/true);
7540 Highlights \a item as selected.
7542 NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in
7543 qgraphicssvgitem.cpp!
7545 static void qt_graphicsItem_highlightSelected(
7546 QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option)
7548 const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1));
7549 if (qFuzzyIsNull(qMax(murect.width(), murect.height())))
7552 const QRectF mbrect = painter->transform().mapRect(item->boundingRect());
7553 if (qMin(mbrect.width(), mbrect.height()) < qreal(1.0))
7557 switch (item->type()) {
7558 case QGraphicsEllipseItem::Type:
7559 itemPenWidth = static_cast<QGraphicsEllipseItem *>(item)->pen().widthF();
7561 case QGraphicsPathItem::Type:
7562 itemPenWidth = static_cast<QGraphicsPathItem *>(item)->pen().widthF();
7564 case QGraphicsPolygonItem::Type:
7565 itemPenWidth = static_cast<QGraphicsPolygonItem *>(item)->pen().widthF();
7567 case QGraphicsRectItem::Type:
7568 itemPenWidth = static_cast<QGraphicsRectItem *>(item)->pen().widthF();
7570 case QGraphicsSimpleTextItem::Type:
7571 itemPenWidth = static_cast<QGraphicsSimpleTextItem *>(item)->pen().widthF();
7573 case QGraphicsLineItem::Type:
7574 itemPenWidth = static_cast<QGraphicsLineItem *>(item)->pen().widthF();
7579 const qreal pad = itemPenWidth / 2;
7581 const qreal penWidth = 0; // cosmetic pen
7583 const QColor fgcolor = option->palette.windowText().color();
7584 const QColor bgcolor( // ensure good contrast against fgcolor
7585 fgcolor.red() > 127 ? 0 : 255,
7586 fgcolor.green() > 127 ? 0 : 255,
7587 fgcolor.blue() > 127 ? 0 : 255);
7589 painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
7590 painter->setBrush(Qt::NoBrush);
7591 painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
7593 painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
7594 painter->setBrush(Qt::NoBrush);
7595 painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
7599 \class QGraphicsObject
7600 \brief The QGraphicsObject class provides a base class for all graphics items that
7601 require signals, slots and properties.
7603 \ingroup graphicsview-api
7606 The class extends a QGraphicsItem with QObject's signal/slot and property mechanisms.
7607 It maps many of QGraphicsItem's basic setters and getters to properties and adds notification
7608 signals for many of them.
7610 \section1 Parents and Children
7612 Each graphics object can be constructed with a parent item. This ensures that the
7613 item will be destroyed when its parent item is destroyed. Although QGraphicsObject
7614 inherits from both QObject and QGraphicsItem, you should use the functions provided
7615 by QGraphicsItem, \e not QObject, to manage the relationships between parent and
7618 The relationships between items can be explored using the parentItem() and childItems()
7619 functions. In the hierarchy of items in a scene, the parentObject() and parentWidget()
7620 functions are the equivalent of the QWidget::parent() and QWidget::parentWidget()
7621 functions for QWidget subclasses.
7627 Constructs a QGraphicsObject with \a parent.
7629 QGraphicsObject::QGraphicsObject(QGraphicsItem *parent)
7630 : QGraphicsItem(parent)
7632 QGraphicsItem::d_ptr->isObject = true;
7638 QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene)
7639 : QGraphicsItem(dd, parent, scene)
7641 QGraphicsItem::d_ptr->isObject = true;
7644 #ifndef QT_NO_GESTURES
7646 Subscribes the graphics object to the given \a gesture with specific \a flags.
7648 \sa ungrabGesture(), QGestureEvent
7650 void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
7652 bool contains = QGraphicsItem::d_ptr->gestureContext.contains(gesture);
7653 QGraphicsItem::d_ptr->gestureContext.insert(gesture, flags);
7654 if (!contains && QGraphicsItem::d_ptr->scene)
7655 QGraphicsItem::d_ptr->scene->d_func()->grabGesture(this, gesture);
7659 Unsubscribes the graphics object from the given \a gesture.
7661 \sa grabGesture(), QGestureEvent
7663 void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
7665 if (QGraphicsItem::d_ptr->gestureContext.remove(gesture) && QGraphicsItem::d_ptr->scene)
7666 QGraphicsItem::d_ptr->scene->d_func()->ungrabGesture(this, gesture);
7668 #endif // QT_NO_GESTURES
7671 Updates the item's micro focus. This is slot for convenience.
7677 void QGraphicsObject::updateMicroFocus()
7679 QGraphicsItem::updateMicroFocus();
7682 void QGraphicsItemPrivate::children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item)
7685 QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(list->object);
7686 if (QGraphicsItemPrivate::get(graphicsObject)->sendParentChangeNotification) {
7687 item->setParentItem(graphicsObject);
7689 QGraphicsItemPrivate::get(item)->setParentItemHelper(graphicsObject, 0, 0);
7694 int QGraphicsItemPrivate::children_count(QDeclarativeListProperty<QGraphicsObject> *list)
7696 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7697 return d->children.count();
7700 QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGraphicsObject> *list, int index)
7702 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7703 if (index >= 0 && index < d->children.count())
7704 return d->children.at(index)->toGraphicsObject();
7709 void QGraphicsItemPrivate::children_clear(QDeclarativeListProperty<QGraphicsObject> *list)
7711 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7712 int childCount = d->children.count();
7713 if (d->sendParentChangeNotification) {
7714 for (int index = 0; index < childCount; index++)
7715 d->children.at(0)->setParentItem(0);
7717 for (int index = 0; index < childCount; index++)
7718 QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, 0, 0);
7723 Returns a list of this item's children.
7725 The items are sorted by stacking order. This takes into account both the
7726 items' insertion order and their Z-values.
7729 QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList()
7733 QGraphicsObject *that = static_cast<QGraphicsObject *>(q);
7734 return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append,
7735 children_count, children_at, children_clear);
7737 //QGraphicsItem is not supported for this property
7738 return QDeclarativeListProperty<QGraphicsObject>();
7744 Returns the width of the item
7745 Reimplemented by QGraphicsWidget
7747 qreal QGraphicsItemPrivate::width() const
7754 Set the width of the item
7755 Reimplemented by QGraphicsWidget
7757 void QGraphicsItemPrivate::setWidth(qreal w)
7764 Reset the width of the item
7765 Reimplemented by QGraphicsWidget
7767 void QGraphicsItemPrivate::resetWidth()
7773 Returns the height of the item
7774 Reimplemented by QGraphicsWidget
7776 qreal QGraphicsItemPrivate::height() const
7783 Set the height of the item
7784 Reimplemented by QGraphicsWidget
7786 void QGraphicsItemPrivate::setHeight(qreal h)
7793 Reset the height of the item
7794 Reimplemented by QGraphicsWidget
7796 void QGraphicsItemPrivate::resetHeight()
7801 \property QGraphicsObject::children
7807 \property QGraphicsObject::width
7813 \property QGraphicsObject::height
7819 \property QGraphicsObject::parent
7820 \brief the parent of the item
7822 \note The item's parent is set independently of the parent object returned
7823 by QObject::parent().
7825 \sa QGraphicsItem::setParentItem(), QGraphicsItem::parentObject()
7829 \property QGraphicsObject::opacity
7830 \brief the opacity of the item
7832 \sa QGraphicsItem::setOpacity(), QGraphicsItem::opacity()
7836 \fn QGraphicsObject::opacityChanged()
7838 This signal gets emitted whenever the opacity of the item changes
7840 \sa QGraphicsItem::opacity()
7844 \fn QGraphicsObject::parentChanged()
7846 This signal gets emitted whenever the parent of the item changes
7850 \property QGraphicsObject::pos
7851 \brief the position of the item
7853 Describes the items position.
7855 \sa QGraphicsItem::setPos(), QGraphicsItem::pos()
7859 \property QGraphicsObject::x
7860 \brief the x position of the item
7862 Describes the items x position.
7864 \sa QGraphicsItem::setX(), setPos(), xChanged()
7868 \fn QGraphicsObject::xChanged()
7870 This signal gets emitted whenever the x position of the item changes
7876 \property QGraphicsObject::y
7877 \brief the y position of the item
7879 Describes the items y position.
7881 \sa QGraphicsItem::setY(), setPos(), yChanged()
7885 \fn QGraphicsObject::yChanged()
7887 This signal gets emitted whenever the y position of the item changes.
7893 \property QGraphicsObject::z
7894 \brief the z value of the item
7896 Describes the items z value.
7898 \sa QGraphicsItem::setZValue(), zValue(), zChanged()
7902 \fn QGraphicsObject::zChanged()
7904 This signal gets emitted whenever the z value of the item changes.
7910 \property QGraphicsObject::rotation
7911 This property holds the rotation of the item in degrees.
7913 This specifies how many degrees to rotate the item around its transformOrigin.
7914 The default rotation is 0 degrees (i.e. not rotated at all).
7918 \fn QGraphicsObject::rotationChanged()
7920 This signal gets emitted whenever the roation of the item changes.
7924 \property QGraphicsObject::scale
7925 This property holds the scale of the item.
7927 A scale of less than 1 means the item will be displayed smaller than
7928 normal, and a scale of greater than 1 means the item will be
7929 displayed larger than normal. A negative scale means the item will
7932 By default, items are displayed at a scale of 1 (i.e. at their
7935 Scaling is from the item's transformOrigin.
7939 \fn void QGraphicsObject::scaleChanged()
7941 This signal is emitted when the scale of the item changes.
7946 \property QGraphicsObject::enabled
7947 \brief whether the item is enabled or not
7949 This property is declared in QGraphicsItem.
7951 By default, this property is true.
7953 \sa QGraphicsItem::isEnabled(), QGraphicsItem::setEnabled()
7954 \sa QGraphicsObject::enabledChanged()
7958 \fn void QGraphicsObject::enabledChanged()
7960 This signal gets emitted whenever the item get's enabled or disabled.
7966 \property QGraphicsObject::visible
7967 \brief whether the item is visible or not
7969 This property is declared in QGraphicsItem.
7971 By default, this property is true.
7973 \sa QGraphicsItem::isVisible(), QGraphicsItem::setVisible(), visibleChanged()
7977 \fn QGraphicsObject::visibleChanged()
7979 This signal gets emitted whenever the visibility of the item changes
7985 \fn const QObjectList &QGraphicsObject::children() const
7988 This function returns the same value as QObject::children(). It's
7989 provided to differentiate between the obsolete member
7990 QGraphicsItem::children() and QObject::children(). QGraphicsItem now
7991 provides childItems() instead.
7995 \property QGraphicsObject::transformOriginPoint
7996 \brief the transformation origin
7998 This property sets a specific point in the items coordiante system as the
7999 origin for scale and rotation.
8001 \sa scale, rotation, QGraphicsItem::transformOriginPoint()
8005 \fn void QGraphicsObject::widthChanged()
8010 \fn void QGraphicsObject::heightChanged()
8016 \fn QGraphicsObject::childrenChanged()
8018 This signal gets emitted whenever the children list changes
8023 \property QGraphicsObject::effect
8025 \brief the effect attached to this item
8027 \sa QGraphicsItem::setGraphicsEffect(), QGraphicsItem::graphicsEffect()
8031 \class QAbstractGraphicsShapeItem
8032 \brief The QAbstractGraphicsShapeItem class provides a common base for
8035 \ingroup graphicsview-api
8038 This class does not fully implement an item by itself; in particular, it
8039 does not implement boundingRect() and paint(), which are inherited by
8042 You can subclass this item to provide a simple base implementation of
8043 accessors for the item's pen and brush.
8045 \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPathItem,
8046 QGraphicsPolygonItem, QGraphicsTextItem, QGraphicsLineItem,
8047 QGraphicsPixmapItem, {Graphics View Framework}
8050 class QAbstractGraphicsShapeItemPrivate : public QGraphicsItemPrivate
8052 Q_DECLARE_PUBLIC(QAbstractGraphicsShapeItem)
8058 // Cached bounding rectangle
8059 mutable QRectF boundingRect;
8063 Constructs a QAbstractGraphicsShapeItem. \a parent is passed to
8064 QGraphicsItem's constructor.
8066 QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QGraphicsItem *parent
8068 // obsolete argument
8069 , QGraphicsScene *scene
8072 : QGraphicsItem(*new QAbstractGraphicsShapeItemPrivate, parent, scene)
8079 QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QAbstractGraphicsShapeItemPrivate &dd,
8080 QGraphicsItem *parent,
8081 QGraphicsScene *scene)
8082 : QGraphicsItem(dd, parent, scene)
8087 Destroys a QAbstractGraphicsShapeItem.
8089 QAbstractGraphicsShapeItem::~QAbstractGraphicsShapeItem()
8094 Returns the item's pen. If no pen has been set, this function returns
8095 QPen(), a default black solid line pen with 0 width.
8097 QPen QAbstractGraphicsShapeItem::pen() const
8099 Q_D(const QAbstractGraphicsShapeItem);
8104 Sets the pen for this item to \a pen.
8106 The pen is used to draw the item's outline.
8110 void QAbstractGraphicsShapeItem::setPen(const QPen &pen)
8112 Q_D(QAbstractGraphicsShapeItem);
8115 prepareGeometryChange();
8117 d->boundingRect = QRectF();
8122 Returns the item's brush, or an empty brush if no brush has been set.
8126 QBrush QAbstractGraphicsShapeItem::brush() const
8128 Q_D(const QAbstractGraphicsShapeItem);
8133 Sets the item's brush to \a brush.
8135 The item's brush is used to fill the item.
8137 If you use a brush with a QGradient, the gradient
8138 is relative to the item's coordinate system.
8142 void QAbstractGraphicsShapeItem::setBrush(const QBrush &brush)
8144 Q_D(QAbstractGraphicsShapeItem);
8145 if (d->brush == brush)
8154 bool QAbstractGraphicsShapeItem::isObscuredBy(const QGraphicsItem *item) const
8156 return QGraphicsItem::isObscuredBy(item);
8162 QPainterPath QAbstractGraphicsShapeItem::opaqueArea() const
8164 Q_D(const QAbstractGraphicsShapeItem);
8165 if (d->brush.isOpaque())
8166 return isClipped() ? clipPath() : shape();
8167 return QGraphicsItem::opaqueArea();
8171 \class QGraphicsPathItem
8172 \brief The QGraphicsPathItem class provides a path item that you
8173 can add to a QGraphicsScene.
8175 \ingroup graphicsview-api
8178 To set the item's path, pass a QPainterPath to QGraphicsPathItem's
8179 constructor, or call the setPath() function. The path() function
8180 returns the current path.
8182 \image graphicsview-pathitem.png
8184 QGraphicsPathItem uses the path to provide a reasonable
8185 implementation of boundingRect(), shape(), and contains(). The
8186 paint() function draws the path using the item's associated pen
8187 and brush, which you can set by calling the setPen() and
8188 setBrush() functions.
8190 \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
8191 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8195 class QGraphicsPathItemPrivate : public QAbstractGraphicsShapeItemPrivate
8197 Q_DECLARE_PUBLIC(QGraphicsPathItem)
8203 Constructs a QGraphicsPath item using \a path as the default path. \a
8204 parent is passed to QAbstractGraphicsShapeItem's constructor.
8206 \sa QGraphicsScene::addItem()
8208 QGraphicsPathItem::QGraphicsPathItem(const QPainterPath &path,
8209 QGraphicsItem *parent
8211 // obsolete argument
8212 , QGraphicsScene *scene
8215 : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
8217 if (!path.isEmpty())
8222 Constructs a QGraphicsPath. \a parent is passed to
8223 QAbstractGraphicsShapeItem's constructor.
8225 \sa QGraphicsScene::addItem()
8227 QGraphicsPathItem::QGraphicsPathItem(QGraphicsItem *parent
8229 // obsolete argument
8230 , QGraphicsScene *scene
8233 : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
8238 Destroys the QGraphicsPathItem.
8240 QGraphicsPathItem::~QGraphicsPathItem()
8245 Returns the item's path as a QPainterPath. If no item has been set, an
8246 empty QPainterPath is returned.
8250 QPainterPath QGraphicsPathItem::path() const
8252 Q_D(const QGraphicsPathItem);
8257 Sets the item's path to be the given \a path.
8261 void QGraphicsPathItem::setPath(const QPainterPath &path)
8263 Q_D(QGraphicsPathItem);
8264 if (d->path == path)
8266 prepareGeometryChange();
8268 d->boundingRect = QRectF();
8275 QRectF QGraphicsPathItem::boundingRect() const
8277 Q_D(const QGraphicsPathItem);
8278 if (d->boundingRect.isNull()) {
8279 qreal pw = pen().widthF();
8281 d->boundingRect = d->path.controlPointRect();
8283 d->boundingRect = shape().controlPointRect();
8286 return d->boundingRect;
8292 QPainterPath QGraphicsPathItem::shape() const
8294 Q_D(const QGraphicsPathItem);
8295 return qt_graphicsItem_shapeFromPath(d->path, d->pen);
8301 bool QGraphicsPathItem::contains(const QPointF &point) const
8303 return QAbstractGraphicsShapeItem::contains(point);
8309 void QGraphicsPathItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8312 Q_D(QGraphicsPathItem);
8314 painter->setPen(d->pen);
8315 painter->setBrush(d->brush);
8316 painter->drawPath(d->path);
8318 if (option->state & QStyle::State_Selected)
8319 qt_graphicsItem_highlightSelected(this, painter, option);
8325 bool QGraphicsPathItem::isObscuredBy(const QGraphicsItem *item) const
8327 return QAbstractGraphicsShapeItem::isObscuredBy(item);
8333 QPainterPath QGraphicsPathItem::opaqueArea() const
8335 return QAbstractGraphicsShapeItem::opaqueArea();
8341 int QGraphicsPathItem::type() const
8349 bool QGraphicsPathItem::supportsExtension(Extension extension) const
8351 Q_UNUSED(extension);
8358 void QGraphicsPathItem::setExtension(Extension extension, const QVariant &variant)
8360 Q_UNUSED(extension);
8367 QVariant QGraphicsPathItem::extension(const QVariant &variant) const
8374 \class QGraphicsRectItem
8375 \brief The QGraphicsRectItem class provides a rectangle item that you
8376 can add to a QGraphicsScene.
8378 \ingroup graphicsview-api
8381 To set the item's rectangle, pass a QRectF to QGraphicsRectItem's
8382 constructor, or call the setRect() function. The rect() function
8383 returns the current rectangle.
8385 \image graphicsview-rectitem.png
8387 QGraphicsRectItem uses the rectangle and the pen width to provide
8388 a reasonable implementation of boundingRect(), shape(), and
8389 contains(). The paint() function draws the rectangle using the
8390 item's associated pen and brush, which you can set by calling the
8391 setPen() and setBrush() functions.
8393 \note The rendering of invalid rectangles, such as those with negative
8394 widths or heights, is undefined. If you cannot be sure that you are
8395 using valid rectangles (for example, if you are creating
8396 rectangles using data from an unreliable source) then you should
8397 use QRectF::normalized() to create normalized rectangles, and use
8400 \sa QGraphicsPathItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
8401 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8405 class QGraphicsRectItemPrivate : public QAbstractGraphicsShapeItemPrivate
8407 Q_DECLARE_PUBLIC(QGraphicsRectItem)
8413 Constructs a QGraphicsRectItem, using \a rect as the default rectangle.
8414 \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8416 \sa QGraphicsScene::addItem()
8418 QGraphicsRectItem::QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent
8420 // obsolete argument
8421 , QGraphicsScene *scene
8424 : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
8430 \fn QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal width, qreal height,
8431 QGraphicsItem *parent)
8433 Constructs a QGraphicsRectItem with a default rectangle defined
8434 by (\a x, \a y) and the given \a width and \a height.
8436 \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8438 \sa QGraphicsScene::addItem()
8440 QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h,
8441 QGraphicsItem *parent
8443 // obsolete argument
8444 , QGraphicsScene *scene
8447 : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
8449 setRect(QRectF(x, y, w, h));
8453 Constructs a QGraphicsRectItem. \a parent is passed to
8454 QAbstractGraphicsShapeItem's constructor.
8456 \sa QGraphicsScene::addItem()
8458 QGraphicsRectItem::QGraphicsRectItem(QGraphicsItem *parent
8460 // obsolete argument
8461 , QGraphicsScene *scene
8464 : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
8469 Destroys the QGraphicsRectItem.
8471 QGraphicsRectItem::~QGraphicsRectItem()
8476 Returns the item's rectangle.
8480 QRectF QGraphicsRectItem::rect() const
8482 Q_D(const QGraphicsRectItem);
8487 \fn void QGraphicsRectItem::setRect(const QRectF &rectangle)
8489 Sets the item's rectangle to be the given \a rectangle.
8493 void QGraphicsRectItem::setRect(const QRectF &rect)
8495 Q_D(QGraphicsRectItem);
8496 if (d->rect == rect)
8498 prepareGeometryChange();
8500 d->boundingRect = QRectF();
8505 \fn void QGraphicsRectItem::setRect(qreal x, qreal y, qreal width, qreal height)
8506 \fn void QGraphicsEllipseItem::setRect(qreal x, qreal y, qreal width, qreal height)
8508 Sets the item's rectangle to the rectangle defined by (\a x, \a y)
8509 and the given \a width and \a height.
8511 This convenience function is equivalent to calling \c
8512 {setRect(QRectF(x, y, width, height))}
8520 QRectF QGraphicsRectItem::boundingRect() const
8522 Q_D(const QGraphicsRectItem);
8523 if (d->boundingRect.isNull()) {
8524 qreal halfpw = pen().widthF() / 2;
8525 d->boundingRect = d->rect;
8527 d->boundingRect.adjust(-halfpw, -halfpw, halfpw, halfpw);
8529 return d->boundingRect;
8535 QPainterPath QGraphicsRectItem::shape() const
8537 Q_D(const QGraphicsRectItem);
8539 path.addRect(d->rect);
8540 return qt_graphicsItem_shapeFromPath(path, d->pen);
8546 bool QGraphicsRectItem::contains(const QPointF &point) const
8548 return QAbstractGraphicsShapeItem::contains(point);
8554 void QGraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8557 Q_D(QGraphicsRectItem);
8559 painter->setPen(d->pen);
8560 painter->setBrush(d->brush);
8561 painter->drawRect(d->rect);
8563 if (option->state & QStyle::State_Selected)
8564 qt_graphicsItem_highlightSelected(this, painter, option);
8570 bool QGraphicsRectItem::isObscuredBy(const QGraphicsItem *item) const
8572 return QAbstractGraphicsShapeItem::isObscuredBy(item);
8578 QPainterPath QGraphicsRectItem::opaqueArea() const
8580 return QAbstractGraphicsShapeItem::opaqueArea();
8586 int QGraphicsRectItem::type() const
8594 bool QGraphicsRectItem::supportsExtension(Extension extension) const
8596 Q_UNUSED(extension);
8603 void QGraphicsRectItem::setExtension(Extension extension, const QVariant &variant)
8605 Q_UNUSED(extension);
8612 QVariant QGraphicsRectItem::extension(const QVariant &variant) const
8619 \class QGraphicsEllipseItem
8620 \brief The QGraphicsEllipseItem class provides an ellipse item that you
8621 can add to a QGraphicsScene.
8623 \ingroup graphicsview-api
8626 QGraphicsEllipseItem respresents an ellipse with a fill and an outline,
8627 and you can also use it for ellipse segments (see startAngle(),
8632 \li \inlineimage graphicsview-ellipseitem.png
8633 \li \inlineimage graphicsview-ellipseitem-pie.png
8636 To set the item's ellipse, pass a QRectF to QGraphicsEllipseItem's
8637 constructor, or call setRect(). The rect() function returns the
8638 current ellipse geometry.
8640 QGraphicsEllipseItem uses the rect and the pen width to provide a
8641 reasonable implementation of boundingRect(), shape(), and contains(). The
8642 paint() function draws the ellipse using the item's associated pen and
8643 brush, which you can set by calling setPen() and setBrush().
8645 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsPolygonItem,
8646 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8650 class QGraphicsEllipseItemPrivate : public QAbstractGraphicsShapeItemPrivate
8652 Q_DECLARE_PUBLIC(QGraphicsEllipseItem)
8654 inline QGraphicsEllipseItemPrivate()
8655 : startAngle(0), spanAngle(360 * 16)
8664 Constructs a QGraphicsEllipseItem using \a rect as the default rectangle.
8665 \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8667 \sa QGraphicsScene::addItem()
8669 QGraphicsEllipseItem::QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent
8671 // obsolete argument
8672 , QGraphicsScene *scene
8675 : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
8681 \fn QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent)
8684 Constructs a QGraphicsEllipseItem using the rectangle defined by (\a x, \a
8685 y) and the given \a width and \a height, as the default rectangle. \a
8686 parent is passed to QAbstractGraphicsShapeItem's constructor.
8688 \sa QGraphicsScene::addItem()
8690 QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h,
8691 QGraphicsItem *parent
8693 // obsolete argument
8694 , QGraphicsScene *scene
8697 : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
8705 Constructs a QGraphicsEllipseItem. \a parent is passed to
8706 QAbstractGraphicsShapeItem's constructor.
8708 \sa QGraphicsScene::addItem()
8710 QGraphicsEllipseItem::QGraphicsEllipseItem(QGraphicsItem *parent
8712 // obsolete argument
8713 , QGraphicsScene *scene
8716 : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
8721 Destroys the QGraphicsEllipseItem.
8723 QGraphicsEllipseItem::~QGraphicsEllipseItem()
8728 Returns the item's ellipse geometry as a QRectF.
8730 \sa setRect(), QPainter::drawEllipse()
8732 QRectF QGraphicsEllipseItem::rect() const
8734 Q_D(const QGraphicsEllipseItem);
8739 Sets the item's ellipse geometry to \a rect. The rectangle's left edge
8740 defines the left edge of the ellipse, and the rectangle's top edge
8741 describes the top of the ellipse. The height and width of the rectangle
8742 describe the height and width of the ellipse.
8744 \sa rect(), QPainter::drawEllipse()
8746 void QGraphicsEllipseItem::setRect(const QRectF &rect)
8748 Q_D(QGraphicsEllipseItem);
8749 if (d->rect == rect)
8751 prepareGeometryChange();
8753 d->boundingRect = QRectF();
8758 Returns the start angle for an ellipse segment in 16ths of a degree. This
8759 angle is used together with spanAngle() for representing an ellipse
8760 segment (a pie). By default, the start angle is 0.
8762 \sa setStartAngle(), spanAngle()
8764 int QGraphicsEllipseItem::startAngle() const
8766 Q_D(const QGraphicsEllipseItem);
8767 return d->startAngle;
8771 Sets the start angle for an ellipse segment to \a angle, which is in 16ths
8772 of a degree. This angle is used together with spanAngle() for representing
8773 an ellipse segment (a pie). By default, the start angle is 0.
8775 \sa startAngle(), setSpanAngle(), QPainter::drawPie()
8777 void QGraphicsEllipseItem::setStartAngle(int angle)
8779 Q_D(QGraphicsEllipseItem);
8780 if (angle != d->startAngle) {
8781 prepareGeometryChange();
8782 d->boundingRect = QRectF();
8783 d->startAngle = angle;
8789 Returns the span angle of an ellipse segment in 16ths of a degree. This
8790 angle is used together with startAngle() for representing an ellipse
8791 segment (a pie). By default, this function returns 5760 (360 * 16, a full
8794 \sa setSpanAngle(), startAngle()
8796 int QGraphicsEllipseItem::spanAngle() const
8798 Q_D(const QGraphicsEllipseItem);
8799 return d->spanAngle;
8803 Sets the span angle for an ellipse segment to \a angle, which is in 16ths
8804 of a degree. This angle is used together with startAngle() to represent an
8805 ellipse segment (a pie). By default, the span angle is 5760 (360 * 16, a
8808 \sa spanAngle(), setStartAngle(), QPainter::drawPie()
8810 void QGraphicsEllipseItem::setSpanAngle(int angle)
8812 Q_D(QGraphicsEllipseItem);
8813 if (angle != d->spanAngle) {
8814 prepareGeometryChange();
8815 d->boundingRect = QRectF();
8816 d->spanAngle = angle;
8824 QRectF QGraphicsEllipseItem::boundingRect() const
8826 Q_D(const QGraphicsEllipseItem);
8827 if (d->boundingRect.isNull()) {
8828 qreal pw = pen().widthF();
8829 if (pw == 0.0 && d->spanAngle == 360 * 16)
8830 d->boundingRect = d->rect;
8832 d->boundingRect = shape().controlPointRect();
8834 return d->boundingRect;
8840 QPainterPath QGraphicsEllipseItem::shape() const
8842 Q_D(const QGraphicsEllipseItem);
8844 if (d->rect.isNull())
8846 if (d->spanAngle != 360 * 16) {
8847 path.moveTo(d->rect.center());
8848 path.arcTo(d->rect, d->startAngle / 16.0, d->spanAngle / 16.0);
8850 path.addEllipse(d->rect);
8853 return qt_graphicsItem_shapeFromPath(path, d->pen);
8859 bool QGraphicsEllipseItem::contains(const QPointF &point) const
8861 return QAbstractGraphicsShapeItem::contains(point);
8867 void QGraphicsEllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8870 Q_D(QGraphicsEllipseItem);
8872 painter->setPen(d->pen);
8873 painter->setBrush(d->brush);
8874 if ((d->spanAngle != 0) && (qAbs(d->spanAngle) % (360 * 16) == 0))
8875 painter->drawEllipse(d->rect);
8877 painter->drawPie(d->rect, d->startAngle, d->spanAngle);
8879 if (option->state & QStyle::State_Selected)
8880 qt_graphicsItem_highlightSelected(this, painter, option);
8886 bool QGraphicsEllipseItem::isObscuredBy(const QGraphicsItem *item) const
8888 return QAbstractGraphicsShapeItem::isObscuredBy(item);
8894 QPainterPath QGraphicsEllipseItem::opaqueArea() const
8896 return QAbstractGraphicsShapeItem::opaqueArea();
8902 int QGraphicsEllipseItem::type() const
8911 bool QGraphicsEllipseItem::supportsExtension(Extension extension) const
8913 Q_UNUSED(extension);
8920 void QGraphicsEllipseItem::setExtension(Extension extension, const QVariant &variant)
8922 Q_UNUSED(extension);
8929 QVariant QGraphicsEllipseItem::extension(const QVariant &variant) const
8936 \class QGraphicsPolygonItem
8937 \brief The QGraphicsPolygonItem class provides a polygon item that you
8938 can add to a QGraphicsScene.
8940 \ingroup graphicsview-api
8943 To set the item's polygon, pass a QPolygonF to
8944 QGraphicsPolygonItem's constructor, or call the setPolygon()
8945 function. The polygon() function returns the current polygon.
8947 \image graphicsview-polygonitem.png
8949 QGraphicsPolygonItem uses the polygon and the pen width to provide
8950 a reasonable implementation of boundingRect(), shape(), and
8951 contains(). The paint() function draws the polygon using the
8952 item's associated pen and brush, which you can set by calling the
8953 setPen() and setBrush() functions.
8955 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
8956 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8960 class QGraphicsPolygonItemPrivate : public QAbstractGraphicsShapeItemPrivate
8962 Q_DECLARE_PUBLIC(QGraphicsPolygonItem)
8964 inline QGraphicsPolygonItemPrivate()
8965 : fillRule(Qt::OddEvenFill)
8969 Qt::FillRule fillRule;
8973 Constructs a QGraphicsPolygonItem with \a polygon as the default
8974 polygon. \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8976 \sa QGraphicsScene::addItem()
8978 QGraphicsPolygonItem::QGraphicsPolygonItem(const QPolygonF &polygon,
8979 QGraphicsItem *parent
8981 // obsolete argument
8982 , QGraphicsScene *scene
8985 : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
8987 setPolygon(polygon);
8991 Constructs a QGraphicsPolygonItem. \a parent is passed to
8992 QAbstractGraphicsShapeItem's constructor.
8994 \sa QGraphicsScene::addItem()
8996 QGraphicsPolygonItem::QGraphicsPolygonItem(QGraphicsItem *parent
8998 // obsolete argument
8999 , QGraphicsScene *scene
9002 : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
9007 Destroys the QGraphicsPolygonItem.
9009 QGraphicsPolygonItem::~QGraphicsPolygonItem()
9014 Returns the item's polygon, or an empty polygon if no polygon
9019 QPolygonF QGraphicsPolygonItem::polygon() const
9021 Q_D(const QGraphicsPolygonItem);
9026 Sets the item's polygon to be the given \a polygon.
9030 void QGraphicsPolygonItem::setPolygon(const QPolygonF &polygon)
9032 Q_D(QGraphicsPolygonItem);
9033 if (d->polygon == polygon)
9035 prepareGeometryChange();
9036 d->polygon = polygon;
9037 d->boundingRect = QRectF();
9042 Returns the fill rule of the polygon. The default fill rule is
9045 \sa setFillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
9047 Qt::FillRule QGraphicsPolygonItem::fillRule() const
9049 Q_D(const QGraphicsPolygonItem);
9054 Sets the fill rule of the polygon to \a rule. The default fill rule is
9057 \sa fillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
9059 void QGraphicsPolygonItem::setFillRule(Qt::FillRule rule)
9061 Q_D(QGraphicsPolygonItem);
9062 if (rule != d->fillRule) {
9071 QRectF QGraphicsPolygonItem::boundingRect() const
9073 Q_D(const QGraphicsPolygonItem);
9074 if (d->boundingRect.isNull()) {
9075 qreal pw = pen().widthF();
9077 d->boundingRect = d->polygon.boundingRect();
9079 d->boundingRect = shape().controlPointRect();
9081 return d->boundingRect;
9087 QPainterPath QGraphicsPolygonItem::shape() const
9089 Q_D(const QGraphicsPolygonItem);
9091 path.addPolygon(d->polygon);
9092 return qt_graphicsItem_shapeFromPath(path, d->pen);
9098 bool QGraphicsPolygonItem::contains(const QPointF &point) const
9100 return QAbstractGraphicsShapeItem::contains(point);
9106 void QGraphicsPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
9108 Q_D(QGraphicsPolygonItem);
9110 painter->setPen(d->pen);
9111 painter->setBrush(d->brush);
9112 painter->drawPolygon(d->polygon, d->fillRule);
9114 if (option->state & QStyle::State_Selected)
9115 qt_graphicsItem_highlightSelected(this, painter, option);
9121 bool QGraphicsPolygonItem::isObscuredBy(const QGraphicsItem *item) const
9123 return QAbstractGraphicsShapeItem::isObscuredBy(item);
9129 QPainterPath QGraphicsPolygonItem::opaqueArea() const
9131 return QAbstractGraphicsShapeItem::opaqueArea();
9137 int QGraphicsPolygonItem::type() const
9145 bool QGraphicsPolygonItem::supportsExtension(Extension extension) const
9147 Q_UNUSED(extension);
9154 void QGraphicsPolygonItem::setExtension(Extension extension, const QVariant &variant)
9156 Q_UNUSED(extension);
9163 QVariant QGraphicsPolygonItem::extension(const QVariant &variant) const
9170 \class QGraphicsLineItem
9171 \brief The QGraphicsLineItem class provides a line item that you can add to a
9174 \ingroup graphicsview-api
9177 To set the item's line, pass a QLineF to QGraphicsLineItem's
9178 constructor, or call the setLine() function. The line() function
9179 returns the current line. By default the line is black with a
9180 width of 0, but you can change this by calling setPen().
9182 \img graphicsview-lineitem.png
9184 QGraphicsLineItem uses the line and the pen width to provide a reasonable
9185 implementation of boundingRect(), shape(), and contains(). The paint()
9186 function draws the line using the item's associated pen.
9188 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
9189 QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsPixmapItem,
9190 {Graphics View Framework}
9193 class QGraphicsLineItemPrivate : public QGraphicsItemPrivate
9195 Q_DECLARE_PUBLIC(QGraphicsLineItem)
9202 Constructs a QGraphicsLineItem, using \a line as the default line. \a
9203 parent is passed to QGraphicsItem's constructor.
9205 \sa QGraphicsScene::addItem()
9207 QGraphicsLineItem::QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent
9209 // obsolete argument
9210 , QGraphicsScene *scene
9213 : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
9219 Constructs a QGraphicsLineItem, using the line between (\a x1, \a y1) and
9220 (\a x2, \a y2) as the default line. \a parent is passed to
9221 QGraphicsItem's constructor.
9223 \sa QGraphicsScene::addItem()
9225 QGraphicsLineItem::QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent
9227 // obsolete argument
9228 , QGraphicsScene *scene
9231 : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
9233 setLine(x1, y1, x2, y2);
9239 Constructs a QGraphicsLineItem. \a parent is passed to QGraphicsItem's
9242 \sa QGraphicsScene::addItem()
9244 QGraphicsLineItem::QGraphicsLineItem(QGraphicsItem *parent
9246 // obsolete argument
9247 , QGraphicsScene *scene
9250 : QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
9255 Destroys the QGraphicsLineItem.
9257 QGraphicsLineItem::~QGraphicsLineItem()
9262 Returns the item's pen, or a black solid 0-width pen if no pen has
9267 QPen QGraphicsLineItem::pen() const
9269 Q_D(const QGraphicsLineItem);
9274 Sets the item's pen to \a pen. If no pen is set, the line will be painted
9275 using a black solid 0-width pen.
9279 void QGraphicsLineItem::setPen(const QPen &pen)
9281 Q_D(QGraphicsLineItem);
9284 prepareGeometryChange();
9290 Returns the item's line, or a null line if no line has been set.
9294 QLineF QGraphicsLineItem::line() const
9296 Q_D(const QGraphicsLineItem);
9301 Sets the item's line to be the given \a line.
9305 void QGraphicsLineItem::setLine(const QLineF &line)
9307 Q_D(QGraphicsLineItem);
9308 if (d->line == line)
9310 prepareGeometryChange();
9316 \fn void QGraphicsLineItem::setLine(qreal x1, qreal y1, qreal x2, qreal y2)
9319 Sets the item's line to be the line between (\a x1, \a y1) and (\a
9322 This is the same as calling \c {setLine(QLineF(x1, y1, x2, y2))}.
9328 QRectF QGraphicsLineItem::boundingRect() const
9330 Q_D(const QGraphicsLineItem);
9331 if (d->pen.widthF() == 0.0) {
9332 const qreal x1 = d->line.p1().x();
9333 const qreal x2 = d->line.p2().x();
9334 const qreal y1 = d->line.p1().y();
9335 const qreal y2 = d->line.p2().y();
9336 qreal lx = qMin(x1, x2);
9337 qreal rx = qMax(x1, x2);
9338 qreal ty = qMin(y1, y2);
9339 qreal by = qMax(y1, y2);
9340 return QRectF(lx, ty, rx - lx, by - ty);
9342 return shape().controlPointRect();
9348 QPainterPath QGraphicsLineItem::shape() const
9350 Q_D(const QGraphicsLineItem);
9352 if (d->line == QLineF())
9355 path.moveTo(d->line.p1());
9356 path.lineTo(d->line.p2());
9357 return qt_graphicsItem_shapeFromPath(path, d->pen);
9363 bool QGraphicsLineItem::contains(const QPointF &point) const
9365 return QGraphicsItem::contains(point);
9371 void QGraphicsLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
9373 Q_D(QGraphicsLineItem);
9375 painter->setPen(d->pen);
9376 painter->drawLine(d->line);
9378 if (option->state & QStyle::State_Selected)
9379 qt_graphicsItem_highlightSelected(this, painter, option);
9385 bool QGraphicsLineItem::isObscuredBy(const QGraphicsItem *item) const
9387 return QGraphicsItem::isObscuredBy(item);
9393 QPainterPath QGraphicsLineItem::opaqueArea() const
9395 return QGraphicsItem::opaqueArea();
9401 int QGraphicsLineItem::type() const
9409 bool QGraphicsLineItem::supportsExtension(Extension extension) const
9411 Q_UNUSED(extension);
9418 void QGraphicsLineItem::setExtension(Extension extension, const QVariant &variant)
9420 Q_UNUSED(extension);
9427 QVariant QGraphicsLineItem::extension(const QVariant &variant) const
9434 \class QGraphicsPixmapItem
9435 \brief The QGraphicsPixmapItem class provides a pixmap item that you can add to
9438 \ingroup graphicsview-api
9441 To set the item's pixmap, pass a QPixmap to QGraphicsPixmapItem's
9442 constructor, or call the setPixmap() function. The pixmap()
9443 function returns the current pixmap.
9445 QGraphicsPixmapItem uses pixmap's optional alpha mask to provide a
9446 reasonable implementation of boundingRect(), shape(), and contains().
9448 \image graphicsview-pixmapitem.png
9450 The pixmap is drawn at the item's (0, 0) coordinate, as returned by
9451 offset(). You can change the drawing offset by calling setOffset().
9453 You can set the pixmap's transformation mode by calling
9454 setTransformationMode(). By default, Qt::FastTransformation is used, which
9455 provides fast, non-smooth scaling. Qt::SmoothTransformation enables
9456 QPainter::SmoothPixmapTransform on the painter, and the quality depends on
9457 the platform and viewport. The result is usually not as good as calling
9458 QPixmap::scale() directly. Call transformationMode() to get the current
9459 transformation mode for the item.
9461 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
9462 QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsLineItem,
9463 {Graphics View Framework}
9467 \enum QGraphicsPixmapItem::ShapeMode
9469 This enum describes how QGraphicsPixmapItem calculates its shape and
9472 The default value is MaskShape.
9474 \value MaskShape The shape is determined by calling QPixmap::mask().
9475 This shape includes only the opaque pixels of the pixmap.
9476 Because the shape is more complex, however, it can be slower than the other modes,
9477 and uses more memory.
9479 \value BoundingRectShape The shape is determined by tracing the outline of
9480 the pixmap. This is the fastest shape mode, but it does not take into account
9481 any transparent areas on the pixmap.
9483 \value HeuristicMaskShape The shape is determine by calling
9484 QPixmap::createHeuristicMask(). The performance and memory consumption
9485 is similar to MaskShape.
9487 extern QPainterPath qt_regionToPath(const QRegion ®ion);
9489 class QGraphicsPixmapItemPrivate : public QGraphicsItemPrivate
9491 Q_DECLARE_PUBLIC(QGraphicsPixmapItem)
9493 QGraphicsPixmapItemPrivate()
9494 : transformationMode(Qt::FastTransformation),
9495 shapeMode(QGraphicsPixmapItem::MaskShape),
9500 Qt::TransformationMode transformationMode;
9502 QGraphicsPixmapItem::ShapeMode shapeMode;
9508 shape = QPainterPath();
9509 switch (shapeMode) {
9510 case QGraphicsPixmapItem::MaskShape: {
9511 QBitmap mask = pixmap.mask();
9512 if (!mask.isNull()) {
9513 shape = qt_regionToPath(QRegion(mask).translated(offset.toPoint()));
9518 case QGraphicsPixmapItem::BoundingRectShape:
9519 shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
9521 case QGraphicsPixmapItem::HeuristicMaskShape:
9522 #ifndef QT_NO_IMAGE_HEURISTIC_MASK
9523 shape = qt_regionToPath(QRegion(pixmap.createHeuristicMask()).translated(offset.toPoint()));
9525 shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
9533 Constructs a QGraphicsPixmapItem, using \a pixmap as the default pixmap.
9534 \a parent is passed to QGraphicsItem's constructor.
9536 \sa QGraphicsScene::addItem()
9538 QGraphicsPixmapItem::QGraphicsPixmapItem(const QPixmap &pixmap,
9539 QGraphicsItem *parent
9541 // obsolete argument
9542 , QGraphicsScene *scene
9545 : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
9551 Constructs a QGraphicsPixmapItem. \a parent is passed to QGraphicsItem's
9554 \sa QGraphicsScene::addItem()
9556 QGraphicsPixmapItem::QGraphicsPixmapItem(QGraphicsItem *parent
9558 // obsolete argument
9559 , QGraphicsScene *scene
9562 : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
9567 Destroys the QGraphicsPixmapItem.
9569 QGraphicsPixmapItem::~QGraphicsPixmapItem()
9574 Sets the item's pixmap to \a pixmap.
9578 void QGraphicsPixmapItem::setPixmap(const QPixmap &pixmap)
9580 Q_D(QGraphicsPixmapItem);
9581 prepareGeometryChange();
9583 d->hasShape = false;
9588 Returns the item's pixmap, or an invalid QPixmap if no pixmap has been
9593 QPixmap QGraphicsPixmapItem::pixmap() const
9595 Q_D(const QGraphicsPixmapItem);
9600 Returns the transformation mode of the pixmap. The default mode is
9601 Qt::FastTransformation, which provides quick transformation with no
9604 \sa setTransformationMode()
9606 Qt::TransformationMode QGraphicsPixmapItem::transformationMode() const
9608 Q_D(const QGraphicsPixmapItem);
9609 return d->transformationMode;
9613 Sets the pixmap item's transformation mode to \a mode, and toggles an
9614 update of the item. The default mode is Qt::FastTransformation, which
9615 provides quick transformation with no smoothing.
9617 Qt::SmoothTransformation enables QPainter::SmoothPixmapTransform on the
9618 painter, and the quality depends on the platform and viewport. The result
9619 is usually not as good as calling QPixmap::scale() directly.
9621 \sa transformationMode()
9623 void QGraphicsPixmapItem::setTransformationMode(Qt::TransformationMode mode)
9625 Q_D(QGraphicsPixmapItem);
9626 if (mode != d->transformationMode) {
9627 d->transformationMode = mode;
9633 Returns the pixmap item's \e offset, which defines the point of the
9634 top-left corner of the pixmap, in local coordinates.
9638 QPointF QGraphicsPixmapItem::offset() const
9640 Q_D(const QGraphicsPixmapItem);
9645 Sets the pixmap item's offset to \a offset. QGraphicsPixmapItem will draw
9646 its pixmap using \a offset for its top-left corner.
9650 void QGraphicsPixmapItem::setOffset(const QPointF &offset)
9652 Q_D(QGraphicsPixmapItem);
9653 if (d->offset == offset)
9655 prepareGeometryChange();
9657 d->hasShape = false;
9662 \fn void QGraphicsPixmapItem::setOffset(qreal x, qreal y)
9665 This convenience function is equivalent to calling setOffset(QPointF(\a x, \a y)).
9671 QRectF QGraphicsPixmapItem::boundingRect() const
9673 Q_D(const QGraphicsPixmapItem);
9674 if (d->pixmap.isNull())
9676 if (d->flags & ItemIsSelectable) {
9678 return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
9680 return QRectF(d->offset, d->pixmap.size());
9687 QPainterPath QGraphicsPixmapItem::shape() const
9689 Q_D(const QGraphicsPixmapItem);
9691 QGraphicsPixmapItemPrivate *thatD = const_cast<QGraphicsPixmapItemPrivate *>(d);
9692 thatD->updateShape();
9693 thatD->hasShape = true;
9695 return d_func()->shape;
9701 bool QGraphicsPixmapItem::contains(const QPointF &point) const
9703 return QGraphicsItem::contains(point);
9709 void QGraphicsPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
9712 Q_D(QGraphicsPixmapItem);
9715 painter->setRenderHint(QPainter::SmoothPixmapTransform,
9716 (d->transformationMode == Qt::SmoothTransformation));
9718 painter->drawPixmap(d->offset, d->pixmap);
9720 if (option->state & QStyle::State_Selected)
9721 qt_graphicsItem_highlightSelected(this, painter, option);
9727 bool QGraphicsPixmapItem::isObscuredBy(const QGraphicsItem *item) const
9729 return QGraphicsItem::isObscuredBy(item);
9735 QPainterPath QGraphicsPixmapItem::opaqueArea() const
9743 int QGraphicsPixmapItem::type() const
9749 Returns the item's shape mode. The shape mode describes how
9750 QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
9752 \sa setShapeMode(), ShapeMode
9754 QGraphicsPixmapItem::ShapeMode QGraphicsPixmapItem::shapeMode() const
9756 return d_func()->shapeMode;
9760 Sets the item's shape mode to \a mode. The shape mode describes how
9761 QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
9763 \sa shapeMode(), ShapeMode
9765 void QGraphicsPixmapItem::setShapeMode(ShapeMode mode)
9767 Q_D(QGraphicsPixmapItem);
9768 if (d->shapeMode == mode)
9770 d->shapeMode = mode;
9771 d->hasShape = false;
9777 bool QGraphicsPixmapItem::supportsExtension(Extension extension) const
9779 Q_UNUSED(extension);
9786 void QGraphicsPixmapItem::setExtension(Extension extension, const QVariant &variant)
9788 Q_UNUSED(extension);
9795 QVariant QGraphicsPixmapItem::extension(const QVariant &variant) const
9802 \class QGraphicsTextItem
9803 \brief The QGraphicsTextItem class provides a text item that you can add to
9804 a QGraphicsScene to display formatted text.
9806 \ingroup graphicsview-api
9809 If you only need to show plain text in an item, consider using QGraphicsSimpleTextItem
9812 To set the item's text, pass a QString to QGraphicsTextItem's
9813 constructor, or call setHtml()/setPlainText().
9815 QGraphicsTextItem uses the text's formatted size and the associated font
9816 to provide a reasonable implementation of boundingRect(), shape(),
9817 and contains(). You can set the font by calling setFont().
9819 It is possible to make the item editable by setting the Qt::TextEditorInteraction flag
9820 using setTextInteractionFlags().
9822 The item's preferred text width can be set using setTextWidth() and obtained
9825 \note In order to align HTML text in the center, the item's text width must be set.
9827 \img graphicsview-textitem.png
9829 \note QGraphicsTextItem accepts \l{QGraphicsItem::acceptHoverEvents()}{hover events}
9830 by default. You can change this with \l{QGraphicsItem::}{setAcceptHoverEvents()}.
9832 \sa QGraphicsSimpleTextItem, QGraphicsPathItem, QGraphicsRectItem,
9833 QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
9834 QGraphicsLineItem, {Graphics View Framework}
9837 class QGraphicsTextItemPrivate
9840 QGraphicsTextItemPrivate()
9841 : control(0), pageNumber(0), useDefaultImpl(false), tabChangesFocus(false), clickCausedFocus(0)
9844 mutable QWidgetTextControl *control;
9845 QWidgetTextControl *textControl() const;
9847 inline QPointF controlOffset() const
9848 { return QPointF(0., pageNumber * control->document()->pageSize().height()); }
9849 inline void sendControlEvent(QEvent *e)
9850 { if (control) control->processEvent(e, controlOffset()); }
9852 void _q_updateBoundingRect(const QSizeF &);
9853 void _q_update(QRectF);
9854 void _q_ensureVisible(QRectF);
9855 bool _q_mouseOnEdge(QGraphicsSceneMouseEvent *);
9857 QRectF boundingRect;
9859 bool useDefaultImpl;
9860 bool tabChangesFocus;
9862 uint clickCausedFocus : 1;
9864 QGraphicsTextItem *qq;
9869 Constructs a QGraphicsTextItem, using \a text as the default plain
9870 text. \a parent is passed to QGraphicsItem's constructor.
9872 \sa QGraphicsScene::addItem()
9874 QGraphicsTextItem::QGraphicsTextItem(const QString &text, QGraphicsItem *parent
9876 // obsolete argument
9877 , QGraphicsScene *scene
9880 : QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
9883 if (!text.isEmpty())
9885 setAcceptDrops(true);
9886 setAcceptHoverEvents(true);
9887 setFlags(ItemUsesExtendedStyleOption);
9891 Constructs a QGraphicsTextItem. \a parent is passed to QGraphicsItem's
9894 \sa QGraphicsScene::addItem()
9896 QGraphicsTextItem::QGraphicsTextItem(QGraphicsItem *parent
9898 // obsolete argument
9899 , QGraphicsScene *scene
9902 : QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
9905 setAcceptDrops(true);
9906 setAcceptHoverEvents(true);
9907 setFlag(ItemUsesExtendedStyleOption);
9911 Destroys the QGraphicsTextItem.
9913 QGraphicsTextItem::~QGraphicsTextItem()
9919 Returns the item's text converted to HTML, or an empty QString if no text has been set.
9923 QString QGraphicsTextItem::toHtml() const
9925 #ifndef QT_NO_TEXTHTMLPARSER
9927 return dd->control->toHtml();
9933 Sets the item's text to \a text, assuming that text is HTML formatted. If
9934 the item has keyboard input focus, this function will also call
9935 ensureVisible() to ensure that the text is visible in all viewports.
9937 \sa toHtml(), hasFocus(), QGraphicsSimpleTextItem
9939 void QGraphicsTextItem::setHtml(const QString &text)
9941 dd->textControl()->setHtml(text);
9945 Returns the item's text converted to plain text, or an empty QString if no text has been set.
9949 QString QGraphicsTextItem::toPlainText() const
9952 return dd->control->toPlainText();
9957 Sets the item's text to \a text. If the item has keyboard input focus,
9958 this function will also call ensureVisible() to ensure that the text is
9959 visible in all viewports.
9961 \sa toHtml(), hasFocus()
9963 void QGraphicsTextItem::setPlainText(const QString &text)
9965 dd->textControl()->setPlainText(text);
9969 Returns the item's font, which is used to render the text.
9973 QFont QGraphicsTextItem::font() const
9977 return dd->control->document()->defaultFont();
9981 Sets the font used to render the text item to \a font.
9985 void QGraphicsTextItem::setFont(const QFont &font)
9987 dd->textControl()->document()->setDefaultFont(font);
9991 Sets the color for unformatted text to \a col.
9993 void QGraphicsTextItem::setDefaultTextColor(const QColor &col)
9995 QWidgetTextControl *c = dd->textControl();
9996 QPalette pal = c->palette();
9997 QColor old = pal.color(QPalette::Text);
9998 pal.setColor(QPalette::Text, col);
10005 Returns the default text color that is used to for unformatted text.
10007 QColor QGraphicsTextItem::defaultTextColor() const
10009 return dd->textControl()->palette().color(QPalette::Text);
10015 QRectF QGraphicsTextItem::boundingRect() const
10017 return dd->boundingRect;
10023 QPainterPath QGraphicsTextItem::shape() const
10026 return QPainterPath();
10028 path.addRect(dd->boundingRect);
10035 bool QGraphicsTextItem::contains(const QPointF &point) const
10037 return dd->boundingRect.contains(point);
10043 void QGraphicsTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
10049 QRectF r = option->exposedRect;
10050 painter->translate(-dd->controlOffset());
10051 r.translate(dd->controlOffset());
10053 QTextDocument *doc = dd->control->document();
10054 QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
10056 // the layout might need to expand the root frame to
10057 // the viewport if NoWrap is set
10059 layout->setViewport(dd->boundingRect);
10061 dd->control->drawContents(painter, r);
10064 layout->setViewport(QRect());
10066 painter->restore();
10069 if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
10070 qt_graphicsItem_highlightSelected(this, painter, option);
10076 bool QGraphicsTextItem::isObscuredBy(const QGraphicsItem *item) const
10078 return QGraphicsItem::isObscuredBy(item);
10084 QPainterPath QGraphicsTextItem::opaqueArea() const
10086 return QGraphicsItem::opaqueArea();
10092 int QGraphicsTextItem::type() const
10098 Sets the preferred width for the item's text. If the actual text
10099 is wider than the specified width then it will be broken into
10102 If \a width is set to -1 then the text will not be broken into
10103 multiple lines unless it is enforced through an explicit line
10104 break or a new paragraph.
10106 The default value is -1.
10108 Note that QGraphicsTextItem keeps a QTextDocument internally,
10109 which is used to calculate the text width.
10111 \sa textWidth(), QTextDocument::setTextWidth()
10113 void QGraphicsTextItem::setTextWidth(qreal width)
10115 dd->textControl()->setTextWidth(width);
10119 Returns the text width.
10121 The width is calculated with the QTextDocument that
10122 QGraphicsTextItem keeps internally.
10124 \sa setTextWidth(), QTextDocument::textWidth()
10126 qreal QGraphicsTextItem::textWidth() const
10130 return dd->control->textWidth();
10134 Adjusts the text item to a reasonable size.
10136 void QGraphicsTextItem::adjustSize()
10139 dd->control->adjustSize();
10143 Sets the text document \a document on the item.
10145 void QGraphicsTextItem::setDocument(QTextDocument *document)
10147 dd->textControl()->setDocument(document);
10148 dd->_q_updateBoundingRect(dd->control->size());
10152 Returns the item's text document.
10154 QTextDocument *QGraphicsTextItem::document() const
10156 return dd->textControl()->document();
10162 bool QGraphicsTextItem::sceneEvent(QEvent *event)
10164 QEvent::Type t = event->type();
10165 if (!dd->tabChangesFocus && (t == QEvent::KeyPress || t == QEvent::KeyRelease)) {
10166 int k = ((QKeyEvent *)event)->key();
10167 if (k == Qt::Key_Tab || k == Qt::Key_Backtab) {
10168 dd->sendControlEvent(event);
10172 bool result = QGraphicsItem::sceneEvent(event);
10174 // Ensure input context is updated.
10175 switch (event->type()) {
10176 case QEvent::ContextMenu:
10177 case QEvent::FocusIn:
10178 case QEvent::FocusOut:
10179 case QEvent::GraphicsSceneDragEnter:
10180 case QEvent::GraphicsSceneDragLeave:
10181 case QEvent::GraphicsSceneDragMove:
10182 case QEvent::GraphicsSceneDrop:
10183 case QEvent::GraphicsSceneHoverEnter:
10184 case QEvent::GraphicsSceneHoverLeave:
10185 case QEvent::GraphicsSceneHoverMove:
10186 case QEvent::GraphicsSceneMouseDoubleClick:
10187 case QEvent::GraphicsSceneMousePress:
10188 case QEvent::GraphicsSceneMouseMove:
10189 case QEvent::GraphicsSceneMouseRelease:
10190 case QEvent::KeyPress:
10191 case QEvent::KeyRelease:
10192 // Reset the focus widget's input context, regardless
10193 // of how this item gained or lost focus.
10194 if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) {
10195 qApp->inputMethod()->reset();
10197 qApp->inputMethod()->update(Qt::ImQueryInput);
10200 case QEvent::ShortcutOverride:
10201 dd->sendControlEvent(event);
10213 void QGraphicsTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
10215 if ((QGraphicsItem::d_ptr->flags & (ItemIsSelectable | ItemIsMovable))
10216 && (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) {
10217 // User left-pressed on edge of selectable/movable item, use
10219 dd->useDefaultImpl = true;
10220 } else if (event->buttons() == event->button()
10221 && dd->control->textInteractionFlags() == Qt::NoTextInteraction) {
10222 // User pressed first button on non-interactive item.
10223 dd->useDefaultImpl = true;
10225 if (dd->useDefaultImpl) {
10226 QGraphicsItem::mousePressEvent(event);
10227 if (!event->isAccepted())
10228 dd->useDefaultImpl = false;
10232 dd->sendControlEvent(event);
10238 void QGraphicsTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
10240 if (dd->useDefaultImpl) {
10241 QGraphicsItem::mouseMoveEvent(event);
10245 dd->sendControlEvent(event);
10251 void QGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
10253 if (dd->useDefaultImpl) {
10254 QGraphicsItem::mouseReleaseEvent(event);
10255 if (dd->control->textInteractionFlags() == Qt::NoTextInteraction
10256 && !event->buttons()) {
10257 // User released last button on non-interactive item.
10258 dd->useDefaultImpl = false;
10259 } else if ((event->buttons() & Qt::LeftButton) == 0) {
10260 // User released the left button on an interactive item.
10261 dd->useDefaultImpl = false;
10266 QWidget *widget = event->widget();
10267 if (widget && (dd->control->textInteractionFlags() & Qt::TextEditable) && boundingRect().contains(event->pos())) {
10268 qt_widget_private(widget)->handleSoftwareInputPanel(event->button(), dd->clickCausedFocus);
10270 dd->clickCausedFocus = 0;
10271 dd->sendControlEvent(event);
10277 void QGraphicsTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
10279 if (dd->useDefaultImpl) {
10280 QGraphicsItem::mouseDoubleClickEvent(event);
10285 QGraphicsItem::mouseDoubleClickEvent(event);
10289 dd->sendControlEvent(event);
10295 void QGraphicsTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
10297 dd->sendControlEvent(event);
10303 void QGraphicsTextItem::keyPressEvent(QKeyEvent *event)
10305 dd->sendControlEvent(event);
10311 void QGraphicsTextItem::keyReleaseEvent(QKeyEvent *event)
10313 dd->sendControlEvent(event);
10319 void QGraphicsTextItem::focusInEvent(QFocusEvent *event)
10321 dd->sendControlEvent(event);
10322 if (event->reason() == Qt::MouseFocusReason) {
10323 dd->clickCausedFocus = 1;
10331 void QGraphicsTextItem::focusOutEvent(QFocusEvent *event)
10333 dd->sendControlEvent(event);
10340 void QGraphicsTextItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
10342 dd->sendControlEvent(event);
10348 void QGraphicsTextItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
10350 dd->sendControlEvent(event);
10356 void QGraphicsTextItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
10358 dd->sendControlEvent(event);
10364 void QGraphicsTextItem::dropEvent(QGraphicsSceneDragDropEvent *event)
10366 dd->sendControlEvent(event);
10372 void QGraphicsTextItem::inputMethodEvent(QInputMethodEvent *event)
10374 dd->sendControlEvent(event);
10380 void QGraphicsTextItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
10382 dd->sendControlEvent(event);
10388 void QGraphicsTextItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
10390 dd->sendControlEvent(event);
10396 void QGraphicsTextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
10398 dd->sendControlEvent(event);
10404 QVariant QGraphicsTextItem::inputMethodQuery(Qt::InputMethodQuery query) const
10408 v = dd->control->inputMethodQuery(query);
10409 if (v.type() == QVariant::RectF)
10410 v = v.toRectF().translated(-dd->controlOffset());
10411 else if (v.type() == QVariant::PointF)
10412 v = v.toPointF() - dd->controlOffset();
10413 else if (v.type() == QVariant::Rect)
10414 v = v.toRect().translated(-dd->controlOffset().toPoint());
10415 else if (v.type() == QVariant::Point)
10416 v = v.toPoint() - dd->controlOffset().toPoint();
10423 bool QGraphicsTextItem::supportsExtension(Extension extension) const
10425 Q_UNUSED(extension);
10432 void QGraphicsTextItem::setExtension(Extension extension, const QVariant &variant)
10434 Q_UNUSED(extension);
10441 QVariant QGraphicsTextItem::extension(const QVariant &variant) const
10450 void QGraphicsTextItemPrivate::_q_update(QRectF rect)
10452 if (rect.isValid()) {
10453 rect.translate(-controlOffset());
10455 rect = boundingRect;
10457 if (rect.intersects(boundingRect))
10464 void QGraphicsTextItemPrivate::_q_updateBoundingRect(const QSizeF &size)
10466 if (!control) return; // can't happen
10467 const QSizeF pageSize = control->document()->pageSize();
10468 // paged items have a constant (page) size
10469 if (size == boundingRect.size() || pageSize.height() != -1)
10471 qq->prepareGeometryChange();
10472 boundingRect.setSize(size);
10479 void QGraphicsTextItemPrivate::_q_ensureVisible(QRectF rect)
10481 if (qq->hasFocus()) {
10482 rect.translate(-controlOffset());
10483 qq->ensureVisible(rect, /*xmargin=*/0, /*ymargin=*/0);
10487 QWidgetTextControl *QGraphicsTextItemPrivate::textControl() const
10490 QGraphicsTextItem *that = const_cast<QGraphicsTextItem *>(qq);
10491 control = new QWidgetTextControl(that);
10492 control->setTextInteractionFlags(Qt::NoTextInteraction);
10494 QObject::connect(control, SIGNAL(updateRequest(QRectF)),
10495 qq, SLOT(_q_update(QRectF)));
10496 QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)),
10497 qq, SLOT(_q_updateBoundingRect(QSizeF)));
10498 QObject::connect(control, SIGNAL(visibilityRequest(QRectF)),
10499 qq, SLOT(_q_ensureVisible(QRectF)));
10500 QObject::connect(control, SIGNAL(linkActivated(QString)),
10501 qq, SIGNAL(linkActivated(QString)));
10502 QObject::connect(control, SIGNAL(linkHovered(QString)),
10503 qq, SIGNAL(linkHovered(QString)));
10505 const QSizeF pgSize = control->document()->pageSize();
10506 if (pgSize.height() != -1) {
10507 qq->prepareGeometryChange();
10508 that->dd->boundingRect.setSize(pgSize);
10511 that->dd->_q_updateBoundingRect(control->size());
10520 bool QGraphicsTextItemPrivate::_q_mouseOnEdge(QGraphicsSceneMouseEvent *event)
10523 path.addRect(qq->boundingRect());
10525 QPainterPath docPath;
10526 const QTextFrameFormat format = control->document()->rootFrame()->frameFormat();
10528 qq->boundingRect().adjusted(
10529 format.leftMargin(),
10530 format.topMargin(),
10531 -format.rightMargin(),
10532 -format.bottomMargin()));
10534 return path.subtracted(docPath).contains(event->pos());
10538 \fn QGraphicsTextItem::linkActivated(const QString &link)
10540 This signal is emitted when the user clicks on a link on a text item
10541 that enables Qt::LinksAccessibleByMouse or Qt::LinksAccessibleByKeyboard.
10542 \a link is the link that was clicked.
10544 \sa setTextInteractionFlags()
10548 \fn QGraphicsTextItem::linkHovered(const QString &link)
10550 This signal is emitted when the user hovers over a link on a text item
10551 that enables Qt::LinksAccessibleByMouse. \a link is
10552 the link that was hovered over.
10554 \sa setTextInteractionFlags()
10558 Sets the flags \a flags to specify how the text item should react to user
10561 The default for a QGraphicsTextItem is Qt::NoTextInteraction. This function
10562 also affects the ItemIsFocusable QGraphicsItem flag by setting it if \a flags
10563 is different from Qt::NoTextInteraction and clearing it otherwise.
10565 By default, the text is read-only. To transform the item into an editor,
10566 set the Qt::TextEditable flag.
10568 void QGraphicsTextItem::setTextInteractionFlags(Qt::TextInteractionFlags flags)
10570 if (flags == Qt::NoTextInteraction)
10571 setFlags(this->flags() & ~(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod));
10573 setFlags(this->flags() | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod);
10575 dd->textControl()->setTextInteractionFlags(flags);
10579 Returns the current text interaction flags.
10581 \sa setTextInteractionFlags()
10583 Qt::TextInteractionFlags QGraphicsTextItem::textInteractionFlags() const
10586 return Qt::NoTextInteraction;
10587 return dd->control->textInteractionFlags();
10593 If \a b is true, the \uicontrol Tab key will cause the widget to change focus;
10594 otherwise, the tab key will insert a tab into the document.
10596 In some occasions text edits should not allow the user to input tabulators
10597 or change indentation using the \uicontrol Tab key, as this breaks the focus
10598 chain. The default is false.
10600 \sa tabChangesFocus(), ItemIsFocusable, textInteractionFlags()
10602 void QGraphicsTextItem::setTabChangesFocus(bool b)
10604 dd->tabChangesFocus = b;
10610 Returns true if the \uicontrol Tab key will cause the widget to change focus;
10611 otherwise, false is returned.
10613 By default, this behavior is disabled, and this function will return false.
10615 \sa setTabChangesFocus()
10617 bool QGraphicsTextItem::tabChangesFocus() const
10619 return dd->tabChangesFocus;
10623 \property QGraphicsTextItem::openExternalLinks
10625 Specifies whether QGraphicsTextItem should automatically open links using
10626 QDesktopServices::openUrl() instead of emitting the
10627 linkActivated signal.
10629 The default value is false.
10631 void QGraphicsTextItem::setOpenExternalLinks(bool open)
10633 dd->textControl()->setOpenExternalLinks(open);
10636 bool QGraphicsTextItem::openExternalLinks() const
10640 return dd->control->openExternalLinks();
10644 \property QGraphicsTextItem::textCursor
10646 This property represents the visible text cursor in an editable
10649 By default, if the item's text has not been set, this property
10650 contains a null text cursor; otherwise it contains a text cursor
10651 placed at the start of the item's document.
10653 void QGraphicsTextItem::setTextCursor(const QTextCursor &cursor)
10655 dd->textControl()->setTextCursor(cursor);
10658 QTextCursor QGraphicsTextItem::textCursor() const
10661 return QTextCursor();
10662 return dd->control->textCursor();
10665 class QGraphicsSimpleTextItemPrivate : public QAbstractGraphicsShapeItemPrivate
10667 Q_DECLARE_PUBLIC(QGraphicsSimpleTextItem)
10669 inline QGraphicsSimpleTextItemPrivate() {
10670 pen.setStyle(Qt::NoPen);
10671 brush.setStyle(Qt::SolidPattern);
10675 QRectF boundingRect;
10677 void updateBoundingRect();
10680 static QRectF setupTextLayout(QTextLayout *layout)
10682 layout->setCacheEnabled(true);
10683 layout->beginLayout();
10684 while (layout->createLine().isValid())
10686 layout->endLayout();
10687 qreal maxWidth = 0;
10689 for (int i = 0; i < layout->lineCount(); ++i) {
10690 QTextLine line = layout->lineAt(i);
10691 maxWidth = qMax(maxWidth, line.naturalTextWidth());
10692 line.setPosition(QPointF(0, y));
10693 y += line.height();
10695 return QRectF(0, 0, maxWidth, y);
10698 void QGraphicsSimpleTextItemPrivate::updateBoundingRect()
10700 Q_Q(QGraphicsSimpleTextItem);
10702 if (text.isEmpty()) {
10705 QString tmp = text;
10706 tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
10707 QStackTextEngine engine(tmp, font);
10708 QTextLayout layout(&engine);
10709 br = setupTextLayout(&layout);
10711 if (br != boundingRect) {
10712 q->prepareGeometryChange();
10719 \class QGraphicsSimpleTextItem
10720 \brief The QGraphicsSimpleTextItem class provides a simple text path item
10721 that you can add to a QGraphicsScene.
10723 \ingroup graphicsview-api
10724 \inmodule QtWidgets
10726 To set the item's text, you can either pass a QString to
10727 QGraphicsSimpleTextItem's constructor, or call setText() to change the
10728 text later. To set the text fill color, call setBrush().
10730 The simple text item can have both a fill and an outline; setBrush() will
10731 set the text fill (i.e., text color), and setPen() sets the pen that will
10732 be used to draw the text outline. (The latter can be slow, especially for
10733 complex pens, and items with long text content.) If all you want is to
10734 draw a simple line of text, you should call setBrush() only, and leave the
10735 pen unset; QGraphicsSimpleTextItem's pen is by default Qt::NoPen.
10737 QGraphicsSimpleTextItem uses the text's formatted size and the associated
10738 font to provide a reasonable implementation of boundingRect(), shape(),
10739 and contains(). You can set the font by calling setFont().
10741 QGraphicsSimpleText does not display rich text; instead, you can use
10742 QGraphicsTextItem, which provides full text control capabilities.
10744 \img graphicsview-simpletextitem.png
10746 \sa QGraphicsTextItem, QGraphicsPathItem, QGraphicsRectItem,
10747 QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
10748 QGraphicsLineItem, {Graphics View Framework}
10752 Constructs a QGraphicsSimpleTextItem.
10754 \a parent is passed to QGraphicsItem's constructor.
10756 \sa QGraphicsScene::addItem()
10758 QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(QGraphicsItem *parent
10760 // obsolete argument
10761 , QGraphicsScene *scene
10764 : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
10769 Constructs a QGraphicsSimpleTextItem, using \a text as the default plain text.
10771 \a parent is passed to QGraphicsItem's constructor.
10773 \sa QGraphicsScene::addItem()
10775 QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent
10777 // obsolete argument
10778 , QGraphicsScene *scene
10781 : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
10787 Destroys the QGraphicsSimpleTextItem.
10789 QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem()
10794 Sets the item's text to \a text. The text will be displayed as
10795 plain text. Newline characters ('\n') as well as characters of
10796 type QChar::LineSeparator will cause item to break the text into
10799 void QGraphicsSimpleTextItem::setText(const QString &text)
10801 Q_D(QGraphicsSimpleTextItem);
10802 if (d->text == text)
10805 d->updateBoundingRect();
10810 Returns the item's text.
10812 QString QGraphicsSimpleTextItem::text() const
10814 Q_D(const QGraphicsSimpleTextItem);
10819 Sets the font that is used to draw the item's text to \a font.
10821 void QGraphicsSimpleTextItem::setFont(const QFont &font)
10823 Q_D(QGraphicsSimpleTextItem);
10825 d->updateBoundingRect();
10829 Returns the font that is used to draw the item's text.
10831 QFont QGraphicsSimpleTextItem::font() const
10833 Q_D(const QGraphicsSimpleTextItem);
10840 QRectF QGraphicsSimpleTextItem::boundingRect() const
10842 Q_D(const QGraphicsSimpleTextItem);
10843 return d->boundingRect;
10849 QPainterPath QGraphicsSimpleTextItem::shape() const
10851 Q_D(const QGraphicsSimpleTextItem);
10853 path.addRect(d->boundingRect);
10860 bool QGraphicsSimpleTextItem::contains(const QPointF &point) const
10862 Q_D(const QGraphicsSimpleTextItem);
10863 return d->boundingRect.contains(point);
10869 void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
10872 Q_D(QGraphicsSimpleTextItem);
10874 painter->setFont(d->font);
10876 QString tmp = d->text;
10877 tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
10878 QStackTextEngine engine(tmp, d->font);
10879 QTextLayout layout(&engine);
10880 setupTextLayout(&layout);
10883 p.setBrush(d->brush);
10884 painter->setPen(p);
10885 if (d->pen.style() == Qt::NoPen && d->brush.style() == Qt::SolidPattern) {
10886 painter->setBrush(Qt::NoBrush);
10888 QTextLayout::FormatRange range;
10890 range.length = layout.text().length();
10891 range.format.setTextOutline(d->pen);
10892 QList<QTextLayout::FormatRange> formats;
10893 formats.append(range);
10894 layout.setAdditionalFormats(formats);
10897 layout.draw(painter, QPointF(0, 0));
10899 if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
10900 qt_graphicsItem_highlightSelected(this, painter, option);
10906 bool QGraphicsSimpleTextItem::isObscuredBy(const QGraphicsItem *item) const
10908 return QAbstractGraphicsShapeItem::isObscuredBy(item);
10914 QPainterPath QGraphicsSimpleTextItem::opaqueArea() const
10916 return QAbstractGraphicsShapeItem::opaqueArea();
10922 int QGraphicsSimpleTextItem::type() const
10930 bool QGraphicsSimpleTextItem::supportsExtension(Extension extension) const
10932 Q_UNUSED(extension);
10939 void QGraphicsSimpleTextItem::setExtension(Extension extension, const QVariant &variant)
10941 Q_UNUSED(extension);
10948 QVariant QGraphicsSimpleTextItem::extension(const QVariant &variant) const
10955 \class QGraphicsItemGroup
10956 \brief The QGraphicsItemGroup class provides a container that treats
10957 a group of items as a single item.
10959 \ingroup graphicsview-api
10960 \inmodule QtWidgets
10962 A QGraphicsItemGroup is a special type of compound item that
10963 treats itself and all its children as one item (i.e., all events
10964 and geometries for all children are merged together). It's common
10965 to use item groups in presentation tools, when the user wants to
10966 group several smaller items into one big item in order to simplify
10967 moving and copying of items.
10969 If all you want is to store items inside other items, you can use
10970 any QGraphicsItem directly by passing a suitable parent to
10973 The boundingRect() function of QGraphicsItemGroup returns the
10974 bounding rectangle of all items in the item group.
10975 QGraphicsItemGroup ignores the ItemIgnoresTransformations flag on
10976 its children (i.e., with respect to the geometry of the group
10977 item, the children are treated as if they were transformable).
10979 There are two ways to construct an item group. The easiest and
10980 most common approach is to pass a list of items (e.g., all
10981 selected items) to QGraphicsScene::createItemGroup(), which
10982 returns a new QGraphicsItemGroup item. The other approach is to
10983 manually construct a QGraphicsItemGroup item, add it to the scene
10984 calling QGraphicsScene::addItem(), and then add items to the group
10985 manually, one at a time by calling addToGroup(). To dismantle
10986 ("ungroup") an item group, you can either call
10987 QGraphicsScene::destroyItemGroup(), or you can manually remove all
10988 items from the group by calling removeFromGroup().
10990 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 17
10992 The operation of adding and removing items preserves the items'
10993 scene-relative position and transformation, as opposed to calling
10994 setParentItem(), where only the child item's parent-relative
10995 position and transformation are kept.
10997 The addtoGroup() function reparents the target item to this item
10998 group, keeping the item's position and transformation intact
10999 relative to the scene. Visually, this means that items added via
11000 addToGroup() will remain completely unchanged as a result of this
11001 operation, regardless of the item or the group's current position
11002 or transformation; although the item's position and matrix are
11005 The removeFromGroup() function has similar semantics to
11006 setParentItem(); it reparents the item to the parent item of the
11007 item group. As with addToGroup(), the item's scene-relative
11008 position and transformation remain intact.
11010 \sa QGraphicsItem, {Graphics View Framework}
11013 class QGraphicsItemGroupPrivate : public QGraphicsItemPrivate
11016 QRectF itemsBoundingRect;
11020 Constructs a QGraphicsItemGroup. \a parent is passed to QGraphicsItem's
11023 \sa QGraphicsScene::addItem()
11025 QGraphicsItemGroup::QGraphicsItemGroup(QGraphicsItem *parent
11027 // obsolete argument
11028 , QGraphicsScene *scene
11031 : QGraphicsItem(*new QGraphicsItemGroupPrivate, parent, scene)
11033 setHandlesChildEvents(true);
11037 Destroys the QGraphicsItemGroup.
11039 QGraphicsItemGroup::~QGraphicsItemGroup()
11044 Adds the given \a item and item's child items to this item group.
11045 The item and child items will be reparented to this group, but its
11046 position and transformation relative to the scene will stay intact.
11048 \sa removeFromGroup(), QGraphicsScene::createItemGroup()
11050 void QGraphicsItemGroup::addToGroup(QGraphicsItem *item)
11052 Q_D(QGraphicsItemGroup);
11054 qWarning("QGraphicsItemGroup::addToGroup: cannot add null item");
11057 if (item == this) {
11058 qWarning("QGraphicsItemGroup::addToGroup: cannot add a group to itself");
11064 QTransform itemTransform = item->itemTransform(this, &ok);
11067 qWarning("QGraphicsItemGroup::addToGroup: could not find a valid transformation from item to group coordinates");
11071 QTransform newItemTransform(itemTransform);
11072 item->setPos(mapFromItem(item, 0, 0));
11073 item->setParentItem(this);
11075 // removing position from translation component of the new transform
11076 if (!item->pos().isNull())
11077 newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
11079 // removing additional transformations properties applied with itemTransform()
11080 QPointF origin = item->transformOriginPoint();
11082 QList<QGraphicsTransform*> transformList = item->transformations();
11083 for (int i = 0; i < transformList.size(); ++i)
11084 transformList.at(i)->applyTo(&m);
11085 newItemTransform *= m.toTransform().inverted();
11086 newItemTransform.translate(origin.x(), origin.y());
11087 newItemTransform.rotate(-item->rotation());
11088 newItemTransform.scale(1/item->scale(), 1/item->scale());
11089 newItemTransform.translate(-origin.x(), -origin.y());
11091 // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
11093 item->setTransform(newItemTransform);
11094 item->d_func()->setIsMemberOfGroup(true);
11095 prepareGeometryChange();
11096 d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
11101 Removes the specified \a item from this group. The item will be
11102 reparented to this group's parent item, or to 0 if this group has
11103 no parent. Its position and transformation relative to the scene
11106 \sa addToGroup(), QGraphicsScene::destroyItemGroup()
11108 void QGraphicsItemGroup::removeFromGroup(QGraphicsItem *item)
11110 Q_D(QGraphicsItemGroup);
11112 qWarning("QGraphicsItemGroup::removeFromGroup: cannot remove null item");
11116 QGraphicsItem *newParent = d_ptr->parent;
11120 QTransform itemTransform;
11122 itemTransform = item->itemTransform(newParent, &ok);
11124 itemTransform = item->sceneTransform();
11126 QPointF oldPos = item->mapToItem(newParent, 0, 0);
11127 item->setParentItem(newParent);
11128 item->setPos(oldPos);
11130 // removing position from translation component of the new transform
11131 if (!item->pos().isNull())
11132 itemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
11134 // removing additional transformations properties applied
11135 // with itemTransform() or sceneTransform()
11136 QPointF origin = item->transformOriginPoint();
11138 QList<QGraphicsTransform*> transformList = item->transformations();
11139 for (int i = 0; i < transformList.size(); ++i)
11140 transformList.at(i)->applyTo(&m);
11141 itemTransform *= m.toTransform().inverted();
11142 itemTransform.translate(origin.x(), origin.y());
11143 itemTransform.rotate(-item->rotation());
11144 itemTransform.scale(1 / item->scale(), 1 / item->scale());
11145 itemTransform.translate(-origin.x(), -origin.y());
11147 // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
11149 item->setTransform(itemTransform);
11150 item->d_func()->setIsMemberOfGroup(item->group() != 0);
11152 // ### Quite expensive. But removeFromGroup() isn't called very often.
11153 prepareGeometryChange();
11154 d->itemsBoundingRect = childrenBoundingRect();
11160 Returns the bounding rect of this group item, and all its children.
11162 QRectF QGraphicsItemGroup::boundingRect() const
11164 Q_D(const QGraphicsItemGroup);
11165 return d->itemsBoundingRect;
11171 void QGraphicsItemGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
11175 if (option->state & QStyle::State_Selected) {
11176 Q_D(QGraphicsItemGroup);
11177 painter->setBrush(Qt::NoBrush);
11178 painter->drawRect(d->itemsBoundingRect);
11185 bool QGraphicsItemGroup::isObscuredBy(const QGraphicsItem *item) const
11187 return QGraphicsItem::isObscuredBy(item);
11193 QPainterPath QGraphicsItemGroup::opaqueArea() const
11195 return QGraphicsItem::opaqueArea();
11201 int QGraphicsItemGroup::type() const
11206 #ifndef QT_NO_GRAPHICSEFFECT
11207 QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
11209 const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
11210 if (!info && deviceCoordinates) {
11211 // Device coordinates without info not yet supported.
11212 qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
11216 QRectF rect = item->boundingRect();
11217 if (!item->d_ptr->children.isEmpty())
11218 rect |= item->childrenBoundingRect();
11220 if (deviceCoordinates) {
11221 Q_ASSERT(info->painter);
11222 rect = info->painter->worldTransform().mapRect(rect);
11228 void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter)
11231 qWarning("QGraphicsEffectSource::draw: Can only begin as a result of QGraphicsEffect::draw");
11235 Q_ASSERT(item->d_ptr->scene);
11236 QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
11237 if (painter == info->painter) {
11238 scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
11239 info->widget, info->opacity, info->effectTransform, info->wasDirtySceneTransform,
11242 QTransform effectTransform = info->painter->worldTransform().inverted();
11243 effectTransform *= painter->worldTransform();
11244 scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
11245 info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
11250 // sourceRect must be in the given coordinate system
11251 QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
11253 QRectF effectRectF;
11258 if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
11260 QRectF deviceRect = system == Qt::DeviceCoordinates ? sourceRect : info->painter->worldTransform().mapRect(sourceRect);
11261 effectRectF = item->graphicsEffect()->boundingRectFor(deviceRect);
11263 *unpadded = (effectRectF.size() == sourceRect.size());
11264 if (info && system == Qt::LogicalCoordinates)
11265 effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
11267 // no choice but to send a logical coordinate bounding rect to boundingRectFor
11268 effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect);
11270 } else if (mode == QGraphicsEffect::PadToTransparentBorder) {
11271 // adjust by 1.5 to account for cosmetic pens
11272 effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
11274 effectRectF = sourceRect;
11279 return effectRectF.toAlignedRect();
11282 QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
11283 QGraphicsEffect::PixmapPadMode mode) const
11285 const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
11286 if (!info && deviceCoordinates) {
11287 // Device coordinates without info not yet supported.
11288 qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
11291 if (!item->d_ptr->scene)
11293 QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
11296 const QRectF sourceRect = boundingRect(system);
11297 QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded);
11300 *offset = effectRect.topLeft();
11302 bool untransformed = !deviceCoordinates
11303 || info->painter->worldTransform().type() <= QTransform::TxTranslate;
11304 if (untransformed && unpadded && isPixmap()) {
11306 *offset = boundingRect(system).topLeft().toPoint();
11307 return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
11310 if (effectRect.isEmpty())
11313 QPixmap pixmap(effectRect.size());
11314 pixmap.fill(Qt::transparent);
11315 QPainter pixmapPainter(&pixmap);
11316 pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing);
11318 QTransform effectTransform = QTransform::fromTranslate(-effectRect.x(), -effectRect.y());
11319 if (deviceCoordinates && info->effectTransform)
11320 effectTransform *= *info->effectTransform;
11323 // Logical coordinates without info.
11324 QTransform sceneTransform = item->sceneTransform();
11325 QTransform newEffectTransform = sceneTransform.inverted();
11326 newEffectTransform *= effectTransform;
11327 scened->draw(item, &pixmapPainter, 0, &sceneTransform, 0, 0, qreal(1.0),
11328 &newEffectTransform, false, true);
11329 } else if (deviceCoordinates) {
11330 // Device coordinates with info.
11331 scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
11332 info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
11335 // Item coordinates with info.
11336 QTransform newEffectTransform = info->transformPtr->inverted();
11337 newEffectTransform *= effectTransform;
11338 scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
11339 info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform,
11343 pixmapPainter.end();
11347 #endif //QT_NO_GRAPHICSEFFECT
11349 #ifndef QT_NO_DEBUG_STREAM
11350 QDebug operator<<(QDebug debug, QGraphicsItem *item)
11353 debug << "QGraphicsItem(0)";
11357 if (QGraphicsObject *o = item->toGraphicsObject())
11358 debug << o->metaObject()->className();
11360 debug << "QGraphicsItem";
11361 debug << "(this =" << (void*)item
11362 << ", parent =" << (void*)item->parentItem()
11363 << ", pos =" << item->pos()
11364 << ", z =" << item->zValue() << ", flags = "
11365 << item->flags() << ")";
11369 QDebug operator<<(QDebug debug, QGraphicsObject *item)
11372 debug << "QGraphicsObject(0)";
11376 debug.nospace() << item->metaObject()->className() << '(' << (void*)item;
11377 if (!item->objectName().isEmpty())
11378 debug << ", name = " << item->objectName();
11379 debug.nospace() << ", parent = " << ((void*)item->parentItem())
11380 << ", pos = " << item->pos()
11381 << ", z = " << item->zValue() << ", flags = "
11382 << item->flags() << ')';
11383 return debug.space();
11386 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change)
11388 const char *str = "UnknownChange";
11390 case QGraphicsItem::ItemChildAddedChange:
11391 str = "ItemChildAddedChange";
11393 case QGraphicsItem::ItemChildRemovedChange:
11394 str = "ItemChildRemovedChange";
11396 case QGraphicsItem::ItemCursorChange:
11397 str = "ItemCursorChange";
11399 case QGraphicsItem::ItemCursorHasChanged:
11400 str = "ItemCursorHasChanged";
11402 case QGraphicsItem::ItemEnabledChange:
11403 str = "ItemEnabledChange";
11405 case QGraphicsItem::ItemEnabledHasChanged:
11406 str = "ItemEnabledHasChanged";
11408 case QGraphicsItem::ItemFlagsChange:
11409 str = "ItemFlagsChange";
11411 case QGraphicsItem::ItemFlagsHaveChanged:
11412 str = "ItemFlagsHaveChanged";
11414 case QGraphicsItem::ItemMatrixChange:
11415 str = "ItemMatrixChange";
11417 case QGraphicsItem::ItemParentChange:
11418 str = "ItemParentChange";
11420 case QGraphicsItem::ItemParentHasChanged:
11421 str = "ItemParentHasChanged";
11423 case QGraphicsItem::ItemPositionChange:
11424 str = "ItemPositionChange";
11426 case QGraphicsItem::ItemPositionHasChanged:
11427 str = "ItemPositionHasChanged";
11429 case QGraphicsItem::ItemSceneChange:
11430 str = "ItemSceneChange";
11432 case QGraphicsItem::ItemSceneHasChanged:
11433 str = "ItemSceneHasChanged";
11435 case QGraphicsItem::ItemSelectedChange:
11436 str = "ItemSelectedChange";
11438 case QGraphicsItem::ItemSelectedHasChanged:
11439 str = "ItemSelectedHasChanged";
11441 case QGraphicsItem::ItemToolTipChange:
11442 str = "ItemToolTipChange";
11444 case QGraphicsItem::ItemToolTipHasChanged:
11445 str = "ItemToolTipHasChanged";
11447 case QGraphicsItem::ItemTransformChange:
11448 str = "ItemTransformChange";
11450 case QGraphicsItem::ItemTransformHasChanged:
11451 str = "ItemTransformHasChanged";
11453 case QGraphicsItem::ItemVisibleChange:
11454 str = "ItemVisibleChange";
11456 case QGraphicsItem::ItemVisibleHasChanged:
11457 str = "ItemVisibleHasChanged";
11459 case QGraphicsItem::ItemZValueChange:
11460 str = "ItemZValueChange";
11462 case QGraphicsItem::ItemZValueHasChanged:
11463 str = "ItemZValueHasChanged";
11465 case QGraphicsItem::ItemOpacityChange:
11466 str = "ItemOpacityChange";
11468 case QGraphicsItem::ItemOpacityHasChanged:
11469 str = "ItemOpacityHasChanged";
11471 case QGraphicsItem::ItemScenePositionHasChanged:
11472 str = "ItemScenePositionHasChanged";
11474 case QGraphicsItem::ItemRotationChange:
11475 str = "ItemRotationChange";
11477 case QGraphicsItem::ItemRotationHasChanged:
11478 str = "ItemRotationHasChanged";
11480 case QGraphicsItem::ItemScaleChange:
11481 str = "ItemScaleChange";
11483 case QGraphicsItem::ItemScaleHasChanged:
11484 str = "ItemScaleHasChanged";
11486 case QGraphicsItem::ItemTransformOriginPointChange:
11487 str = "ItemTransformOriginPointChange";
11489 case QGraphicsItem::ItemTransformOriginPointHasChanged:
11490 str = "ItemTransformOriginPointHasChanged";
11497 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
11499 const char *str = "UnknownFlag";
11501 case QGraphicsItem::ItemIsMovable:
11502 str = "ItemIsMovable";
11504 case QGraphicsItem::ItemIsSelectable:
11505 str = "ItemIsSelectable";
11507 case QGraphicsItem::ItemIsFocusable:
11508 str = "ItemIsFocusable";
11510 case QGraphicsItem::ItemClipsToShape:
11511 str = "ItemClipsToShape";
11513 case QGraphicsItem::ItemClipsChildrenToShape:
11514 str = "ItemClipsChildrenToShape";
11516 case QGraphicsItem::ItemIgnoresTransformations:
11517 str = "ItemIgnoresTransformations";
11519 case QGraphicsItem::ItemIgnoresParentOpacity:
11520 str = "ItemIgnoresParentOpacity";
11522 case QGraphicsItem::ItemDoesntPropagateOpacityToChildren:
11523 str = "ItemDoesntPropagateOpacityToChildren";
11525 case QGraphicsItem::ItemStacksBehindParent:
11526 str = "ItemStacksBehindParent";
11528 case QGraphicsItem::ItemUsesExtendedStyleOption:
11529 str = "ItemUsesExtendedStyleOption";
11531 case QGraphicsItem::ItemHasNoContents:
11532 str = "ItemHasNoContents";
11534 case QGraphicsItem::ItemSendsGeometryChanges:
11535 str = "ItemSendsGeometryChanges";
11537 case QGraphicsItem::ItemAcceptsInputMethod:
11538 str = "ItemAcceptsInputMethod";
11540 case QGraphicsItem::ItemNegativeZStacksBehindParent:
11541 str = "ItemNegativeZStacksBehindParent";
11543 case QGraphicsItem::ItemIsPanel:
11544 str = "ItemIsPanel";
11546 case QGraphicsItem::ItemIsFocusScope:
11547 str = "ItemIsFocusScope";
11549 case QGraphicsItem::ItemSendsScenePositionChanges:
11550 str = "ItemSendsScenePositionChanges";
11552 case QGraphicsItem::ItemStopsClickFocusPropagation:
11553 str = "ItemStopsClickFocusPropagation";
11555 case QGraphicsItem::ItemStopsFocusHandling:
11556 str = "ItemStopsFocusHandling";
11563 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags)
11567 for (int i = 0; i < 17; ++i) {
11568 if (flags & (1 << i)) {
11572 debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i)));
11583 #include "moc_qgraphicsitem.cpp"
11585 #endif // QT_NO_GRAPHICSVIEW