1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
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 \image 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>
759 #include <private/qgesturemanager_p.h>
765 static inline void _q_adjustRect(QRect *rect)
769 rect->adjust(0, 0, 1, 0);
771 rect->adjust(0, 0, 0, 1);
775 ### Move this into QGraphicsItemPrivate
777 class QGraphicsItemCustomDataStore
780 QHash<const QGraphicsItem *, QMap<int, QVariant> > data;
782 Q_GLOBAL_STATIC(QGraphicsItemCustomDataStore, qt_dataStore)
787 Returns a QPainterPath of \a path when stroked with the \a pen.
788 Ignoring dash pattern.
790 static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)
792 // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
793 // if we pass a value of 0.0 to QPainterPathStroker::setWidth()
794 const qreal penWidthZero = qreal(0.00000001);
796 if (path == QPainterPath())
798 QPainterPathStroker ps;
799 ps.setCapStyle(pen.capStyle());
800 if (pen.widthF() <= 0.0)
801 ps.setWidth(penWidthZero);
803 ps.setWidth(pen.widthF());
804 ps.setJoinStyle(pen.joinStyle());
805 ps.setMiterLimit(pen.miterLimit());
806 QPainterPath p = ps.createStroke(path);
814 Propagates the ancestor flag \a flag with value \a enabled to all this
815 item's children. If \a root is false, the flag is also set on this item
818 void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
819 AncestorFlag flag, bool enabled, bool root)
823 // For root items only. This is the item that has either enabled or
824 // disabled \a childFlag, or has been reparented.
825 switch (int(childFlag)) {
827 flag = AncestorFiltersChildEvents;
828 enabled = q->filtersChildEvents();
831 flag = AncestorHandlesChildEvents;
832 enabled = q->handlesChildEvents();
834 case QGraphicsItem::ItemClipsChildrenToShape:
835 flag = AncestorClipsChildren;
836 enabled = flags & QGraphicsItem::ItemClipsChildrenToShape;
838 case QGraphicsItem::ItemIgnoresTransformations:
839 flag = AncestorIgnoresTransformations;
840 enabled = flags & QGraphicsItem::ItemIgnoresTransformations;
847 // Inherit the enabled-state from our parents.
848 if ((parent->d_ptr->ancestorFlags & flag)
849 || (int(parent->d_ptr->flags & childFlag) == childFlag)
850 || (childFlag == -1 && parent->d_ptr->handlesChildEvents)
851 || (childFlag == -2 && parent->d_ptr->filtersDescendantEvents)) {
853 ancestorFlags |= flag;
855 ancestorFlags &= ~flag;
858 // Top-level root items don't have any ancestors, so there are no
859 // ancestor flags either.
863 // Don't set or propagate the ancestor flag if it's already correct.
864 if (((ancestorFlags & flag) && enabled) || (!(ancestorFlags & flag) && !enabled))
869 ancestorFlags |= flag;
871 ancestorFlags &= ~flag;
873 // Don't process children if the item has the main flag set on itself.
874 if ((childFlag != -1 && int(flags & childFlag) == childFlag)
875 || (int(childFlag) == -1 && handlesChildEvents)
876 || (int(childFlag) == -2 && filtersDescendantEvents))
880 for (int i = 0; i < children.size(); ++i)
881 children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
884 void QGraphicsItemPrivate::updateAncestorFlags()
888 // Inherit the parent's ancestor flags.
889 QGraphicsItemPrivate *pd = parent->d_ptr.data();
890 flags = pd->ancestorFlags;
892 // Add in flags from the parent.
893 if (pd->filtersDescendantEvents)
894 flags |= AncestorFiltersChildEvents;
895 if (pd->handlesChildEvents)
896 flags |= AncestorHandlesChildEvents;
897 if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape)
898 flags |= AncestorClipsChildren;
899 if (pd->flags & QGraphicsItem::ItemIgnoresTransformations)
900 flags |= AncestorIgnoresTransformations;
903 if (ancestorFlags == flags)
904 return; // No change; stop propagation.
905 ancestorFlags = flags;
907 // Propagate to children recursively.
908 for (int i = 0; i < children.size(); ++i)
909 children.at(i)->d_ptr->updateAncestorFlags();
915 Propagates item group membership.
917 void QGraphicsItemPrivate::setIsMemberOfGroup(bool enabled)
920 isMemberOfGroup = enabled;
921 if (!qgraphicsitem_cast<QGraphicsItemGroup *>(q)) {
922 foreach (QGraphicsItem *child, children)
923 child->d_func()->setIsMemberOfGroup(enabled);
930 Maps any item pos properties of \a event to \a item's coordinate system.
932 void QGraphicsItemPrivate::remapItemPos(QEvent *event, QGraphicsItem *item)
935 switch (event->type()) {
936 case QEvent::GraphicsSceneMouseMove:
937 case QEvent::GraphicsSceneMousePress:
938 case QEvent::GraphicsSceneMouseRelease:
939 case QEvent::GraphicsSceneMouseDoubleClick: {
940 QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
941 mouseEvent->setPos(item->mapFromItem(q, mouseEvent->pos()));
942 mouseEvent->setLastPos(item->mapFromItem(q, mouseEvent->pos()));
943 for (int i = 0x1; i <= 0x10; i <<= 1) {
944 if (mouseEvent->buttons() & i) {
945 Qt::MouseButton button = Qt::MouseButton(i);
946 mouseEvent->setButtonDownPos(button, item->mapFromItem(q, mouseEvent->buttonDownPos(button)));
951 case QEvent::GraphicsSceneWheel: {
952 QGraphicsSceneWheelEvent *wheelEvent = static_cast<QGraphicsSceneWheelEvent *>(event);
953 wheelEvent->setPos(item->mapFromItem(q, wheelEvent->pos()));
956 case QEvent::GraphicsSceneContextMenu: {
957 QGraphicsSceneContextMenuEvent *contextEvent = static_cast<QGraphicsSceneContextMenuEvent *>(event);
958 contextEvent->setPos(item->mapFromItem(q, contextEvent->pos()));
961 case QEvent::GraphicsSceneHoverMove: {
962 QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
963 hoverEvent->setPos(item->mapFromItem(q, hoverEvent->pos()));
974 Maps the point \a pos from scene to item coordinates. If \a view is passed and the item
975 is untransformable, this function will correctly map \a pos from the scene using the
976 view's transformation.
978 QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos,
979 const QWidget *viewport) const
981 Q_Q(const QGraphicsItem);
982 if (!itemIsUntransformable())
983 return q->mapFromScene(pos);
984 QGraphicsView *view = 0;
986 view = qobject_cast<QGraphicsView *>(viewport->parentWidget());
988 return q->mapFromScene(pos);
989 // ### More ping pong than needed.
990 return q->deviceTransform(view->viewportTransform()).inverted().map(view->mapFromScene(pos));
996 Combines this item's position and transform onto \a transform.
998 If you need to change this function (e.g., adding more transformation
999 modes / options), make sure to change all places marked with COMBINE.
1001 void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransform *viewTransform) const
1004 if (viewTransform && itemIsUntransformable()) {
1005 *x = q_ptr->deviceTransform(*viewTransform);
1008 *x *= transformData->computedFullTransform();
1010 *x *= QTransform::fromTranslate(pos.x(), pos.y());
1017 Combines this item's position and transform onto \a transform.
1019 If you need to change this function (e.g., adding more transformation
1020 modes / options), make sure to change QGraphicsItem::deviceTransform() as
1023 void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTransform *viewTransform) const
1026 if (viewTransform && itemIsUntransformable()) {
1027 *x = q_ptr->deviceTransform(*viewTransform);
1029 x->translate(pos.x(), pos.y());
1031 *x = transformData->computedFullTransform(x);
1035 void QGraphicsItemPrivate::updateSceneTransformFromParent()
1038 Q_ASSERT(!parent->d_ptr->dirtySceneTransform);
1039 if (parent->d_ptr->sceneTransformTranslateOnly) {
1040 sceneTransform = QTransform::fromTranslate(parent->d_ptr->sceneTransform.dx() + pos.x(),
1041 parent->d_ptr->sceneTransform.dy() + pos.y());
1043 sceneTransform = parent->d_ptr->sceneTransform;
1044 sceneTransform.translate(pos.x(), pos.y());
1046 if (transformData) {
1047 sceneTransform = transformData->computedFullTransform(&sceneTransform);
1048 sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1050 sceneTransformTranslateOnly = parent->d_ptr->sceneTransformTranslateOnly;
1052 } else if (!transformData) {
1053 sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
1054 sceneTransformTranslateOnly = 1;
1055 } else if (transformData->onlyTransform) {
1056 sceneTransform = transformData->transform;
1058 sceneTransform *= QTransform::fromTranslate(pos.x(), pos.y());
1059 sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1060 } else if (pos.isNull()) {
1061 sceneTransform = transformData->computedFullTransform();
1062 sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1064 sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
1065 sceneTransform = transformData->computedFullTransform(&sceneTransform);
1066 sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
1068 dirtySceneTransform = 0;
1074 Make sure not to trigger any pure virtual function calls (e.g.,
1075 prepareGeometryChange) if the item is in its destructor, i.e.
1078 void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant,
1079 const QVariant *thisPointerVariant)
1082 if (newParent == parent)
1086 static_cast<QGraphicsWidgetPrivate *>(this)->fixFocusChainBeforeReparenting((newParent &&
1087 newParent->isWidget()) ? static_cast<QGraphicsWidget *>(newParent) : 0,
1090 // Deliver the change to the index
1091 if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
1092 scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent);
1094 // Disable scene pos notifications for old ancestors
1095 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
1096 scene->d_func()->setScenePosItemEnabled(q, false);
1099 if (subFocusItem && parent) {
1100 // Make sure none of the old parents point to this guy.
1101 subFocusItem->d_ptr->clearSubFocus(parent);
1104 // We anticipate geometry changes. If the item is deleted, it will be
1105 // removed from the index at a later stage, and the whole scene will be
1108 q_ptr->prepareGeometryChange();
1111 // Remove from current parent
1112 parent->d_ptr->removeChild(q);
1113 if (thisPointerVariant)
1114 parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant);
1117 // Update toplevelitem list. If this item is being deleted, its parent
1118 // will be 0 but we don't want to register/unregister it in the TLI list.
1119 if (scene && !inDestructor) {
1120 if (parent && !newParent) {
1121 scene->d_func()->registerTopLevelItem(q);
1122 } else if (!parent && newParent) {
1123 scene->d_func()->unregisterTopLevelItem(q);
1127 // Ensure any last parent focus scope does not point to this item or any of
1129 QGraphicsItem *p = parent;
1130 QGraphicsItem *parentFocusScopeItem = 0;
1132 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
1133 // If this item's focus scope's focus scope item points
1134 // to this item or a descendent, then clear it.
1135 QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
1136 if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
1137 parentFocusScopeItem = fsi;
1138 p->d_ptr->focusScopeItem = 0;
1139 fsi->d_ptr->focusScopeItemChange(false);
1143 p = p->d_ptr->parent;
1146 // Update graphics effect optimization flag
1147 if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect))
1148 newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
1150 // Update focus scope item ptr in new scope.
1151 QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
1152 if (newFocusScopeItem && newParent) {
1153 QGraphicsItem *p = newParent;
1155 if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) {
1156 if (subFocusItem && subFocusItem != q_ptr) {
1157 // Find the subFocusItem's topmost focus scope within the new parent's focusscope
1158 QGraphicsItem *ancestorScope = 0;
1159 QGraphicsItem *p2 = subFocusItem->d_ptr->parent;
1160 while (p2 && p2 != p) {
1161 if (p2->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
1163 if (p2->d_ptr->flags & QGraphicsItem::ItemIsPanel)
1167 p2 = p2->d_ptr->parent;
1170 newFocusScopeItem = ancestorScope;
1173 p->d_ptr->focusScopeItem = newFocusScopeItem;
1174 newFocusScopeItem->d_ptr->focusScopeItemChange(true);
1175 // Ensure the new item is no longer the subFocusItem. The
1176 // only way to set focus on a child of a focus scope is
1177 // by setting focus on the scope itself.
1178 if (subFocusItem && !p->focusItem())
1179 subFocusItem->d_ptr->clearSubFocus();
1182 p = p->d_ptr->parent;
1187 invalidateDepthRecursively();
1189 if ((parent = newParent)) {
1190 if (parent->d_func()->scene && parent->d_func()->scene != scene) {
1191 // Move this item to its new parent's scene
1192 parent->d_func()->scene->addItem(q);
1193 } else if (!parent->d_func()->scene && scene) {
1194 // Remove this item from its former scene
1195 scene->removeItem(q);
1198 parent->d_ptr->addChild(q);
1199 if (thisPointerVariant)
1200 parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant);
1202 // Re-enable scene pos notifications for new ancestors
1203 if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges))
1204 scene->d_func()->setScenePosItemEnabled(q, true);
1207 // Propagate dirty flags to the new parent
1208 markParentDirty(/*updateBoundingRect=*/true);
1210 // Inherit ancestor flags from the new parent.
1211 updateAncestorFlags();
1213 // Update item visible / enabled.
1214 if (parent->d_ptr->visible != visible) {
1215 if (!parent->d_ptr->visible || !explicitlyHidden)
1216 setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false);
1218 if (parent->isEnabled() != enabled) {
1219 if (!parent->d_ptr->enabled || !explicitlyDisabled)
1220 setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false);
1223 // Auto-activate if visible and the parent is active.
1224 if (visible && parent->isActive())
1227 // Inherit ancestor flags from the new parent.
1228 updateAncestorFlags();
1230 if (!inDestructor) {
1231 // Update item visible / enabled.
1232 if (!visible && !explicitlyHidden)
1233 setVisibleHelper(true, /* explicit = */ false);
1234 if (!enabled && !explicitlyDisabled)
1235 setEnabledHelper(true, /* explicit = */ false);
1239 dirtySceneTransform = 1;
1240 if (!inDestructor && (transformData || (newParent && newParent->d_ptr->transformData)))
1243 // Restore the sub focus chain.
1245 subFocusItem->d_ptr->setSubFocus(newParent);
1246 if (parent && parent->isActive())
1247 subFocusItem->setFocus();
1250 // Deliver post-change notification
1251 if (newParentVariant)
1252 q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant);
1255 emit static_cast<QGraphicsObject *>(q)->parentChanged();
1261 Returns the bounding rect of this item's children (excluding itself).
1263 void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect, QGraphicsItem *topMostEffectItem)
1267 QRectF childrenRect;
1268 QRectF *result = rect;
1269 rect = &childrenRect;
1270 const bool setTopMostEffectItem = !topMostEffectItem;
1272 for (int i = 0; i < children.size(); ++i) {
1273 QGraphicsItem *child = children.at(i);
1274 QGraphicsItemPrivate *childd = child->d_ptr.data();
1275 if (setTopMostEffectItem)
1276 topMostEffectItem = child;
1277 bool hasPos = !childd->pos.isNull();
1278 if (hasPos || childd->transformData) {
1280 QTransform matrix = childd->transformToParent();
1283 *rect |= matrix.mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
1284 if (!childd->children.isEmpty())
1285 childd->childrenBoundingRectHelper(&matrix, rect, topMostEffectItem);
1288 *rect |= x->mapRect(child->d_ptr->effectiveBoundingRect(topMostEffectItem));
1290 *rect |= child->d_ptr->effectiveBoundingRect(topMostEffectItem);
1291 if (!childd->children.isEmpty())
1292 childd->childrenBoundingRectHelper(x, rect, topMostEffectItem);
1296 if (flags & QGraphicsItem::ItemClipsChildrenToShape){
1298 *rect &= x->mapRect(q->boundingRect());
1300 *rect &= q->boundingRect();
1306 void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
1307 const QRegion &exposedRegion, bool allItems) const
1310 Q_Q(const QGraphicsItem);
1312 // Initialize standard QStyleOption values.
1313 const QRectF brect = q->boundingRect();
1314 option->state = QStyle::State_None;
1315 option->rect = brect.toRect();
1316 option->levelOfDetail = 1;
1317 option->exposedRect = brect;
1319 option->state |= QStyle::State_Selected;
1321 option->state |= QStyle::State_Enabled;
1323 option->state |= QStyle::State_HasFocus;
1325 if (scene->d_func()->hoverItems.contains(q_ptr))
1326 option->state |= QStyle::State_MouseOver;
1327 if (q == scene->mouseGrabberItem())
1328 option->state |= QStyle::State_Sunken;
1331 if (!(flags & QGraphicsItem::ItemUsesExtendedStyleOption))
1334 // Initialize QStyleOptionGraphicsItem specific values (matrix, exposedRect).
1335 option->matrix = worldTransform.toAffine(); //### discards perspective
1338 // Determine the item's exposed area
1339 option->exposedRect = QRectF();
1340 const QTransform reverseMap = worldTransform.inverted();
1341 const QVector<QRect> exposedRects(exposedRegion.rects());
1342 for (int i = 0; i < exposedRects.size(); ++i) {
1343 option->exposedRect |= reverseMap.mapRect(QRectF(exposedRects.at(i)));
1344 if (option->exposedRect.contains(brect))
1347 option->exposedRect &= brect;
1354 Empty all cached pixmaps from the pixmap cache.
1356 void QGraphicsItemCache::purge()
1358 QPixmapCache::remove(key);
1359 key = QPixmapCache::Key();
1360 QMutableHashIterator<QPaintDevice *, DeviceData> it(deviceData);
1361 while (it.hasNext()) {
1362 DeviceData &data = it.next().value();
1363 QPixmapCache::remove(data.key);
1364 data.cacheIndent = QPoint();
1372 Constructs a QGraphicsItem with the given \a parent item.
1373 It does not modify the parent object returned by QObject::parent().
1375 If \a parent is 0, you can add the item to a scene by calling
1376 QGraphicsScene::addItem(). The item will then become a top-level item.
1378 \sa QGraphicsScene::addItem(), setParentItem()
1380 QGraphicsItem::QGraphicsItem(QGraphicsItem *parent)
1381 : d_ptr(new QGraphicsItemPrivate)
1383 d_ptr->q_ptr = this;
1384 setParentItem(parent);
1390 QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent)
1393 d_ptr->q_ptr = this;
1394 setParentItem(parent);
1398 Destroys the QGraphicsItem and all its children. If this item is currently
1399 associated with a scene, the item will be removed from the scene before it
1402 \note It is more efficient to remove the item from the QGraphicsScene before
1403 destroying the item.
1405 QGraphicsItem::~QGraphicsItem()
1407 if (d_ptr->isObject) {
1408 QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
1409 QObjectPrivate *p = QObjectPrivate::get(o);
1410 p->wasDeleted = true;
1411 if (p->declarativeData) {
1412 QAbstractDeclarativeData::destroyed(p->declarativeData, o);
1413 p->declarativeData = 0;
1417 d_ptr->inDestructor = 1;
1418 d_ptr->removeExtraItemCache();
1420 #ifndef QT_NO_GESTURES
1421 if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) {
1422 QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
1423 if (QGestureManager *manager = QGestureManager::instance()) {
1424 foreach (Qt::GestureType type, d_ptr->gestureContext.keys())
1425 manager->cleanupCachedGestures(o, type);
1432 // Update focus scope item ptr.
1433 QGraphicsItem *p = d_ptr->parent;
1435 if (p->flags() & ItemIsFocusScope) {
1436 if (p->d_ptr->focusScopeItem == this)
1437 p->d_ptr->focusScopeItem = 0;
1440 p = p->d_ptr->parent;
1443 if (!d_ptr->children.isEmpty()) {
1444 while (!d_ptr->children.isEmpty())
1445 delete d_ptr->children.first();
1446 Q_ASSERT(d_ptr->children.isEmpty());
1450 d_ptr->scene->d_func()->removeItemHelper(this);
1452 d_ptr->resetFocusProxy();
1456 #ifndef QT_NO_GRAPHICSEFFECT
1457 delete d_ptr->graphicsEffect;
1458 #endif //QT_NO_GRAPHICSEFFECT
1459 if (d_ptr->transformData) {
1460 for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) {
1461 QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i);
1462 static_cast<QGraphicsTransformPrivate *>(t->d_ptr.data())->item = 0;
1466 delete d_ptr->transformData;
1468 if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore())
1469 dataStore->data.remove(this);
1473 Returns the current scene for the item, or 0 if the item is not stored in
1476 To add or move an item to a scene, call QGraphicsScene::addItem().
1478 QGraphicsScene *QGraphicsItem::scene() const
1480 return d_ptr->scene;
1484 Returns a pointer to this item's item group, or 0 if this item is not
1487 \sa QGraphicsItemGroup, QGraphicsScene::createItemGroup()
1489 QGraphicsItemGroup *QGraphicsItem::group() const
1491 if (!d_ptr->isMemberOfGroup)
1493 QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
1494 while ((parent = parent->d_ptr->parent)) {
1495 if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(parent))
1498 // Unreachable; if d_ptr->isMemberOfGroup is != 0, then one parent of this
1499 // item is a group item.
1504 Adds this item to the item group \a group. If \a group is 0, this item is
1505 removed from any current group and added as a child of the previous
1508 \sa group(), QGraphicsScene::createItemGroup()
1510 void QGraphicsItem::setGroup(QGraphicsItemGroup *group)
1513 if (QGraphicsItemGroup *group = this->group())
1514 group->removeFromGroup(this);
1516 group->addToGroup(this);
1521 Returns a pointer to this item's parent item. If this item does not have a
1522 parent, 0 is returned.
1524 \sa setParentItem(), childItems()
1526 QGraphicsItem *QGraphicsItem::parentItem() const
1528 return d_ptr->parent;
1532 Returns this item's top-level item. The top-level item is the item's
1533 topmost ancestor item whose parent is 0. If an item has no parent, its own
1534 pointer is returned (i.e., a top-level item is its own top-level item).
1538 QGraphicsItem *QGraphicsItem::topLevelItem() const
1540 QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
1541 while (QGraphicsItem *grandPa = parent->parentItem())
1549 Returns a pointer to the item's parent, cast to a QGraphicsObject. returns 0 if the parent item
1550 is not a QGraphicsObject.
1552 \sa parentItem(), childItems()
1554 QGraphicsObject *QGraphicsItem::parentObject() const
1556 QGraphicsItem *p = d_ptr->parent;
1557 return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : 0;
1563 Returns a pointer to the item's parent widget. The item's parent widget is
1564 the closest parent item that is a widget.
1566 \sa parentItem(), childItems()
1568 QGraphicsWidget *QGraphicsItem::parentWidget() const
1570 QGraphicsItem *p = parentItem();
1571 while (p && !p->isWidget())
1572 p = p->parentItem();
1573 return (p && p->isWidget()) ? static_cast<QGraphicsWidget *>(p) : 0;
1579 Returns a pointer to the item's top level widget (i.e., the item's
1580 ancestor whose parent is 0, or whose parent is not a widget), or 0 if this
1581 item does not have a top level widget. If the item is its own top level
1582 widget, this function returns a pointer to the item itself.
1584 QGraphicsWidget *QGraphicsItem::topLevelWidget() const
1586 if (const QGraphicsWidget *p = parentWidget())
1587 return p->topLevelWidget();
1588 return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : 0;
1594 Returns the item's window, or 0 if this item does not have a window. If
1595 the item is a window, it will return itself. Otherwise it will return the
1596 closest ancestor that is a window.
1598 \sa QGraphicsWidget::isWindow()
1600 QGraphicsWidget *QGraphicsItem::window() const
1602 QGraphicsItem *p = panel();
1603 if (p && p->isWindow())
1604 return static_cast<QGraphicsWidget *>(p);
1611 Returns the item's panel, or 0 if this item does not have a panel. If the
1612 item is a panel, it will return itself. Otherwise it will return the
1613 closest ancestor that is a panel.
1615 \sa isPanel(), ItemIsPanel
1617 QGraphicsItem *QGraphicsItem::panel() const
1619 if (d_ptr->flags & ItemIsPanel)
1620 return const_cast<QGraphicsItem *>(this);
1621 return d_ptr->parent ? d_ptr->parent->panel() : 0;
1627 Return the graphics item cast to a QGraphicsObject, if the class is actually a
1628 graphics object, 0 otherwise.
1630 QGraphicsObject *QGraphicsItem::toGraphicsObject()
1632 return d_ptr->isObject ? static_cast<QGraphicsObject *>(this) : 0;
1638 Return the graphics item cast to a QGraphicsObject, if the class is actually a
1639 graphics object, 0 otherwise.
1641 const QGraphicsObject *QGraphicsItem::toGraphicsObject() const
1643 return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0;
1647 Sets this item's parent item to \a newParent. If this item already
1648 has a parent, it is first removed from the previous parent. If \a
1649 newParent is 0, this item will become a top-level item.
1651 Note that this implicitly adds this graphics item to the scene of
1652 the parent. You should not \l{QGraphicsScene::addItem()}{add} the
1653 item to the scene yourself.
1655 Calling this function on an item that is an ancestor of \a newParent
1656 have undefined behaviour.
1658 \sa parentItem(), childItems()
1660 void QGraphicsItem::setParentItem(QGraphicsItem *newParent)
1662 if (newParent == this) {
1663 qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
1666 if (newParent == d_ptr->parent)
1669 const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange,
1670 QVariant::fromValue<QGraphicsItem *>(newParent)));
1671 newParent = qvariant_cast<QGraphicsItem *>(newParentVariant);
1672 if (newParent == d_ptr->parent)
1675 const QVariant thisPointerVariant(QVariant::fromValue<QGraphicsItem *>(this));
1676 d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant);
1680 \fn QList<QGraphicsItem *> QGraphicsItem::children() const
1683 Use childItems() instead.
1691 Returns a list of this item's children.
1693 The items are sorted by stacking order. This takes into account both the
1694 items' insertion order and their Z-values.
1696 \sa setParentItem(), zValue(), {QGraphicsItem#Sorting}{Sorting}
1698 QList<QGraphicsItem *> QGraphicsItem::childItems() const
1700 const_cast<QGraphicsItem *>(this)->d_ptr->ensureSortedChildren();
1701 return d_ptr->children;
1706 Returns true if this item is a widget (i.e., QGraphicsWidget); otherwise,
1709 bool QGraphicsItem::isWidget() const
1711 return d_ptr->isWidget;
1716 Returns true if the item is a QGraphicsWidget window, otherwise returns
1719 \sa QGraphicsWidget::windowFlags()
1721 bool QGraphicsItem::isWindow() const
1723 return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
1728 Returns true if the item is a panel; otherwise returns false.
1730 \sa QGraphicsItem::panel(), ItemIsPanel
1732 bool QGraphicsItem::isPanel() const
1734 return d_ptr->flags & ItemIsPanel;
1738 Returns this item's flags. The flags describe what configurable features
1739 of the item are enabled and not. For example, if the flags include
1740 ItemIsFocusable, the item can accept input focus.
1742 By default, no flags are enabled.
1744 \sa setFlags(), setFlag()
1746 QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const
1748 return GraphicsItemFlags(d_ptr->flags);
1752 If \a enabled is true, the item flag \a flag is enabled; otherwise, it is
1755 \sa flags(), setFlags()
1757 void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled)
1760 setFlags(GraphicsItemFlags(d_ptr->flags) | flag);
1762 setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag);
1768 Sets the flag \a flag on \a item and all its children, to \a enabled.
1770 static void _q_qgraphicsItemSetFlag(QGraphicsItem *item, QGraphicsItem::GraphicsItemFlag flag,
1773 if (item->flags() & flag) {
1774 // If this item already has the correct flag set, we don't have to
1778 item->setFlag(flag, enabled);
1779 foreach (QGraphicsItem *child, item->childItems())
1780 _q_qgraphicsItemSetFlag(child, flag, enabled);
1784 Sets the item flags to \a flags. All flags in \a flags are enabled; all
1785 flags not in \a flags are disabled.
1787 If the item had focus and \a flags does not enable ItemIsFocusable, the
1788 item loses focus as a result of calling this function. Similarly, if the
1789 item was selected, and \a flags does not enabled ItemIsSelectable, the
1790 item is automatically unselected.
1792 By default, no flags are enabled. (QGraphicsWidget enables the
1793 ItemSendsGeometryChanges flag by default in order to track position
1796 \sa flags(), setFlag()
1798 void QGraphicsItem::setFlags(GraphicsItemFlags flags)
1800 // Notify change and check for adjustment.
1801 if (quint32(d_ptr->flags) == quint32(flags))
1803 flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
1804 if (quint32(d_ptr->flags) == quint32(flags))
1806 if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex)
1807 d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags);
1809 // Flags that alter the geometry of the item (or its children).
1810 const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable);
1811 bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
1813 d_ptr->updatePaintedViewBoundingRects(/*children=*/true);
1815 // Keep the old flags to compare the diff.
1816 GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags);
1819 d_ptr->flags = flags;
1821 if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
1822 // Clear focus on the item if it has focus when the focusable flag
1827 if (!(d_ptr->flags & ItemIsSelectable) && isSelected()) {
1828 // Unselect the item if it is selected when the selectable flag is
1833 if ((flags & ItemClipsChildrenToShape) != (oldFlags & ItemClipsChildrenToShape)) {
1834 // Item children clipping changes. Propagate the ancestor flag to
1836 d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
1837 // The childrenBoundingRect is clipped to the boundingRect in case of ItemClipsChildrenToShape,
1838 // which means we have to invalidate the cached childrenBoundingRect whenever this flag changes.
1839 d_ptr->dirtyChildrenBoundingRect = 1;
1840 d_ptr->markParentDirty(true);
1843 if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
1844 // Item children clipping changes. Propagate the ancestor flag to
1846 d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
1849 if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
1850 // NB! We change the flags directly here, so we must also update d_ptr->flags.
1851 // Note that this has do be done before the ItemStacksBehindParent check
1852 // below; otherwise we will loose the change.
1854 // Update stack-behind.
1855 if (d_ptr->z < qreal(0.0))
1856 flags |= ItemStacksBehindParent;
1858 flags &= ~ItemStacksBehindParent;
1859 d_ptr->flags = flags;
1862 if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
1863 // NB! This check has to come after the ItemNegativeZStacksBehindParent
1864 // check above. Be careful.
1866 // Ensure child item sorting is up to date when toggling this flag.
1868 d_ptr->parent->d_ptr->needSortChildren = 1;
1869 else if (d_ptr->scene)
1870 d_ptr->scene->d_func()->needSortTopLevelItems = 1;
1873 if ((flags & ItemAcceptsInputMethod) != (oldFlags & ItemAcceptsInputMethod)) {
1874 // Update input method sensitivity in any views.
1876 d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
1880 if ((d_ptr->panelModality != NonModal)
1882 && (flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
1883 // update the panel's modal state
1884 if (flags & ItemIsPanel)
1885 d_ptr->scene->d_func()->enterModal(this);
1887 d_ptr->scene->d_func()->leaveModal(this);
1891 if ((flags & ItemSendsScenePositionChanges) != (oldFlags & ItemSendsScenePositionChanges)) {
1892 if (flags & ItemSendsScenePositionChanges)
1893 d_ptr->scene->d_func()->registerScenePosItem(this);
1895 d_ptr->scene->d_func()->unregisterScenePosItem(this);
1897 d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
1901 itemChange(ItemFlagsHaveChanged, quint32(flags));
1906 Returns the cache mode for this item. The default mode is NoCache (i.e.,
1907 cache is disabled and all painting is immediate).
1911 QGraphicsItem::CacheMode QGraphicsItem::cacheMode() const
1913 return QGraphicsItem::CacheMode(d_ptr->cacheMode);
1918 Sets the item's cache mode to \a mode.
1920 The optional \a logicalCacheSize argument is used only by
1921 ItemCoordinateCache mode, and describes the resolution of the cache
1922 buffer; if \a logicalCacheSize is (100, 100), QGraphicsItem will fit the
1923 item into 100x100 pixels in graphics memory, regardless of the logical
1924 size of the item itself. By default QGraphicsItem uses the size of
1925 boundingRect(). For all other cache modes than ItemCoordinateCache, \a
1926 logicalCacheSize is ignored.
1928 Caching can speed up rendering if your item spends a significant time
1929 redrawing itself. In some cases the cache can also slow down rendering, in
1930 particular when the item spends less time redrawing than QGraphicsItem
1931 spends redrawing from the cache. When enabled, the item's paint() function
1932 will be called only once for each call to update(); for any subsequent
1933 repaint requests, the Graphics View framework will redraw from the
1934 cache. This approach works particularly well with QGLWidget, which stores
1935 all the cache as OpenGL textures.
1937 Be aware that QPixmapCache's cache limit may need to be changed to obtain
1938 optimal performance.
1940 You can read more about the different cache modes in the CacheMode
1943 \sa CacheMode, QPixmapCache::setCacheLimit()
1945 void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize)
1947 CacheMode lastMode = CacheMode(d_ptr->cacheMode);
1948 d_ptr->cacheMode = mode;
1949 bool noVisualChange = (mode == NoCache && lastMode == NoCache)
1950 || (mode == NoCache && lastMode == DeviceCoordinateCache)
1951 || (mode == DeviceCoordinateCache && lastMode == NoCache)
1952 || (mode == DeviceCoordinateCache && lastMode == DeviceCoordinateCache);
1953 if (mode == NoCache) {
1954 d_ptr->removeExtraItemCache();
1956 QGraphicsItemCache *cache = d_ptr->extraItemCache();
1961 if (mode == ItemCoordinateCache) {
1962 if (lastMode == mode && cache->fixedSize == logicalCacheSize)
1963 noVisualChange = true;
1964 cache->fixedSize = logicalCacheSize;
1967 if (!noVisualChange)
1974 Returns the modality for this item.
1976 QGraphicsItem::PanelModality QGraphicsItem::panelModality() const
1978 return d_ptr->panelModality;
1984 Sets the modality for this item to \a panelModality.
1986 Changing the modality of a visible item takes effect immediately.
1988 void QGraphicsItem::setPanelModality(PanelModality panelModality)
1990 if (d_ptr->panelModality == panelModality)
1993 PanelModality previousModality = d_ptr->panelModality;
1994 bool enterLeaveModal = (isPanel() && d_ptr->scene && isVisible());
1995 if (enterLeaveModal && panelModality == NonModal)
1996 d_ptr->scene->d_func()->leaveModal(this);
1997 d_ptr->panelModality = panelModality;
1998 if (enterLeaveModal && d_ptr->panelModality != NonModal)
1999 d_ptr->scene->d_func()->enterModal(this, previousModality);
2005 Returns true if this item is blocked by a modal panel, false otherwise. If \a blockingPanel is
2006 non-zero, \a blockingPanel will be set to the modal panel that is blocking this item. If this
2007 item is not blocked, \a blockingPanel will not be set by this function.
2009 This function always returns false for items not in a scene.
2011 \sa panelModality(), setPanelModality(), PanelModality
2013 bool QGraphicsItem::isBlockedByModalPanel(QGraphicsItem **blockingPanel) const
2019 QGraphicsItem *dummy = 0;
2021 blockingPanel = &dummy;
2023 QGraphicsScenePrivate *scene_d = d_ptr->scene->d_func();
2024 if (scene_d->modalPanels.isEmpty())
2028 if (!scene_d->popupWidgets.isEmpty() && scene_d->popupWidgets.first() == this)
2031 for (int i = 0; i < scene_d->modalPanels.count(); ++i) {
2032 QGraphicsItem *modalPanel = scene_d->modalPanels.at(i);
2033 if (modalPanel->panelModality() == QGraphicsItem::SceneModal) {
2034 // Scene modal panels block all non-descendents.
2035 if (modalPanel != this && !modalPanel->isAncestorOf(this)) {
2036 *blockingPanel = modalPanel;
2040 // Window modal panels block ancestors and siblings/cousins.
2041 if (modalPanel != this
2042 && !modalPanel->isAncestorOf(this)
2043 && commonAncestorItem(modalPanel)) {
2044 *blockingPanel = modalPanel;
2052 #ifndef QT_NO_TOOLTIP
2054 Returns the item's tool tip, or an empty QString if no tool tip has been
2057 \sa setToolTip(), QToolTip
2059 QString QGraphicsItem::toolTip() const
2061 return d_ptr->extra(QGraphicsItemPrivate::ExtraToolTip).toString();
2065 Sets the item's tool tip to \a toolTip. If \a toolTip is empty, the item's
2066 tool tip is cleared.
2068 \sa toolTip(), QToolTip
2070 void QGraphicsItem::setToolTip(const QString &toolTip)
2072 const QVariant toolTipVariant(itemChange(ItemToolTipChange, toolTip));
2073 d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTipVariant.toString());
2074 itemChange(ItemToolTipHasChanged, toolTipVariant);
2076 #endif // QT_NO_TOOLTIP
2078 #ifndef QT_NO_CURSOR
2080 Returns the current cursor shape for the item. The mouse cursor
2081 will assume this shape when it's over this item.
2082 See the \l{Qt::CursorShape}{list of predefined cursor objects} for a
2083 range of useful shapes.
2085 An editor item might want to use an I-beam cursor:
2087 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 2
2089 If no cursor has been set, the cursor of the item beneath is used.
2091 \sa setCursor(), hasCursor(), unsetCursor(), QWidget::cursor,
2092 QApplication::overrideCursor()
2094 QCursor QGraphicsItem::cursor() const
2096 return qvariant_cast<QCursor>(d_ptr->extra(QGraphicsItemPrivate::ExtraCursor));
2100 Sets the current cursor shape for the item to \a cursor. The mouse cursor
2101 will assume this shape when it's over this item.
2102 See the \l{Qt::CursorShape}{list of predefined cursor objects} for a
2103 range of useful shapes.
2105 An editor item might want to use an I-beam cursor:
2107 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 3
2109 If no cursor has been set, the cursor of the item beneath is used.
2111 \sa cursor(), hasCursor(), unsetCursor(), QWidget::cursor,
2112 QApplication::overrideCursor()
2114 void QGraphicsItem::setCursor(const QCursor &cursor)
2116 const QVariant cursorVariant(itemChange(ItemCursorChange, QVariant::fromValue<QCursor>(cursor)));
2117 d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qvariant_cast<QCursor>(cursorVariant));
2118 d_ptr->hasCursor = 1;
2120 d_ptr->scene->d_func()->allItemsUseDefaultCursor = false;
2121 foreach (QGraphicsView *view, d_ptr->scene->views()) {
2122 view->viewport()->setMouseTracking(true);
2123 // Note: Some of this logic is duplicated in QGraphicsView's mouse events.
2124 if (view->underMouse()) {
2125 foreach (QGraphicsItem *itemUnderCursor, view->items(view->mapFromGlobal(QCursor::pos()))) {
2126 if (itemUnderCursor->hasCursor()) {
2127 QMetaObject::invokeMethod(view, "_q_setViewportCursor",
2128 Q_ARG(QCursor, itemUnderCursor->cursor()));
2136 itemChange(ItemCursorHasChanged, cursorVariant);
2140 Returns true if this item has a cursor set; otherwise, false is returned.
2142 By default, items don't have any cursor set. cursor() will return a
2143 standard pointing arrow cursor.
2147 bool QGraphicsItem::hasCursor() const
2149 return d_ptr->hasCursor;
2153 Clears the cursor from this item.
2155 \sa hasCursor(), setCursor()
2157 void QGraphicsItem::unsetCursor()
2159 d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraCursor);
2160 d_ptr->hasCursor = 0;
2162 foreach (QGraphicsView *view, d_ptr->scene->views()) {
2163 if (view->underMouse() && view->itemAt(view->mapFromGlobal(QCursor::pos())) == this) {
2164 QMetaObject::invokeMethod(view, "_q_unsetViewportCursor");
2171 #endif // QT_NO_CURSOR
2174 Returns true if the item is visible; otherwise, false is returned.
2176 Note that the item's general visibility is unrelated to whether or not it
2177 is actually being visualized by a QGraphicsView.
2181 bool QGraphicsItem::isVisible() const
2183 return d_ptr->visible;
2188 Returns true if the item is visible to \a parent; otherwise, false is
2189 returned. \a parent can be 0, in which case this function will return
2190 whether the item is visible to the scene or not.
2192 An item may not be visible to its ancestors even if isVisible() is true. It
2193 may also be visible to its ancestors even if isVisible() is false. If
2194 any ancestor is hidden, the item itself will be implicitly hidden, in which
2195 case this function will return false.
2197 \sa isVisible(), setVisible()
2199 bool QGraphicsItem::isVisibleTo(const QGraphicsItem *parent) const
2201 const QGraphicsItem *p = this;
2202 if (d_ptr->explicitlyHidden)
2207 if (p->d_ptr->explicitlyHidden)
2209 } while ((p = p->d_ptr->parent));
2216 Sets this item's visibility to \a newVisible. If \a explicitly is true,
2217 this item will be "explicitly" \a newVisible; otherwise, it.. will not be.
2219 void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bool update)
2223 // Update explicit bit.
2225 explicitlyHidden = newVisible ? 0 : 1;
2227 // Check if there's nothing to do.
2228 if (visible == quint32(newVisible))
2231 // Don't show child if parent is not visible
2232 if (parent && newVisible && !parent->d_ptr->visible)
2235 // Modify the property.
2236 const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange,
2237 quint32(newVisible)));
2238 newVisible = newVisibleVariant.toBool();
2239 if (visible == quint32(newVisible))
2241 visible = newVisible;
2243 // Schedule redrawing
2245 QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
2249 #ifndef QT_NO_GRAPHICSEFFECT
2250 invalidateParentGraphicsEffectsRecursively();
2251 #endif //QT_NO_GRAPHICSEFFECT
2252 scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
2256 // Certain properties are dropped as an item becomes invisible.
2257 bool hasFocus = q_ptr->hasFocus();
2260 if (scene->d_func()->mouseGrabberItems.contains(q))
2262 if (scene->d_func()->keyboardGrabberItems.contains(q))
2263 q->ungrabKeyboard();
2264 if (q->isPanel() && panelModality != QGraphicsItem::NonModal)
2265 scene->d_func()->leaveModal(q_ptr);
2267 if (hasFocus && scene) {
2268 // Hiding the closest non-panel ancestor of the focus item
2269 QGraphicsItem *focusItem = scene->focusItem();
2271 if (isWidget && !focusItem->isPanel()) {
2273 if (focusItem == q_ptr) {
2274 clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
2277 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
2280 clearFocusHelper(/* giveFocusToParent = */ false);
2282 if (q_ptr->isSelected())
2283 q_ptr->setSelected(false);
2285 geometryChanged = 1;
2286 paintedViewBoundingRectsNeedRepaint = 1;
2289 QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
2290 if (widget->windowType() == Qt::Popup)
2291 scene->d_func()->addPopup(widget);
2293 if (q->isPanel() && panelModality != QGraphicsItem::NonModal) {
2294 scene->d_func()->enterModal(q_ptr);
2299 // Update children with explicitly = false.
2300 const bool updateChildren = update && !((flags & QGraphicsItem::ItemClipsChildrenToShape)
2301 && !(flags & QGraphicsItem::ItemHasNoContents));
2302 foreach (QGraphicsItem *child, children) {
2303 if (!newVisible || !child->d_ptr->explicitlyHidden)
2304 child->d_ptr->setVisibleHelper(newVisible, false, updateChildren);
2307 // Update activation
2308 if (scene && q->isPanel()) {
2310 if (parent && parent->isActive())
2314 scene->setActivePanel(parent);
2322 QGraphicsItem *p = parent;
2325 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
2326 QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
2327 if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
2329 while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
2330 fsi = fsi->d_ptr->focusScopeItem;
2331 fsi->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
2332 /* focusFromHide = */ false);
2336 p = p->d_ptr->parent;
2339 QGraphicsItem *fi = subFocusItem;
2340 if (fi && fi != scene->focusItem()) {
2341 scene->setFocusItem(fi);
2342 } else if (flags & QGraphicsItem::ItemIsFocusScope &&
2343 !scene->focusItem() &&
2344 q->isAncestorOf(scene->d_func()->lastFocusItem)) {
2351 QGraphicsItem *p = parent;
2353 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
2354 if (p->d_ptr->visible) {
2355 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ true,
2356 /* focusFromHide = */ true);
2360 p = p->d_ptr->parent;
2366 // Deliver post-change notification.
2367 q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, newVisibleVariant);
2370 emit static_cast<QGraphicsObject *>(q_ptr)->visibleChanged();
2374 If \a visible is true, the item is made visible. Otherwise, the item is
2375 made invisible. Invisible items are not painted, nor do they receive any
2376 events. In particular, mouse events pass right through invisible items,
2377 and are delivered to any item that may be behind. Invisible items are also
2378 unselectable, they cannot take input focus, and are not detected by
2379 QGraphicsScene's item location functions.
2381 If an item becomes invisible while grabbing the mouse, (i.e., while it is
2382 receiving mouse events,) it will automatically lose the mouse grab, and
2383 the grab is not regained by making the item visible again; it must receive
2384 a new mouse press to regain the mouse grab.
2386 Similarly, an invisible item cannot have focus, so if the item has focus
2387 when it becomes invisible, it will lose focus, and the focus is not
2388 regained by simply making the item visible again.
2390 If you hide a parent item, all its children will also be hidden. If you
2391 show a parent item, all children will be shown, unless they have been
2392 explicitly hidden (i.e., if you call setVisible(false) on a child, it will
2393 not be reshown even if its parent is hidden, and then shown again).
2395 Items are visible by default; it is unnecessary to call
2396 setVisible() on a new item.
2398 \sa isVisible(), show(), hide()
2400 void QGraphicsItem::setVisible(bool visible)
2402 d_ptr->setVisibleHelper(visible, /* explicit = */ true);
2406 \fn void QGraphicsItem::hide()
2408 Hides the item. (Items are visible by default.)
2410 This convenience function is equivalent to calling \c setVisible(false).
2412 \sa show(), setVisible()
2416 \fn void QGraphicsItem::show()
2418 Shows the item. (Items are visible by default.)
2420 This convenience function is equivalent to calling \c setVisible(true).
2422 \sa hide(), setVisible()
2426 Returns true if the item is enabled; otherwise, false is returned.
2430 bool QGraphicsItem::isEnabled() const
2432 return d_ptr->enabled;
2438 Sets this item's visibility to \a newEnabled. If \a explicitly is true,
2439 this item will be "explicitly" \a newEnabled; otherwise, it.. will not be.
2441 void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bool update)
2443 // Update explicit bit.
2445 explicitlyDisabled = newEnabled ? 0 : 1;
2447 // Check if there's nothing to do.
2448 if (enabled == quint32(newEnabled))
2451 // Certain properties are dropped when an item is disabled.
2453 if (scene && scene->mouseGrabberItem() == q_ptr)
2454 q_ptr->ungrabMouse();
2455 if (q_ptr->hasFocus()) {
2456 // Disabling the closest non-panel ancestor of the focus item
2457 // causes focus to pop to the next item, otherwise it's cleared.
2458 QGraphicsItem *focusItem = scene->focusItem();
2460 if (isWidget && !focusItem->isPanel() && q_ptr->isAncestorOf(focusItem)) {
2462 if (focusItem == q_ptr) {
2463 clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
2466 } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
2469 q_ptr->clearFocus();
2471 if (q_ptr->isSelected())
2472 q_ptr->setSelected(false);
2475 // Modify the property.
2476 const QVariant newEnabledVariant(q_ptr->itemChange(QGraphicsItem::ItemEnabledChange,
2477 quint32(newEnabled)));
2478 enabled = newEnabledVariant.toBool();
2484 foreach (QGraphicsItem *child, children) {
2485 if (!newEnabled || !child->d_ptr->explicitlyDisabled)
2486 child->d_ptr->setEnabledHelper(newEnabled, /* explicitly = */ false);
2489 // Deliver post-change notification.
2490 q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, newEnabledVariant);
2493 emit static_cast<QGraphicsObject *>(q_ptr)->enabledChanged();
2497 If \a enabled is true, the item is enabled; otherwise, it is disabled.
2499 Disabled items are visible, but they do not receive any events, and cannot
2500 take focus nor be selected. Mouse events are discarded; they are not
2501 propagated unless the item is also invisible, or if it does not accept
2502 mouse events (see acceptedMouseButtons()). A disabled item cannot become the
2503 mouse grabber, and as a result of this, an item loses the grab if it
2504 becomes disabled when grabbing the mouse, just like it loses focus if it
2505 had focus when it was disabled.
2507 Disabled items are traditionally drawn using grayed-out colors (see \l
2508 QPalette::Disabled).
2510 If you disable a parent item, all its children will also be disabled. If
2511 you enable a parent item, all children will be enabled, unless they have
2512 been explicitly disabled (i.e., if you call setEnabled(false) on a child,
2513 it will not be reenabled if its parent is disabled, and then enabled
2516 Items are enabled by default.
2518 \note If you install an event filter, you can still intercept events
2519 before they are delivered to items; this mechanism disregards the item's
2524 void QGraphicsItem::setEnabled(bool enabled)
2526 d_ptr->setEnabledHelper(enabled, /* explicitly = */ true);
2530 Returns true if this item is selected; otherwise, false is returned.
2532 Items that are in a group inherit the group's selected state.
2534 Items are not selected by default.
2536 \sa setSelected(), QGraphicsScene::setSelectionArea()
2538 bool QGraphicsItem::isSelected() const
2540 if (QGraphicsItemGroup *group = this->group())
2541 return group->isSelected();
2542 return d_ptr->selected;
2546 If \a selected is true and this item is selectable, this item is selected;
2547 otherwise, it is unselected.
2549 If the item is in a group, the whole group's selected state is toggled by
2550 this function. If the group is selected, all items in the group are also
2551 selected, and if the group is not selected, no item in the group is
2554 Only visible, enabled, selectable items can be selected. If \a selected
2555 is true and this item is either invisible or disabled or unselectable,
2556 this function does nothing.
2558 By default, items cannot be selected. To enable selection, set the
2559 ItemIsSelectable flag.
2561 This function is provided for convenience, allowing individual toggling of
2562 the selected state of an item. However, a more common way of selecting
2563 items is to call QGraphicsScene::setSelectionArea(), which will call this
2564 function for all visible, enabled, and selectable items within a specified
2567 \sa isSelected(), QGraphicsScene::selectedItems()
2569 void QGraphicsItem::setSelected(bool selected)
2571 if (QGraphicsItemGroup *group = this->group()) {
2572 group->setSelected(selected);
2576 if (!(d_ptr->flags & ItemIsSelectable) || !d_ptr->enabled || !d_ptr->visible)
2578 if (d_ptr->selected == selected)
2580 const QVariant newSelectedVariant(itemChange(ItemSelectedChange, quint32(selected)));
2581 bool newSelected = newSelectedVariant.toBool();
2582 if (d_ptr->selected == newSelected)
2584 d_ptr->selected = newSelected;
2588 QGraphicsScenePrivate *sceneD = d_ptr->scene->d_func();
2590 sceneD->selectedItems << this;
2592 // QGraphicsScene::selectedItems() lazily pulls out all items that are
2593 // no longer selected.
2595 if (!sceneD->selectionChanging)
2596 emit d_ptr->scene->selectionChanged();
2599 // Deliver post-change notification.
2600 itemChange(QGraphicsItem::ItemSelectedHasChanged, newSelectedVariant);
2606 Returns this item's local opacity, which is between 0.0 (transparent) and
2607 1.0 (opaque). This value is combined with parent and ancestor values into
2608 the effectiveOpacity(). The effective opacity decides how the item is
2609 rendered and also affects its visibility when queried by functions such as
2610 QGraphicsView::items().
2612 The opacity property decides the state of the painter passed to the
2613 paint() function. If the item is cached, i.e., ItemCoordinateCache or
2614 DeviceCoordinateCache, the effective property will be applied to the item's
2615 cache as it is rendered.
2617 The default opacity is 1.0; fully opaque.
2619 \sa setOpacity(), paint(), ItemIgnoresParentOpacity,
2620 ItemDoesntPropagateOpacityToChildren
2622 qreal QGraphicsItem::opacity() const
2624 return d_ptr->opacity;
2630 Returns this item's \e effective opacity, which is between 0.0
2631 (transparent) and 1.0 (opaque). This value is a combination of this item's
2632 local opacity, and its parent and ancestors' opacities. The effective
2633 opacity decides how the item is rendered.
2635 \sa opacity(), setOpacity(), paint(), ItemIgnoresParentOpacity,
2636 ItemDoesntPropagateOpacityToChildren
2638 qreal QGraphicsItem::effectiveOpacity() const
2640 return d_ptr->effectiveOpacity();
2646 Sets this item's local \a opacity, between 0.0 (transparent) and 1.0
2647 (opaque). The item's local opacity is combined with parent and ancestor
2648 opacities into the effectiveOpacity().
2650 By default, opacity propagates from parent to child, so if a parent's
2651 opacity is 0.5 and the child is also 0.5, the child's effective opacity
2654 The opacity property decides the state of the painter passed to the
2655 paint() function. If the item is cached, i.e., ItemCoordinateCache or
2656 DeviceCoordinateCache, the effective property will be applied to the
2657 item's cache as it is rendered.
2659 There are two item flags that affect how the item's opacity is combined
2660 with the parent: ItemIgnoresParentOpacity and
2661 ItemDoesntPropagateOpacityToChildren.
2663 \sa opacity(), effectiveOpacity()
2665 void QGraphicsItem::setOpacity(qreal opacity)
2668 const QVariant newOpacityVariant(itemChange(ItemOpacityChange, opacity));
2670 // Normalized opacity
2671 qreal newOpacity = qBound(qreal(0), newOpacityVariant.toReal(), qreal(1));
2674 if (newOpacity == d_ptr->opacity)
2677 bool wasFullyTransparent = d_ptr->isOpacityNull();
2678 d_ptr->opacity = newOpacity;
2681 itemChange(ItemOpacityHasChanged, newOpacityVariant);
2685 #ifndef QT_NO_GRAPHICSEFFECT
2686 d_ptr->invalidateParentGraphicsEffectsRecursively();
2687 if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren))
2688 d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged);
2689 #endif //QT_NO_GRAPHICSEFFECT
2690 d_ptr->scene->d_func()->markDirty(this, QRectF(),
2691 /*invalidateChildren=*/true,
2693 /*ignoreOpacity=*/d_ptr->isOpacityNull());
2694 if (wasFullyTransparent)
2695 d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
2698 if (d_ptr->isObject)
2699 emit static_cast<QGraphicsObject *>(this)->opacityChanged();
2703 Returns a pointer to this item's effect if it has one; otherwise 0.
2707 #ifndef QT_NO_GRAPHICSEFFECT
2708 QGraphicsEffect *QGraphicsItem::graphicsEffect() const
2710 return d_ptr->graphicsEffect;
2714 Sets \a effect as the item's effect. If there already is an effect installed
2715 on this item, QGraphicsItem will delete the existing effect before installing
2716 the new \a effect. You can delete an existing effect by calling
2717 setGraphicsEffect(0).
2719 If \a effect is the installed on a different item, setGraphicsEffect() will remove
2720 the effect from the item and install it on this item.
2722 QGraphicsItem takes ownership of \a effect.
2724 \note This function will apply the effect on itself and all its children.
2728 void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
2730 if (d_ptr->graphicsEffect == effect)
2733 if (d_ptr->graphicsEffect) {
2734 delete d_ptr->graphicsEffect;
2735 d_ptr->graphicsEffect = 0;
2736 } else if (d_ptr->parent) {
2737 d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively();
2742 QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
2743 QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
2744 d_ptr->graphicsEffect = effect;
2745 effect->d_func()->setGraphicsEffectSource(source);
2746 prepareGeometryChange();
2749 #endif //QT_NO_GRAPHICSEFFECT
2751 void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively()
2753 #ifndef QT_NO_GRAPHICSEFFECT
2754 QGraphicsItemPrivate *itemPrivate = this;
2756 // parent chain already notified?
2757 if (itemPrivate->mayHaveChildWithGraphicsEffect)
2759 itemPrivate->mayHaveChildWithGraphicsEffect = 1;
2760 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
2767 Returns the effective bounding rect of the given item space rect.
2768 If the item has no effect, the rect is returned unmodified.
2769 If the item has an effect, the effective rect can be extend beyond the
2770 item's bounding rect, depending on the effect.
2774 QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
2776 #ifndef QT_NO_GRAPHICSEFFECT
2777 Q_Q(const QGraphicsItem);
2778 QGraphicsEffect *effect = graphicsEffect;
2779 if (scene && effect && effect->isEnabled()) {
2780 if (scene->d_func()->views.isEmpty())
2781 return effect->boundingRectFor(rect);
2782 QRectF sceneRect = q->mapRectToScene(rect);
2783 QRectF sceneEffectRect;
2784 foreach (QGraphicsView *view, scene->views()) {
2785 QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect);
2786 QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect();
2787 sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect);
2789 return q->mapRectFromScene(sceneEffectRect);
2791 #endif //QT_NO_GRAPHICSEFFECT
2798 Returns the effective bounding rect of the item.
2799 If the item has no effect, this is the same as the item's bounding rect.
2800 If the item has an effect, the effective rect can be larger than the item's
2801 bouding rect, depending on the effect.
2805 QRectF QGraphicsItemPrivate::effectiveBoundingRect(QGraphicsItem *topMostEffectItem) const
2807 #ifndef QT_NO_GRAPHICSEFFECT
2808 Q_Q(const QGraphicsItem);
2809 QRectF brect = effectiveBoundingRect(q_ptr->boundingRect());
2810 if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren || topMostEffectItem == q)
2813 const QGraphicsItem *effectParent = parent;
2814 while (effectParent) {
2815 QGraphicsEffect *effect = effectParent->d_ptr->graphicsEffect;
2816 if (scene && effect && effect->isEnabled()) {
2817 const QRectF brectInParentSpace = q->mapRectToItem(effectParent, brect);
2818 const QRectF effectRectInParentSpace = effectParent->d_ptr->effectiveBoundingRect(brectInParentSpace);
2819 brect = effectParent->mapRectToItem(q, effectRectInParentSpace);
2821 if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren
2822 || topMostEffectItem == effectParent) {
2825 effectParent = effectParent->d_ptr->parent;
2829 #else //QT_NO_GRAPHICSEFFECT
2830 return q_ptr->boundingRect();
2831 #endif //QT_NO_GRAPHICSEFFECT
2838 Returns the effective bounding rect of this item in scene coordinates,
2839 by combining sceneTransform() with boundingRect(), taking into account
2840 the effect that the item might have.
2842 If the item has no effect, this is the same as sceneBoundingRect().
2844 \sa effectiveBoundingRect(), sceneBoundingRect()
2846 QRectF QGraphicsItemPrivate::sceneEffectiveBoundingRect() const
2848 // Find translate-only offset
2851 const QGraphicsItem *parentItem = q_ptr;
2852 const QGraphicsItemPrivate *itemd;
2854 itemd = parentItem->d_ptr.data();
2855 if (itemd->transformData)
2857 offset += itemd->pos;
2858 } while ((parentItem = itemd->parent));
2860 QRectF br = effectiveBoundingRect();
2861 br.translate(offset);
2862 return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
2866 Returns true if this item can accept drag and drop events; otherwise,
2867 returns false. By default, items do not accept drag and drop events; items
2868 are transparent to drag and drop.
2870 \sa setAcceptDrops()
2872 bool QGraphicsItem::acceptDrops() const
2874 return d_ptr->acceptDrops;
2878 If \a on is true, this item will accept drag and drop events; otherwise,
2879 it is transparent for drag and drop events. By default, items do not
2880 accept drag and drop events.
2884 void QGraphicsItem::setAcceptDrops(bool on)
2886 d_ptr->acceptDrops = on;
2890 Returns the mouse buttons that this item accepts mouse events for. By
2891 default, all mouse buttons are accepted.
2893 If an item accepts a mouse button, it will become the mouse
2894 grabber item when a mouse press event is delivered for that mouse
2895 button. However, if the item does not accept the button,
2896 QGraphicsScene will forward the mouse events to the first item
2897 beneath it that does.
2899 \sa setAcceptedMouseButtons(), mousePressEvent()
2901 Qt::MouseButtons QGraphicsItem::acceptedMouseButtons() const
2903 return Qt::MouseButtons(d_ptr->acceptedMouseButtons);
2907 Sets the mouse \a buttons that this item accepts mouse events for.
2909 By default, all mouse buttons are accepted. If an item accepts a
2910 mouse button, it will become the mouse grabber item when a mouse
2911 press event is delivered for that button. However, if the item
2912 does not accept the mouse button, QGraphicsScene will forward the
2913 mouse events to the first item beneath it that does.
2915 To disable mouse events for an item (i.e., make it transparent for mouse
2916 events), call setAcceptedMouseButtons(0).
2918 \sa acceptedMouseButtons(), mousePressEvent()
2920 void QGraphicsItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
2922 if (Qt::MouseButtons(d_ptr->acceptedMouseButtons) != buttons) {
2923 if (buttons == 0 && d_ptr->scene && d_ptr->scene->mouseGrabberItem() == this
2924 && d_ptr->scene->d_func()->lastMouseGrabberItemHasImplicitMouseGrab) {
2927 d_ptr->acceptedMouseButtons = quint32(buttons);
2934 Returns true if an item accepts hover events
2935 (QGraphicsSceneHoverEvent); otherwise, returns false. By default,
2936 items do not accept hover events.
2938 \sa setAcceptedMouseButtons()
2940 bool QGraphicsItem::acceptHoverEvents() const
2942 return d_ptr->acceptsHover;
2946 \fn bool QGraphicsItem::acceptsHoverEvents() const
2949 Call acceptHoverEvents() instead.
2955 If \a enabled is true, this item will accept hover events;
2956 otherwise, it will ignore them. By default, items do not accept
2959 Hover events are delivered when there is no current mouse grabber
2960 item. They are sent when the mouse cursor enters an item, when it
2961 moves around inside the item, and when the cursor leaves an
2962 item. Hover events are commonly used to highlight an item when
2963 it's entered, and for tracking the mouse cursor as it hovers over
2964 the item (equivalent to QWidget::mouseTracking).
2966 Parent items receive hover enter events before their children, and
2967 leave events after their children. The parent does not receive a
2968 hover leave event if the cursor enters a child, though; the parent
2969 stays "hovered" until the cursor leaves its area, including its
2972 If a parent item handles child events, it will receive hover move,
2973 drag move, and drop events as the cursor passes through its
2974 children, but it does not receive hover enter and hover leave, nor
2975 drag enter and drag leave events on behalf of its children.
2977 A QGraphicsWidget with window decorations will accept hover events
2978 regardless of the value of acceptHoverEvents().
2980 \sa acceptHoverEvents(), hoverEnterEvent(), hoverMoveEvent(),
2983 void QGraphicsItem::setAcceptHoverEvents(bool enabled)
2985 if (d_ptr->acceptsHover == quint32(enabled))
2987 d_ptr->acceptsHover = quint32(enabled);
2988 if (d_ptr->acceptsHover && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreHoverEvents) {
2989 d_ptr->scene->d_func()->allItemsIgnoreHoverEvents = false;
2990 d_ptr->scene->d_func()->enableMouseTrackingOnViews();
2995 \fn void QGraphicsItem::setAcceptsHoverEvents(bool enabled)
2998 Use setAcceptHoverEvents(\a enabled) instead.
3003 Returns true if an item accepts \l{QTouchEvent}{touch events};
3004 otherwise, returns false. By default, items do not accept touch events.
3006 \sa setAcceptTouchEvents()
3008 bool QGraphicsItem::acceptTouchEvents() const
3010 return d_ptr->acceptTouchEvents;
3016 If \a enabled is true, this item will accept \l{QTouchEvent}{touch events};
3017 otherwise, it will ignore them. By default, items do not accept
3020 void QGraphicsItem::setAcceptTouchEvents(bool enabled)
3022 if (d_ptr->acceptTouchEvents == quint32(enabled))
3024 d_ptr->acceptTouchEvents = quint32(enabled);
3025 if (d_ptr->acceptTouchEvents && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreTouchEvents) {
3026 d_ptr->scene->d_func()->allItemsIgnoreTouchEvents = false;
3027 d_ptr->scene->d_func()->enableTouchEventsOnViews();
3034 Returns true if this item filters child events (i.e., all events
3035 intended for any of its children are instead sent to this item);
3036 otherwise, false is returned.
3038 The default value is false; child events are not filtered.
3040 \sa setFiltersChildEvents()
3042 bool QGraphicsItem::filtersChildEvents() const
3044 return d_ptr->filtersDescendantEvents;
3050 If \a enabled is true, this item is set to filter all events for
3051 all its children (i.e., all events intented for any of its
3052 children are instead sent to this item); otherwise, if \a enabled
3053 is false, this item will only handle its own events. The default
3056 \sa filtersChildEvents()
3058 void QGraphicsItem::setFiltersChildEvents(bool enabled)
3060 if (d_ptr->filtersDescendantEvents == enabled)
3063 d_ptr->filtersDescendantEvents = enabled;
3064 d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
3070 Returns true if this item handles 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 This property is useful for item groups; it allows one item to
3075 handle events on behalf of its children, as opposed to its
3076 children handling their events individually.
3078 The default is to return false; children handle their own events.
3079 The exception for this is if the item is a QGraphicsItemGroup, then
3080 it defaults to return true.
3082 \sa setHandlesChildEvents()
3084 bool QGraphicsItem::handlesChildEvents() const
3086 return d_ptr->handlesChildEvents;
3092 If \a enabled is true, this item is set to handle all events for
3093 all its children (i.e., all events intented for any of its
3094 children are instead sent to this item); otherwise, if \a enabled
3095 is false, this item will only handle its own events. The default
3098 This property is useful for item groups; it allows one item to
3099 handle events on behalf of its children, as opposed to its
3100 children handling their events individually.
3102 If a child item accepts hover events, its parent will receive
3103 hover move events as the cursor passes through the child, but it
3104 does not receive hover enter and hover leave events on behalf of
3107 \sa handlesChildEvents()
3109 void QGraphicsItem::setHandlesChildEvents(bool enabled)
3111 if (d_ptr->handlesChildEvents == enabled)
3114 d_ptr->handlesChildEvents = enabled;
3115 d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
3119 Returns true if this item is active; otherwise returns false.
3121 An item can only be active if the scene is active. An item is active
3122 if it is, or is a descendent of, an active panel. Items in non-active
3123 panels are not active.
3125 Items that are not part of a panel follow scene activation when the
3126 scene has no active panel.
3128 Only active items can gain input focus.
3130 \sa QGraphicsScene::isActive(), QGraphicsScene::activePanel(), panel(), isPanel()
3132 bool QGraphicsItem::isActive() const
3134 if (!d_ptr->scene || !d_ptr->scene->isActive())
3136 return panel() == d_ptr->scene->activePanel();
3142 If \a active is true, and the scene is active, this item's panel will be
3143 activated. Otherwise, the panel is deactivated.
3145 If the item is not part of an active scene, \a active will decide what
3146 happens to the panel when the scene becomes active or the item is added to
3147 the scene. If true, the item's panel will be activated when the item is
3148 either added to the scene or the scene is activated. Otherwise, the item
3149 will stay inactive independent of the scene's activated state.
3151 \sa isPanel(), QGraphicsScene::setActivePanel(), QGraphicsScene::isActive()
3153 void QGraphicsItem::setActive(bool active)
3155 d_ptr->explicitActivate = 1;
3156 d_ptr->wantsActive = active;
3159 // Activate this item.
3160 d_ptr->scene->setActivePanel(this);
3162 // Deactivate this item, and reactivate the last active item
3164 QGraphicsItem *lastActive = d_ptr->scene->d_func()->lastActivePanel;
3165 d_ptr->scene->setActivePanel(lastActive != this ? lastActive : 0);
3171 Returns true if this item is active, and it or its \l{focusProxy()}{focus
3172 proxy} has keyboard input focus; otherwise, returns false.
3174 \sa focusItem(), setFocus(), QGraphicsScene::setFocusItem(), isActive()
3176 bool QGraphicsItem::hasFocus() const
3178 if (!d_ptr->scene || !d_ptr->scene->isActive())
3181 if (d_ptr->focusProxy)
3182 return d_ptr->focusProxy->hasFocus();
3184 if (d_ptr->scene->d_func()->focusItem != this)
3187 return panel() == d_ptr->scene->d_func()->activePanel;
3191 Gives keyboard input focus to this item. The \a focusReason argument will
3192 be passed into any \l{QFocusEvent}{focus event} generated by this function;
3193 it is used to give an explanation of what caused the item to get focus.
3195 Only enabled items that set the ItemIsFocusable flag can accept keyboard
3198 If this item is not visible, not active, or not associated with a scene,
3199 it will not gain immediate input focus. However, it will be registered as
3200 the preferred focus item for its subtree of items, should it later become
3203 As a result of calling this function, this item will receive a
3204 \l{focusInEvent()}{focus in event} with \a focusReason. If another item
3205 already has focus, that item will first receive a \l{focusOutEvent()}
3206 {focus out event} indicating that it has lost input focus.
3208 \sa clearFocus(), hasFocus(), focusItem(), focusProxy()
3210 void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
3212 d_ptr->setFocusHelper(focusReason, /* climb = */ true, /* focusFromHide = */ false);
3218 void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb, bool focusFromHide)
3220 // Disabled / unfocusable items cannot accept focus.
3221 if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
3224 // Find focus proxy.
3225 QGraphicsItem *f = q_ptr;
3226 while (f->d_ptr->focusProxy)
3227 f = f->d_ptr->focusProxy;
3229 // Return if it already has focus.
3230 if (scene && scene->focusItem() == f)
3233 // Update focus scope item ptr.
3234 QGraphicsItem *p = parent;
3236 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3237 QGraphicsItem *oldFocusScopeItem = p->d_ptr->focusScopeItem;
3238 p->d_ptr->focusScopeItem = q_ptr;
3239 if (!p->focusItem() && !focusFromHide) {
3240 if (oldFocusScopeItem)
3241 oldFocusScopeItem->d_ptr->focusScopeItemChange(false);
3242 focusScopeItemChange(true);
3243 // If you call setFocus on a child of a focus scope that
3244 // doesn't currently have a focus item, then stop.
3249 p = p->d_ptr->parent;
3253 while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible())
3254 f = f->d_ptr->focusScopeItem;
3257 // Update the child focus chain.
3258 QGraphicsItem *commonAncestor = 0;
3259 if (scene && scene->focusItem()) {
3260 commonAncestor = scene->focusItem()->commonAncestorItem(f);
3261 scene->focusItem()->d_ptr->clearSubFocus(scene->focusItem(), commonAncestor);
3264 f->d_ptr->setSubFocus(f, commonAncestor);
3266 // Update the scene's focus item.
3268 QGraphicsItem *p = q_ptr->panel();
3269 if ((!p && scene->isActive()) || (p && p->isActive())) {
3270 // Visible items immediately gain focus from scene.
3271 scene->d_func()->setFocusItemHelper(f, focusReason);
3277 Takes keyboard input focus from the item.
3279 If it has focus, a \l{focusOutEvent()}{focus out event} is sent to this
3280 item to tell it that it is about to lose the focus.
3282 Only items that set the ItemIsFocusable flag, or widgets that set an
3283 appropriate focus policy, can accept keyboard focus.
3285 \sa setFocus(), hasFocus(), QGraphicsWidget::focusPolicy
3287 void QGraphicsItem::clearFocus()
3289 d_ptr->clearFocusHelper(/* giveFocusToParent = */ true);
3295 void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent)
3297 if (giveFocusToParent) {
3298 // Pass focus to the closest parent focus scope
3299 if (!inDestructor) {
3300 QGraphicsItem *p = parent;
3302 if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
3303 if (p->d_ptr->focusScopeItem == q_ptr) {
3304 p->d_ptr->focusScopeItem = 0;
3305 if (!q_ptr->hasFocus()) //if it has focus, focusScopeItemChange is called elsewhere
3306 focusScopeItemChange(false);
3308 if (q_ptr->hasFocus())
3309 p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false,
3310 /* focusFromHide = */ false);
3313 p = p->d_ptr->parent;
3318 if (q_ptr->hasFocus()) {
3319 // Invisible items with focus must explicitly clear subfocus.
3320 clearSubFocus(q_ptr);
3322 // If this item has the scene's input focus, clear it.
3323 scene->setFocusItem(0);
3330 Returns this item's focus proxy, or 0 if this item has no
3333 \sa setFocusProxy(), setFocus(), hasFocus()
3335 QGraphicsItem *QGraphicsItem::focusProxy() const
3337 return d_ptr->focusProxy;
3343 Sets the item's focus proxy to \a item.
3345 If an item has a focus proxy, the focus proxy will receive
3346 input focus when the item gains input focus. The item itself
3347 will still have focus (i.e., hasFocus() will return true),
3348 but only the focus proxy will receive the keyboard input.
3350 A focus proxy can itself have a focus proxy, and so on. In
3351 such case, keyboard input will be handled by the outermost
3354 The focus proxy \a item must belong to the same scene as
3357 \sa focusProxy(), setFocus(), hasFocus()
3359 void QGraphicsItem::setFocusProxy(QGraphicsItem *item)
3361 if (item == d_ptr->focusProxy)
3364 qWarning("QGraphicsItem::setFocusProxy: cannot assign self as focus proxy");
3368 if (item->d_ptr->scene != d_ptr->scene) {
3369 qWarning("QGraphicsItem::setFocusProxy: focus proxy must be in same scene");
3372 for (QGraphicsItem *f = item->focusProxy(); f != 0; f = f->focusProxy()) {
3374 qWarning("QGraphicsItem::setFocusProxy: %p is already in the focus proxy chain", item);
3380 QGraphicsItem *lastFocusProxy = d_ptr->focusProxy;
3382 lastFocusProxy->d_ptr->focusProxyRefs.removeOne(&d_ptr->focusProxy);
3383 d_ptr->focusProxy = item;
3385 item->d_ptr->focusProxyRefs << &d_ptr->focusProxy;
3391 If this item, a child or descendant of this item currently has input
3392 focus, this function will return a pointer to that item. If
3393 no descendant has input focus, 0 is returned.
3395 \sa hasFocus(), setFocus(), QWidget::focusWidget()
3397 QGraphicsItem *QGraphicsItem::focusItem() const
3399 return d_ptr->subFocusItem;
3405 Returns this item's focus scope item.
3407 QGraphicsItem *QGraphicsItem::focusScopeItem() const
3409 return d_ptr->focusScopeItem;
3414 Grabs the mouse input.
3416 This item will receive all mouse events for the scene until any of the
3417 following events occurs:
3420 \li The item becomes invisible
3421 \li The item is removed from the scene
3422 \li The item is deleted
3423 \li The item call ungrabMouse()
3424 \li Another item calls grabMouse(); the item will regain the mouse grab
3425 when the other item calls ungrabMouse().
3428 When an item gains the mouse grab, it receives a QEvent::GrabMouse
3429 event. When it loses the mouse grab, it receives a QEvent::UngrabMouse
3430 event. These events can be used to detect when your item gains or loses
3431 the mouse grab through other means than receiving mouse button events.
3433 It is almost never necessary to explicitly grab the mouse in Qt, as Qt
3434 grabs and releases it sensibly. In particular, Qt grabs the mouse when you
3435 press a mouse button, and keeps the mouse grabbed until you release the
3436 last mouse button. Also, Qt::Popup widgets implicitly call grabMouse()
3437 when shown, and ungrabMouse() when hidden.
3439 Note that only visible items can grab mouse input. Calling grabMouse() on
3440 an invisible item has no effect.
3442 Keyboard events are not affected.
3444 \sa QGraphicsScene::mouseGrabberItem(), ungrabMouse(), grabKeyboard()
3446 void QGraphicsItem::grabMouse()
3448 if (!d_ptr->scene) {
3449 qWarning("QGraphicsItem::grabMouse: cannot grab mouse without scene");
3452 if (!d_ptr->visible) {
3453 qWarning("QGraphicsItem::grabMouse: cannot grab mouse while invisible");
3456 d_ptr->scene->d_func()->grabMouse(this);
3461 Releases the mouse grab.
3463 \sa grabMouse(), ungrabKeyboard()
3465 void QGraphicsItem::ungrabMouse()
3467 if (!d_ptr->scene) {
3468 qWarning("QGraphicsItem::ungrabMouse: cannot ungrab mouse without scene");
3471 d_ptr->scene->d_func()->ungrabMouse(this);
3476 Grabs the keyboard input.
3478 The item will receive all keyboard input to the scene until one of the
3479 following events occur:
3482 \li The item becomes invisible
3483 \li The item is removed from the scene
3484 \li The item is deleted
3485 \li The item calls ungrabKeyboard()
3486 \li Another item calls grabKeyboard(); the item will regain the keyboard grab
3487 when the other item calls ungrabKeyboard().
3490 When an item gains the keyboard grab, it receives a QEvent::GrabKeyboard
3491 event. When it loses the keyboard grab, it receives a
3492 QEvent::UngrabKeyboard event. These events can be used to detect when your
3493 item gains or loses the keyboard grab through other means than gaining
3496 It is almost never necessary to explicitly grab the keyboard in Qt, as Qt
3497 grabs and releases it sensibly. In particular, Qt grabs the keyboard when
3498 your item gains input focus, and releases it when your item loses input
3499 focus, or when the item is hidden.
3501 Note that only visible items can grab keyboard input. Calling
3502 grabKeyboard() on an invisible item has no effect.
3504 Keyboard events are not affected.
3506 \sa ungrabKeyboard(), grabMouse(), setFocus()
3508 void QGraphicsItem::grabKeyboard()
3510 if (!d_ptr->scene) {
3511 qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard without scene");
3514 if (!d_ptr->visible) {
3515 qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard while invisible");
3518 d_ptr->scene->d_func()->grabKeyboard(this);
3523 Releases the keyboard grab.
3525 \sa grabKeyboard(), ungrabMouse()
3527 void QGraphicsItem::ungrabKeyboard()
3529 if (!d_ptr->scene) {
3530 qWarning("QGraphicsItem::ungrabKeyboard: cannot ungrab keyboard without scene");
3533 d_ptr->scene->d_func()->ungrabKeyboard(this);
3537 Returns the position of the item in parent coordinates. If the item has no
3538 parent, its position is given in scene coordinates.
3540 The position of the item describes its origin (local coordinate
3541 (0, 0)) in parent coordinates; this function returns the same as
3544 For convenience, you can also call scenePos() to determine the
3545 item's position in scene coordinates, regardless of its parent.
3547 \sa x(), y(), setPos(), transform(), {The Graphics View Coordinate System}
3549 QPointF QGraphicsItem::pos() const
3555 \fn QGraphicsItem::x() const
3557 This convenience function is equivalent to calling pos().x().
3565 Set's the \a x coordinate of the item's position. Equivalent to
3566 calling setPos(x, y()).
3570 void QGraphicsItem::setX(qreal x)
3572 if (d_ptr->inDestructor)
3578 setPos(QPointF(x, d_ptr->pos.y()));
3582 \fn QGraphicsItem::y() const
3584 This convenience function is equivalent to calling pos().y().
3592 Set's the \a y coordinate of the item's position. Equivalent to
3593 calling setPos(x(), y).
3597 void QGraphicsItem::setY(qreal y)
3599 if (d_ptr->inDestructor)
3605 setPos(QPointF(d_ptr->pos.x(), y));
3609 Returns the item's position in scene coordinates. This is
3610 equivalent to calling \c mapToScene(0, 0).
3612 \sa pos(), sceneTransform(), {The Graphics View Coordinate System}
3614 QPointF QGraphicsItem::scenePos() const
3616 return mapToScene(0, 0);
3622 Sets the position \a pos.
3624 void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
3629 q->prepareGeometryChange();
3630 QPointF oldPos = this->pos;
3632 dirtySceneTransform = 1;
3635 if (pos.x() != oldPos.x())
3636 emit static_cast<QGraphicsObject *>(q_ptr)->xChanged();
3637 if (pos.y() != oldPos.y())
3638 emit static_cast<QGraphicsObject *>(q_ptr)->yChanged();
3645 Sets the transform \a transform.
3647 void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
3649 q_ptr->prepareGeometryChange();
3650 transformData->transform = transform;
3651 dirtySceneTransform = 1;
3656 Sets the position of the item to \a pos, which is in parent
3657 coordinates. For items with no parent, \a pos is in scene
3660 The position of the item describes its origin (local coordinate
3661 (0, 0)) in parent coordinates.
3663 \sa pos(), scenePos(), {The Graphics View Coordinate System}
3665 void QGraphicsItem::setPos(const QPointF &pos)
3667 if (d_ptr->pos == pos)
3670 if (d_ptr->inDestructor)
3673 // Update and repositition.
3674 if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
3675 d_ptr->setPosHelper(pos);
3676 if (d_ptr->isWidget)
3677 static_cast<QGraphicsWidget *>(this)->d_func()->setGeometryFromSetPos();
3678 if (d_ptr->scenePosDescendants)
3679 d_ptr->sendScenePosChange();
3683 // Notify the item that the position is changing.
3684 const QVariant newPosVariant(itemChange(ItemPositionChange, QVariant::fromValue<QPointF>(pos)));
3685 QPointF newPos = newPosVariant.toPointF();
3686 if (newPos == d_ptr->pos)
3689 // Update and repositition.
3690 d_ptr->setPosHelper(newPos);
3692 // Send post-notification.
3693 itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
3694 d_ptr->sendScenePosChange();
3698 \fn void QGraphicsItem::setPos(qreal x, qreal y)
3701 This convenience function is equivalent to calling setPos(QPointF(\a x, \a
3706 \fn void QGraphicsItem::moveBy(qreal dx, qreal dy)
3708 Moves the item by \a dx points horizontally, and \a dy point
3709 vertically. This function is equivalent to calling setPos(pos() +
3710 QPointF(\a dx, \a dy)).
3714 If this item is part of a scene that is viewed by a QGraphicsView, this
3715 convenience function will attempt to scroll the view to ensure that \a
3716 rect is visible inside the view's viewport. If \a rect is a null rect (the
3717 default), QGraphicsItem will default to the item's bounding rect. \a xmargin
3718 and \a ymargin are the number of pixels the view should use for margins.
3720 If the specified rect cannot be reached, the contents are scrolled to the
3721 nearest valid position.
3723 If this item is not viewed by a QGraphicsView, this function does nothing.
3725 \sa QGraphicsView::ensureVisible()
3727 void QGraphicsItem::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
3732 sceneRect = sceneTransform().mapRect(rect);
3734 sceneRect = sceneBoundingRect();
3735 foreach (QGraphicsView *view, d_ptr->scene->d_func()->views)
3736 view->ensureVisible(sceneRect, xmargin, ymargin);
3741 \fn void QGraphicsItem::ensureVisible(qreal x, qreal y, qreal w, qreal h,
3742 int xmargin = 50, int ymargin = 50)
3744 This convenience function is equivalent to calling
3745 ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin):
3751 Returns the item's affine transformation matrix. This is a subset or the
3752 item's full transformation matrix, and might not represent the item's full
3755 Use transform() instead.
3757 \sa setTransform(), sceneTransform()
3759 QMatrix QGraphicsItem::matrix() const
3761 return transform().toAffine();
3767 Returns this item's transformation matrix.
3769 The transformation matrix is combined with the item's rotation(), scale()
3770 and transformations() into a combined transformations for the item.
3772 The default transformation matrix is an identity matrix.
3774 \sa setTransform(), sceneTransform()
3776 QTransform QGraphicsItem::transform() const
3778 if (!d_ptr->transformData)
3779 return QTransform();
3780 return d_ptr->transformData->transform;
3786 Returns the clockwise rotation, in degrees, around the Z axis. The default
3787 value is 0 (i.e., the item is not rotated).
3789 The rotation is combined with the item's scale(), transform() and
3790 transformations() to map the item's coordinate system to the parent item.
3792 \sa setRotation(), transformOriginPoint(), {Transformations}
3794 qreal QGraphicsItem::rotation() const
3796 if (!d_ptr->transformData)
3798 return d_ptr->transformData->rotation;
3804 Sets the clockwise rotation \a angle, in degrees, around the Z axis. The
3805 default value is 0 (i.e., the item is not rotated). Assigning a negative
3806 value will rotate the item counter-clockwise. Normally the rotation angle
3807 is in the range (-360, 360), but it's also possible to assign values
3808 outside of this range (e.g., a rotation of 370 degrees is the same as a
3809 rotation of 10 degrees).
3811 The item is rotated around its transform origin point, which by default
3812 is (0, 0). You can select a different transformation origin by calling
3813 setTransformOriginPoint().
3815 The rotation is combined with the item's scale(), transform() and
3816 transformations() to map the item's coordinate system to the parent item.
3818 \sa rotation(), setTransformOriginPoint(), {Transformations}
3820 void QGraphicsItem::setRotation(qreal angle)
3822 prepareGeometryChange();
3823 qreal newRotation = angle;
3825 if (d_ptr->flags & ItemSendsGeometryChanges) {
3826 // Notify the item that the rotation is changing.
3827 const QVariant newRotationVariant(itemChange(ItemRotationChange, angle));
3828 newRotation = newRotationVariant.toReal();
3831 if (!d_ptr->transformData)
3832 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
3834 if (d_ptr->transformData->rotation == newRotation)
3837 d_ptr->transformData->rotation = newRotation;
3838 d_ptr->transformData->onlyTransform = false;
3839 d_ptr->dirtySceneTransform = 1;
3841 // Send post-notification.
3842 if (d_ptr->flags & ItemSendsGeometryChanges)
3843 itemChange(ItemRotationHasChanged, newRotation);
3845 if (d_ptr->isObject)
3846 emit static_cast<QGraphicsObject *>(this)->rotationChanged();
3848 d_ptr->transformChanged();
3854 Returns the scale factor of the item. The default scale factor is 1.0
3855 (i.e., the item is not scaled).
3857 The scale is combined with the item's rotation(), transform() and
3858 transformations() to map the item's coordinate system to the parent item.
3860 \sa setScale(), rotation(), {Transformations}
3862 qreal QGraphicsItem::scale() const
3864 if (!d_ptr->transformData)
3866 return d_ptr->transformData->scale;
3872 Sets the scale \a factor of the item. The default scale factor is 1.0
3873 (i.e., the item is not scaled). A scale factor of 0.0 will collapse the
3874 item to a single point. If you provide a negative scale factor, the
3875 item will be flipped and mirrored (i.e., rotated 180 degrees).
3877 The item is scaled around its transform origin point, which by default
3878 is (0, 0). You can select a different transformation origin by calling
3879 setTransformOriginPoint().
3881 The scale is combined with the item's rotation(), transform() and
3882 transformations() to map the item's coordinate system to the parent item.
3884 \sa scale(), setTransformOriginPoint(), {Transformations Example}
3886 void QGraphicsItem::setScale(qreal factor)
3888 prepareGeometryChange();
3889 qreal newScale = factor;
3891 if (d_ptr->flags & ItemSendsGeometryChanges) {
3892 // Notify the item that the scale is changing.
3893 const QVariant newScaleVariant(itemChange(ItemScaleChange, factor));
3894 newScale = newScaleVariant.toReal();
3897 if (!d_ptr->transformData)
3898 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
3900 if (d_ptr->transformData->scale == newScale)
3903 d_ptr->transformData->scale = newScale;
3904 d_ptr->transformData->onlyTransform = false;
3905 d_ptr->dirtySceneTransform = 1;
3907 // Send post-notification.
3908 if (d_ptr->flags & ItemSendsGeometryChanges)
3909 itemChange(ItemScaleHasChanged, newScale);
3911 if (d_ptr->isObject)
3912 emit static_cast<QGraphicsObject *>(this)->scaleChanged();
3914 d_ptr->transformChanged();
3921 Returns a list of graphics transforms that currently apply to this item.
3923 QGraphicsTransform is for applying and controlling a chain of individual
3924 transformation operations on an item. It's particularly useful in
3925 animations, where each transform operation needs to be interpolated
3926 independently, or differently.
3928 The transformations are combined with the item's rotation(), scale() and
3929 transform() to map the item's coordinate system to the parent item.
3931 \sa scale(), rotation(), transformOriginPoint(), {Transformations}
3933 QList<QGraphicsTransform *> QGraphicsItem::transformations() const
3935 if (!d_ptr->transformData)
3936 return QList<QGraphicsTransform *>();
3937 return d_ptr->transformData->graphicsTransforms;
3943 Sets a list of graphics \a transformations (QGraphicsTransform) that
3944 currently apply to this item.
3946 If all you want is to rotate or scale an item, you should call setRotation()
3947 or setScale() instead. If you want to set an arbitrary transformation on
3948 an item, you can call setTransform().
3950 QGraphicsTransform is for applying and controlling a chain of individual
3951 transformation operations on an item. It's particularly useful in
3952 animations, where each transform operation needs to be interpolated
3953 independently, or differently.
3955 The transformations are combined with the item's rotation(), scale() and
3956 transform() to map the item's coordinate system to the parent item.
3958 \sa scale(), setTransformOriginPoint(), {Transformations}
3960 void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transformations)
3962 prepareGeometryChange();
3963 if (!d_ptr->transformData)
3964 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
3965 d_ptr->transformData->graphicsTransforms = transformations;
3966 for (int i = 0; i < transformations.size(); ++i)
3967 transformations.at(i)->d_func()->setItem(this);
3968 d_ptr->transformData->onlyTransform = false;
3969 d_ptr->dirtySceneTransform = 1;
3970 d_ptr->transformChanged();
3976 void QGraphicsItemPrivate::prependGraphicsTransform(QGraphicsTransform *t)
3979 transformData = new QGraphicsItemPrivate::TransformData;
3980 if (!transformData->graphicsTransforms.contains(t))
3981 transformData->graphicsTransforms.prepend(t);
3984 t->d_func()->setItem(q);
3985 transformData->onlyTransform = false;
3986 dirtySceneTransform = 1;
3993 void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t)
3996 transformData = new QGraphicsItemPrivate::TransformData;
3997 if (!transformData->graphicsTransforms.contains(t))
3998 transformData->graphicsTransforms.append(t);
4001 t->d_func()->setItem(q);
4002 transformData->onlyTransform = false;
4003 dirtySceneTransform = 1;
4010 Returns the origin point for the transformation in item coordinates.
4012 The default is QPointF(0,0).
4014 \sa setTransformOriginPoint(), {Transformations}
4016 QPointF QGraphicsItem::transformOriginPoint() const
4018 if (!d_ptr->transformData)
4019 return QPointF(0,0);
4020 return QPointF(d_ptr->transformData->xOrigin, d_ptr->transformData->yOrigin);
4026 Sets the \a origin point for the transformation in item coordinates.
4028 \sa transformOriginPoint(), {Transformations}
4030 void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
4032 prepareGeometryChange();
4033 QPointF newOrigin = origin;
4035 if (d_ptr->flags & ItemSendsGeometryChanges) {
4036 // Notify the item that the origin point is changing.
4037 const QVariant newOriginVariant(itemChange(ItemTransformOriginPointChange,
4038 QVariant::fromValue<QPointF>(origin)));
4039 newOrigin = newOriginVariant.toPointF();
4042 if (!d_ptr->transformData)
4043 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4045 if (d_ptr->transformData->xOrigin == newOrigin.x()
4046 && d_ptr->transformData->yOrigin == newOrigin.y()) {
4050 d_ptr->transformData->xOrigin = newOrigin.x();
4051 d_ptr->transformData->yOrigin = newOrigin.y();
4052 d_ptr->transformData->onlyTransform = false;
4053 d_ptr->dirtySceneTransform = 1;
4055 // Send post-notification.
4056 if (d_ptr->flags & ItemSendsGeometryChanges)
4057 itemChange(ItemTransformOriginPointHasChanged, QVariant::fromValue<QPointF>(newOrigin));
4061 \fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y)
4066 Sets the origin point for the transformation in item coordinates.
4067 This is equivalent to calling setTransformOriginPoint(QPointF(\a x, \a y)).
4069 \sa setTransformOriginPoint(), {Transformations}
4076 Use sceneTransform() instead.
4078 \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}
4080 QMatrix QGraphicsItem::sceneMatrix() const
4082 d_ptr->ensureSceneTransform();
4083 return d_ptr->sceneTransform.toAffine();
4090 Returns this item's scene transformation matrix. This matrix can be used
4091 to map coordinates and geometrical shapes from this item's local
4092 coordinate system to the scene's coordinate system. To map coordinates
4093 from the scene, you must first invert the returned matrix.
4097 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 4
4099 Unlike transform(), which returns only an item's local transformation, this
4100 function includes the item's (and any parents') position, and all the transfomation properties.
4102 \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}, {Transformations}
4104 QTransform QGraphicsItem::sceneTransform() const
4106 d_ptr->ensureSceneTransform();
4107 return d_ptr->sceneTransform;
4113 Returns this item's device transformation matrix, using \a
4114 viewportTransform to map from scene to device coordinates. This matrix can
4115 be used to map coordinates and geometrical shapes from this item's local
4116 coordinate system to the viewport's (or any device's) coordinate
4117 system. To map coordinates from the viewport, you must first invert the
4122 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 5
4124 This function is the same as combining this item's scene transform with
4125 the view's viewport transform, but it also understands the
4126 ItemIgnoresTransformations flag. The device transform can be used to do
4127 accurate coordinate mapping (and collision detection) for untransformable
4130 \sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate
4131 System}, itemTransform()
4133 QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) const
4135 // Ensure we return the standard transform if we're not untransformable.
4136 if (!d_ptr->itemIsUntransformable()) {
4137 d_ptr->ensureSceneTransform();
4138 return d_ptr->sceneTransform * viewportTransform;
4141 // Find the topmost item that ignores view transformations.
4142 const QGraphicsItem *untransformedAncestor = this;
4143 QList<const QGraphicsItem *> parents;
4144 while (untransformedAncestor && ((untransformedAncestor->d_ptr->ancestorFlags
4145 & QGraphicsItemPrivate::AncestorIgnoresTransformations))) {
4146 parents.prepend(untransformedAncestor);
4147 untransformedAncestor = untransformedAncestor->parentItem();
4150 if (!untransformedAncestor) {
4151 // Assert in debug mode, continue in release.
4152 Q_ASSERT_X(untransformedAncestor, "QGraphicsItem::deviceTransform",
4153 "Invalid object structure!");
4154 return QTransform();
4157 // First translate the base untransformable item.
4158 untransformedAncestor->d_ptr->ensureSceneTransform();
4159 QPointF mappedPoint = (untransformedAncestor->d_ptr->sceneTransform * viewportTransform).map(QPointF(0, 0));
4162 QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y());
4163 if (untransformedAncestor->d_ptr->transformData)
4164 matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform(&matrix);
4166 // Then transform and translate all children.
4167 for (int i = 0; i < parents.size(); ++i) {
4168 const QGraphicsItem *parent = parents.at(i);
4169 parent->d_ptr->combineTransformFromParent(&matrix);
4178 Returns a QTransform that maps coordinates from this item to \a other. If
4179 \a ok is not null, and if there is no such transform, the boolean pointed
4180 to by \a ok will be set to false; otherwise it will be set to true.
4182 This transform provides an alternative to the mapToItem() or mapFromItem()
4183 functions, by returning the appropriate transform so that you can map
4184 shapes and coordinates yourself. It also helps you write more efficient
4185 code when repeatedly mapping between the same two items.
4187 \note In rare circumstances, there is no transform that maps between two
4190 \sa mapToItem(), mapFromItem(), deviceTransform()
4192 QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) const
4194 // Catch simple cases first.
4196 qWarning("QGraphicsItem::itemTransform: null pointer passed");
4197 return QTransform();
4199 if (other == this) {
4202 return QTransform();
4205 QGraphicsItem *parent = d_ptr->parent;
4206 const QGraphicsItem *otherParent = other->d_ptr->parent;
4208 // This is other's child
4209 if (parent == other) {
4213 d_ptr->combineTransformFromParent(&x);
4217 // This is other's parent
4218 if (otherParent == this) {
4219 const QPointF &otherPos = other->d_ptr->pos;
4220 if (other->d_ptr->transformData) {
4221 QTransform otherToParent;
4222 other->d_ptr->combineTransformFromParent(&otherToParent);
4223 return otherToParent.inverted(ok);
4227 return QTransform::fromTranslate(-otherPos.x(), -otherPos.y());
4231 if (parent == otherParent) {
4233 const QPointF &itemPos = d_ptr->pos;
4234 const QPointF &otherPos = other->d_ptr->pos;
4235 if (!d_ptr->transformData && !other->d_ptr->transformData) {
4236 QPointF delta = itemPos - otherPos;
4239 return QTransform::fromTranslate(delta.x(), delta.y());
4242 QTransform itemToParent;
4243 d_ptr->combineTransformFromParent(&itemToParent);
4244 QTransform otherToParent;
4245 other->d_ptr->combineTransformFromParent(&otherToParent);
4246 return itemToParent * otherToParent.inverted(ok);
4249 // Find the closest common ancestor. If the two items don't share an
4250 // ancestor, then the only way is to combine their scene transforms.
4251 const QGraphicsItem *commonAncestor = commonAncestorItem(other);
4252 if (!commonAncestor) {
4253 d_ptr->ensureSceneTransform();
4254 other->d_ptr->ensureSceneTransform();
4255 return d_ptr->sceneTransform * other->d_ptr->sceneTransform.inverted(ok);
4258 // If the two items are cousins (in sibling branches), map both to the
4259 // common ancestor, and combine the two transforms.
4260 bool cousins = other != commonAncestor && this != commonAncestor;
4263 QTransform thisToScene = itemTransform(commonAncestor, &good);
4264 QTransform otherToScene(Qt::Uninitialized);
4266 otherToScene = other->itemTransform(commonAncestor, &good);
4270 return QTransform();
4272 return thisToScene * otherToScene.inverted(ok);
4275 // One is an ancestor of the other; walk the chain.
4276 bool parentOfOther = isAncestorOf(other);
4277 const QGraphicsItem *child = parentOfOther ? other : this;
4278 const QGraphicsItem *root = parentOfOther ? this : other;
4281 const QGraphicsItem *p = child;
4283 p->d_ptr.data()->combineTransformToParent(&x);
4284 } while ((p = p->d_ptr->parent) && p != root);
4286 return x.inverted(ok);
4295 Sets the item's affine transformation matrix. This is a subset or the
4296 item's full transformation matrix, and might not represent the item's full
4299 Use setTransform() instead.
4301 \sa transform(), {The Graphics View Coordinate System}
4303 void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
4305 if (!d_ptr->transformData)
4306 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4308 QTransform newTransform(combine ? QTransform(matrix) * d_ptr->transformData->transform : QTransform(matrix));
4309 if (d_ptr->transformData->transform == newTransform)
4312 // Update and set the new transformation.
4313 if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
4314 d_ptr->setTransformHelper(newTransform);
4318 // Notify the item that the transformation matrix is changing.
4319 const QVariant newMatrixVariant = QVariant::fromValue<QMatrix>(newTransform.toAffine());
4320 newTransform = QTransform(qvariant_cast<QMatrix>(itemChange(ItemMatrixChange, newMatrixVariant)));
4321 if (d_ptr->transformData->transform == newTransform)
4324 // Update and set the new transformation.
4325 d_ptr->setTransformHelper(newTransform);
4327 // Send post-notification.
4328 itemChange(ItemTransformHasChanged, QVariant::fromValue<QTransform>(newTransform));
4334 Sets the item's current transformation matrix to \a matrix.
4336 If \a combine is true, then \a matrix is combined with the current matrix;
4337 otherwise, \a matrix \e replaces the current matrix. \a combine is false
4340 To simplify interation with items using a transformed view, QGraphicsItem
4341 provides mapTo... and mapFrom... functions that can translate between
4342 items' and the scene's coordinates. For example, you can call mapToScene()
4343 to map an item coordiate to a scene coordinate, or mapFromScene() to map
4344 from scene coordinates to item coordinates.
4346 The transformation matrix is combined with the item's rotation(), scale()
4347 and transformations() into a combined transformation that maps the item's
4348 coordinate system to its parent.
4350 \sa transform(), setRotation(), setScale(), setTransformOriginPoint(), {The Graphics View Coordinate System}, {Transformations}
4352 void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
4354 if (!d_ptr->transformData)
4355 d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
4357 QTransform newTransform(combine ? matrix * d_ptr->transformData->transform : matrix);
4358 if (d_ptr->transformData->transform == newTransform)
4361 // Update and set the new transformation.
4362 if (!(d_ptr->flags & (ItemSendsGeometryChanges | ItemSendsScenePositionChanges))) {
4363 d_ptr->setTransformHelper(newTransform);
4364 if (d_ptr->scenePosDescendants)
4365 d_ptr->sendScenePosChange();
4369 // Notify the item that the transformation matrix is changing.
4370 const QVariant newTransformVariant(itemChange(ItemTransformChange,
4371 QVariant::fromValue<QTransform>(newTransform)));
4372 newTransform = qvariant_cast<QTransform>(newTransformVariant);
4373 if (d_ptr->transformData->transform == newTransform)
4376 // Update and set the new transformation.
4377 d_ptr->setTransformHelper(newTransform);
4379 // Send post-notification.
4380 itemChange(ItemTransformHasChanged, newTransformVariant);
4381 d_ptr->sendScenePosChange();
4387 Use resetTransform() instead.
4389 void QGraphicsItem::resetMatrix()
4397 Resets this item's transformation matrix to the identity matrix or
4398 all the transformation properties to their default values.
4399 This is equivalent to calling \c setTransform(QTransform()).
4401 \sa setTransform(), transform()
4403 void QGraphicsItem::resetTransform()
4405 setTransform(QTransform(), false);
4409 \fn void QGraphicsItem::rotate(qreal angle)
4415 setRotation(rotation() + angle);
4420 Rotates the current item transformation \a angle degrees clockwise around
4421 its origin. To translate around an arbitrary point (x, y), you need to
4422 combine translation and rotation with setTransform().
4426 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 6
4428 \sa setTransform(), transform(), scale(), shear(), translate()
4432 \fn void QGraphicsItem::scale(qreal sx, qreal sy)
4438 setTransform(QTransform::fromScale(sx, sy), true);
4443 Scales the current item transformation by (\a sx, \a sy) around its
4444 origin. To scale from an arbitrary point (x, y), you need to combine
4445 translation and scaling with setTransform().
4449 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 7
4451 \sa setTransform(), transform()
4455 \fn void QGraphicsItem::shear(qreal sh, qreal sv)
4461 setTransform(QTransform().shear(sh, sv), true);
4466 Shears the current item transformation by (\a sh, \a sv).
4468 \sa setTransform(), transform()
4472 \fn void QGraphicsItem::translate(qreal dx, qreal dy)
4475 Use setPos() or setTransformOriginPoint() instead. For identical
4479 setTransform(QTransform::fromTranslate(dx, dy), true);
4482 Translates the current item transformation by (\a dx, \a dy).
4484 If all you want is to move an item, you should call moveBy() or
4485 setPos() instead; this function changes the item's translation,
4486 which is conceptually separate from its position.
4488 \sa setTransform(), transform()
4492 This virtual function is called twice for all items by the
4493 QGraphicsScene::advance() slot. In the first phase, all items are called
4494 with \a phase == 0, indicating that items on the scene are about to
4495 advance, and then all items are called with \a phase == 1. Reimplement
4496 this function to update your item if you need simple scene-controlled
4499 The default implementation does nothing.
4501 This function is intended for animations. An alternative is to
4502 multiple-inherit from QObject and QGraphicsItem and use the \l{The Animation
4503 Framework}{Animation Framework}.
4505 \sa QGraphicsScene::advance(), QTimeLine
4507 void QGraphicsItem::advance(int phase)
4513 Returns the Z-value of the item. The Z-value affects the stacking order of
4514 sibling (neighboring) items.
4516 The default Z-value is 0.
4518 \sa setZValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
4520 qreal QGraphicsItem::zValue() const
4526 Sets the Z-value of the item to \a z. The Z value decides the stacking
4527 order of sibling (neighboring) items. A sibling item of high Z value will
4528 always be drawn on top of another sibling item with a lower Z value.
4530 If you restore the Z value, the item's insertion order will decide its
4533 The Z-value does not affect the item's size in any way.
4535 The default Z-value is 0.
4537 \sa zValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
4539 void QGraphicsItem::setZValue(qreal z)
4541 const QVariant newZVariant(itemChange(ItemZValueChange, z));
4542 qreal newZ = newZVariant.toReal();
4543 if (newZ == d_ptr->z)
4546 if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) {
4547 // Z Value has changed, we have to notify the index.
4548 d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ);
4553 d_ptr->parent->d_ptr->needSortChildren = 1;
4554 else if (d_ptr->scene)
4555 d_ptr->scene->d_func()->needSortTopLevelItems = 1;
4558 d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
4560 itemChange(ItemZValueHasChanged, newZVariant);
4562 if (d_ptr->flags & ItemNegativeZStacksBehindParent)
4563 setFlag(QGraphicsItem::ItemStacksBehindParent, z < qreal(0.0));
4565 if (d_ptr->isObject)
4566 emit static_cast<QGraphicsObject *>(this)->zChanged();
4572 Ensures that the list of children is sorted by insertion order, and that
4573 the siblingIndexes are packed (no gaps), and start at 0.
4575 ### This function is almost identical to
4576 QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes().
4578 void QGraphicsItemPrivate::ensureSequentialSiblingIndex()
4580 if (!sequentialOrdering) {
4581 std::sort(children.begin(), children.end(), insertionOrder);
4582 sequentialOrdering = 1;
4583 needSortChildren = 1;
4585 if (holesInSiblingIndex) {
4586 holesInSiblingIndex = 0;
4587 for (int i = 0; i < children.size(); ++i)
4588 children[i]->d_ptr->siblingIndex = i;
4595 inline void QGraphicsItemPrivate::sendScenePosChange()
4599 if (flags & QGraphicsItem::ItemSendsScenePositionChanges)
4600 q->itemChange(QGraphicsItem::ItemScenePositionHasChanged, q->scenePos());
4601 if (scenePosDescendants) {
4602 foreach (QGraphicsItem *item, scene->d_func()->scenePosItems) {
4603 if (q->isAncestorOf(item))
4604 item->itemChange(QGraphicsItem::ItemScenePositionHasChanged, item->scenePos());
4613 Stacks this item before \a sibling, which must be a sibling item (i.e., the
4614 two items must share the same parent item, or must both be toplevel items).
4615 The \a sibling must have the same Z value as this item, otherwise calling
4616 this function will have no effect.
4618 By default, all sibling items are stacked by insertion order (i.e., the
4619 first item you add is drawn before the next item you add). If two items' Z
4620 values are different, then the item with the highest Z value is drawn on
4621 top. When the Z values are the same, the insertion order will decide the
4624 \sa setZValue(), ItemStacksBehindParent, {QGraphicsItem#Sorting}{Sorting}
4626 void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
4628 if (sibling == this)
4630 if (!sibling || d_ptr->parent != sibling->parentItem()) {
4631 qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
4634 QList<QGraphicsItem *> *siblings = d_ptr->parent
4635 ? &d_ptr->parent->d_ptr->children
4636 : (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0);
4638 qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
4642 // First, make sure that the sibling indexes have no holes. This also
4643 // marks the children list for sorting.
4645 d_ptr->parent->d_ptr->ensureSequentialSiblingIndex();
4647 d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
4649 // Only move items with the same Z value, and that need moving.
4650 int siblingIndex = sibling->d_ptr->siblingIndex;
4651 int myIndex = d_ptr->siblingIndex;
4652 if (myIndex >= siblingIndex) {
4653 siblings->move(myIndex, siblingIndex);
4654 // Fixup the insertion ordering.
4655 for (int i = 0; i < siblings->size(); ++i) {
4656 int &index = siblings->at(i)->d_ptr->siblingIndex;
4657 if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
4660 d_ptr->siblingIndex = siblingIndex;
4661 for (int i = 0; i < siblings->size(); ++i) {
4662 int &index = siblings->at(i)->d_ptr->siblingIndex;
4663 if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
4664 siblings->at(i)->d_ptr->siblingOrderChange();
4666 d_ptr->siblingOrderChange();
4671 Returns the bounding rect of this item's descendants (i.e., its
4672 children, their children, etc.) in local coordinates. The
4673 rectangle will contain all descendants after they have been mapped
4674 to local coordinates. If the item has no children, this function
4675 returns an empty QRectF.
4677 This does not include this item's own bounding rect; it only returns
4678 its descendants' accumulated bounding rect. If you need to include this
4679 item's bounding rect, you can add boundingRect() to childrenBoundingRect()
4680 using QRectF::operator|().
4682 This function is linear in complexity; it determines the size of the
4683 returned bounding rect by iterating through all descendants.
4685 \sa boundingRect(), sceneBoundingRect()
4687 QRectF QGraphicsItem::childrenBoundingRect() const
4689 if (!d_ptr->dirtyChildrenBoundingRect)
4690 return d_ptr->childrenBoundingRect;
4692 d_ptr->childrenBoundingRect = QRectF();
4693 d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect, 0);
4694 d_ptr->dirtyChildrenBoundingRect = 0;
4695 return d_ptr->childrenBoundingRect;
4699 \fn virtual QRectF QGraphicsItem::boundingRect() const = 0
4701 This pure virtual function defines the outer bounds of the item as
4702 a rectangle; all painting must be restricted to inside an item's
4703 bounding rect. QGraphicsView uses this to determine whether the
4704 item requires redrawing.
4706 Although the item's shape can be arbitrary, the bounding rect is
4707 always rectangular, and it is unaffected by the items'
4710 If you want to change the item's bounding rectangle, you must first call
4711 prepareGeometryChange(). This notifies the scene of the imminent change,
4712 so that its can update its item geometry index; otherwise, the scene will
4713 be unaware of the item's new geometry, and the results are undefined
4714 (typically, rendering artifacts are left around in the view).
4716 Reimplement this function to let QGraphicsView determine what
4717 parts of the widget, if any, need to be redrawn.
4719 Note: For shapes that paint an outline / stroke, it is important
4720 to include half the pen width in the bounding rect. It is not
4721 necessary to compensate for antialiasing, though.
4725 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 8
4727 \sa boundingRegion(), shape(), contains(), {The Graphics View Coordinate
4728 System}, prepareGeometryChange()
4732 Returns the bounding rect of this item in scene coordinates, by combining
4733 sceneTransform() with boundingRect().
4735 \sa boundingRect(), {The Graphics View Coordinate System}
4737 QRectF QGraphicsItem::sceneBoundingRect() const
4739 // Find translate-only offset
4742 const QGraphicsItem *parentItem = this;
4743 const QGraphicsItemPrivate *itemd;
4745 itemd = parentItem->d_ptr.data();
4746 if (itemd->transformData)
4748 offset += itemd->pos;
4749 } while ((parentItem = itemd->parent));
4751 QRectF br = boundingRect();
4752 br.translate(offset);
4755 if (parentItem->d_ptr->hasTranslateOnlySceneTransform()) {
4756 br.translate(parentItem->d_ptr->sceneTransform.dx(), parentItem->d_ptr->sceneTransform.dy());
4759 return parentItem->d_ptr->sceneTransform.mapRect(br);
4763 Returns the shape of this item as a QPainterPath in local
4764 coordinates. The shape is used for many things, including collision
4765 detection, hit tests, and for the QGraphicsScene::items() functions.
4767 The default implementation calls boundingRect() to return a simple
4768 rectangular shape, but subclasses can reimplement this function to return
4769 a more accurate shape for non-rectangular items. For example, a round item
4770 may choose to return an elliptic shape for better collision detection. For
4773 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 9
4775 The outline of a shape can vary depending on the width and style of the
4776 pen used when drawing. If you want to include this outline in the item's
4777 shape, you can create a shape from the stroke using QPainterPathStroker.
4779 This function is called by the default implementations of contains() and
4782 \sa boundingRect(), contains(), prepareGeometryChange(), QPainterPathStroker
4784 QPainterPath QGraphicsItem::shape() const
4787 path.addRect(boundingRect());
4792 Returns true if this item is clipped. An item is clipped if it has either
4793 set the \l ItemClipsToShape flag, or if it or any of its ancestors has set
4794 the \l ItemClipsChildrenToShape flag.
4796 Clipping affects the item's appearance (i.e., painting), as well as mouse
4797 and hover event delivery.
4799 \sa clipPath(), shape(), setFlags()
4801 bool QGraphicsItem::isClipped() const
4803 Q_D(const QGraphicsItem);
4804 return (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
4805 || (d->flags & QGraphicsItem::ItemClipsToShape);
4811 Returns this item's clip path, or an empty QPainterPath if this item is
4812 not clipped. The clip path constrains the item's appearance and
4813 interaction (i.e., restricts the area the item can draw, and it also
4814 restricts the area that the item receives events).
4816 You can enable clipping by setting the ItemClipsToShape or
4817 ItemClipsChildrenToShape flags. The item's clip path is calculated by
4818 intersecting all clipping ancestors' shapes. If the item sets
4819 ItemClipsToShape, the final clip is intersected with the item's own shape.
4821 \note Clipping introduces a performance penalty for all items involved;
4822 you should generally avoid using clipping if you can (e.g., if your items
4823 always draw inside boundingRect() or shape() boundaries, clipping is not
4826 \sa isClipped(), shape(), setFlags()
4828 QPainterPath QGraphicsItem::clipPath() const
4830 Q_D(const QGraphicsItem);
4832 return QPainterPath();
4834 const QRectF thisBoundingRect(boundingRect());
4835 if (thisBoundingRect.isEmpty())
4836 return QPainterPath();
4839 // Start with the item's bounding rect.
4840 clip.addRect(thisBoundingRect);
4842 if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
4843 const QGraphicsItem *parent = this;
4844 const QGraphicsItem *lastParent = this;
4846 // Intersect any in-between clips starting at the top and moving downwards.
4847 while ((parent = parent->d_ptr->parent)) {
4848 if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
4849 // Map clip to the current parent and intersect with its shape/clipPath
4850 clip = lastParent->itemTransform(parent).map(clip);
4851 clip = clip.intersected(parent->shape());
4854 lastParent = parent;
4857 if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
4861 if (lastParent != this) {
4862 // Map clip back to the item's transform.
4863 // ### what if itemtransform fails
4864 clip = lastParent->itemTransform(this).map(clip);
4868 if (d->flags & ItemClipsToShape)
4869 clip = clip.intersected(shape());
4875 Returns true if this item contains \a point, which is in local
4876 coordinates; otherwise, false is returned. It is most often called from
4877 QGraphicsView to determine what item is under the cursor, and for that
4878 reason, the implementation of this function should be as light-weight as
4881 By default, this function calls shape(), but you can reimplement it in a
4882 subclass to provide a (perhaps more efficient) implementation.
4884 \sa shape(), boundingRect(), collidesWithPath()
4886 bool QGraphicsItem::contains(const QPointF &point) const
4888 return isClipped() ? clipPath().contains(point) : shape().contains(point);
4893 Returns true if this item collides with \a other; otherwise
4896 The \a mode is applied to \a other, and the resulting shape or
4897 bounding rectangle is then compared to this item's shape. The
4898 default value for \a mode is Qt::IntersectsItemShape; \a other
4899 collides with this item if it either intersects, contains, or is
4900 contained by this item's shape (see Qt::ItemSelectionMode for
4903 The default implementation is based on shape intersection, and it calls
4904 shape() on both items. Because the complexity of arbitrary shape-shape
4905 intersection grows with an order of magnitude when the shapes are complex,
4906 this operation can be noticably time consuming. You have the option of
4907 reimplementing this function in a subclass of QGraphicsItem to provide a
4908 custom algorithm. This allows you to make use of natural constraints in
4909 the shapes of your own items, in order to improve the performance of the
4910 collision detection. For instance, two untransformed perfectly circular
4911 items' collision can be determined very efficiently by comparing their
4912 positions and radii.
4914 Keep in mind that when reimplementing this function and calling shape() or
4915 boundingRect() on \a other, the returned coordinates must be mapped to
4916 this item's coordinate system before any intersection can take place.
4918 \sa contains(), shape()
4920 bool QGraphicsItem::collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode) const
4926 // The items share the same clip if their closest clipper is the same, or
4927 // if one clips the other.
4928 bool clips = (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
4929 bool otherClips = (other->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
4930 if (clips || otherClips) {
4931 const QGraphicsItem *closestClipper = isAncestorOf(other) ? this : parentItem();
4932 while (closestClipper && !(closestClipper->flags() & ItemClipsChildrenToShape))
4933 closestClipper = closestClipper->parentItem();
4934 const QGraphicsItem *otherClosestClipper = other->isAncestorOf(this) ? other : other->parentItem();
4935 while (otherClosestClipper && !(otherClosestClipper->flags() & ItemClipsChildrenToShape))
4936 otherClosestClipper = otherClosestClipper->parentItem();
4937 if (closestClipper == otherClosestClipper) {
4938 d_ptr->localCollisionHack = 1;
4939 bool res = collidesWithPath(mapFromItem(other, other->shape()), mode);
4940 d_ptr->localCollisionHack = 0;
4945 QPainterPath otherShape = other->isClipped() ? other->clipPath() : other->shape();
4946 return collidesWithPath(mapFromItem(other, otherShape), mode);
4950 Returns true if this item collides with \a path.
4952 The collision is determined by \a mode. The default value for \a mode is
4953 Qt::IntersectsItemShape; \a path collides with this item if it either
4954 intersects, contains, or is contained by this item's shape.
4956 Note that this function checks whether the item's shape or
4957 bounding rectangle (depending on \a mode) is contained within \a
4958 path, and not whether \a path is contained within the items shape
4959 or bounding rectangle.
4961 \sa collidesWithItem(), contains(), shape()
4963 bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelectionMode mode) const
4965 if (path.isEmpty()) {
4966 // No collision with empty paths.
4970 QRectF rectA(boundingRect());
4971 _q_adjustRect(&rectA);
4972 QRectF rectB(path.controlPointRect());
4973 _q_adjustRect(&rectB);
4974 if (!rectA.intersects(rectB)) {
4975 // This we can determine efficiently. If the two rects neither
4976 // intersect nor contain eachother, then the two items do not collide.
4980 // For further testing, we need this item's shape or bounding rect.
4981 QPainterPath thisShape;
4982 if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape)
4983 thisShape = (isClipped() && !d_ptr->localCollisionHack) ? clipPath() : shape();
4985 thisShape.addRect(rectA);
4987 if (thisShape == QPainterPath()) {
4988 // Empty shape? No collision.
4992 // Use QPainterPath boolean operations to determine the collision, O(N*logN).
4993 if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
4994 return path.intersects(thisShape);
4995 return path.contains(thisShape);
4999 Returns a list of all items that collide with this item.
5001 The way collisions are detected is determined by applying \a mode
5002 to items that are compared to this item, i.e., each item's shape
5003 or bounding rectangle is checked against this item's shape. The
5004 default value for \a mode is Qt::IntersectsItemShape.
5006 \sa collidesWithItem()
5008 QList<QGraphicsItem *> QGraphicsItem::collidingItems(Qt::ItemSelectionMode mode) const
5011 return d_ptr->scene->collidingItems(this, mode);
5012 return QList<QGraphicsItem *>();
5018 Item obscurity helper function.
5020 Returns true if the subrect \a rect of \a item's bounding rect is obscured
5021 by \a other (i.e., \a other's opaque area covers \a item's \a rect
5022 completely. \a other is assumed to already be "on top of" \a item
5023 wrt. stacking order.
5025 static bool qt_QGraphicsItem_isObscured(const QGraphicsItem *item,
5026 const QGraphicsItem *other,
5029 return other->mapToItem(item, other->opaqueArea()).contains(rect);
5036 Returns true if \a rect is completely obscured by the opaque shape of any
5037 of colliding items above it (i.e., with a higher Z value than this item).
5041 bool QGraphicsItem::isObscured(const QRectF &rect) const
5043 Q_D(const QGraphicsItem);
5047 QRectF br = boundingRect();
5048 QRectF testRect = rect.isNull() ? br : rect;
5050 foreach (QGraphicsItem *item, d->scene->items(mapToScene(br), Qt::IntersectsItemBoundingRect)) {
5053 if (qt_QGraphicsItem_isObscured(this, item, testRect))
5060 \fn bool QGraphicsItem::isObscured(qreal x, qreal y, qreal w, qreal h) const
5064 This convenience function is equivalent to calling isObscured(QRectF(\a x, \a y, \a w, \a h)).
5068 Returns true if this item's bounding rect is completely obscured by the
5069 opaque shape of \a item.
5071 The base implementation maps \a item's opaqueArea() to this item's
5072 coordinate system, and then checks if this item's boundingRect() is fully
5073 contained within the mapped shape.
5075 You can reimplement this function to provide a custom algorithm for
5076 determining whether this item is obscured by \a item.
5078 \sa opaqueArea(), isObscured()
5080 bool QGraphicsItem::isObscuredBy(const QGraphicsItem *item) const
5084 return qt_closestItemFirst(item, this)
5085 && qt_QGraphicsItem_isObscured(this, item, boundingRect());
5089 This virtual function returns a shape representing the area where this
5090 item is opaque. An area is opaque if it is filled using an opaque brush or
5091 color (i.e., not transparent).
5093 This function is used by isObscuredBy(), which is called by underlying
5094 items to determine if they are obscured by this item.
5096 The default implementation returns an empty QPainterPath, indicating that
5097 this item is completely transparent and does not obscure any other items.
5099 \sa isObscuredBy(), isObscured(), shape()
5101 QPainterPath QGraphicsItem::opaqueArea() const
5103 return QPainterPath();
5109 Returns the bounding region for this item. The coordinate space of the
5110 returned region depends on \a itemToDeviceTransform. If you pass an
5111 identity QTransform as a parameter, this function will return a local
5114 The bounding region describes a coarse outline of the item's visual
5115 contents. Although it's expensive to calculate, it's also more precise
5116 than boundingRect(), and it can help to avoid unnecessary repainting when
5117 an item is updated. This is particularly efficient for thin items (e.g.,
5118 lines or simple polygons). You can tune the granularity for the bounding
5119 region by calling setBoundingRegionGranularity(). The default granularity
5120 is 0; in which the item's bounding region is the same as its bounding
5123 \a itemToDeviceTransform is the transformation from item coordinates to
5124 device coordinates. If you want this function to return a QRegion in scene
5125 coordinates, you can pass sceneTransform() as an argument.
5127 \sa boundingRegionGranularity()
5129 QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) const
5131 // ### Ideally we would have a better way to generate this region,
5132 // preferably something in the lines of QPainterPath::toRegion(QTransform)
5133 // coupled with a way to generate a painter path from a set of painter
5134 // operations (e.g., QPicture::toPainterPath() or so). The current
5135 // approach generates a bitmap with the size of the item's bounding rect
5136 // in device coordinates, scaled by b.r.granularity, then paints the item
5137 // into the bitmap, converts the result to a QRegion and scales the region
5138 // back to device space with inverse granularity.
5139 qreal granularity = boundingRegionGranularity();
5140 QRect deviceRect = itemToDeviceTransform.mapRect(boundingRect()).toRect();
5141 _q_adjustRect(&deviceRect);
5142 if (granularity == 0.0)
5143 return QRegion(deviceRect);
5146 QSize bitmapSize(qMax(1, int(deviceRect.width() * granularity) + pad * 2),
5147 qMax(1, int(deviceRect.height() * granularity) + pad * 2));
5148 QImage mask(bitmapSize, QImage::Format_ARGB32_Premultiplied);
5151 p.setRenderHints(QPainter::Antialiasing);
5153 // Transform painter (### this code is from QGraphicsScene::drawItemHelper
5154 // and doesn't work properly with perspective transformations).
5155 QPointF viewOrigo = itemToDeviceTransform.map(QPointF(0, 0));
5156 QPointF offset = viewOrigo - deviceRect.topLeft();
5157 p.scale(granularity, granularity);
5158 p.translate(offset);
5159 p.translate(pad, pad);
5160 p.setWorldTransform(itemToDeviceTransform, true);
5161 p.translate(itemToDeviceTransform.inverted().map(QPointF(0, 0)));
5164 QStyleOptionGraphicsItem option;
5165 const_cast<QGraphicsItem *>(this)->paint(&p, &option, 0);
5168 // Transform QRegion back to device space
5169 QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity);
5171 QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0));
5172 foreach (const QRect &rect, QRegion( colorMask ).rects()) {
5173 QRect xrect = unscale.mapRect(rect).translated(deviceRect.topLeft() - QPoint(pad, pad));
5174 r += xrect.adjusted(-1, -1, 1, 1) & deviceRect;
5182 Returns the item's bounding region granularity; a value between and
5183 including 0 and 1. The default value is 0 (i.e., the lowest granularity,
5184 where the bounding region corresponds to the item's bounding rectangle).
5190 \sa setBoundingRegionGranularity()
5192 qreal QGraphicsItem::boundingRegionGranularity() const
5194 return d_ptr->hasBoundingRegionGranularity
5195 ? qvariant_cast<qreal>(d_ptr->extra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity))
5201 Sets the bounding region granularity to \a granularity; a value between
5202 and including 0 and 1. The default value is 0 (i.e., the lowest
5203 granularity, where the bounding region corresponds to the item's bounding
5206 The granularity is used by boundingRegion() to calculate how fine the
5207 bounding region of the item should be. The highest achievable granularity
5208 is 1, where boundingRegion() will return the finest outline possible for
5209 the respective device (e.g., for a QGraphicsView viewport, this gives you
5210 a pixel-perfect bounding region). The lowest possible granularity is
5211 0. The value of \a granularity describes the ratio between device
5212 resolution and the resolution of the bounding region (e.g., a value of
5213 0.25 will provide a region where each chunk corresponds to 4x4 device
5216 \sa boundingRegionGranularity()
5218 void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
5220 if (granularity < 0.0 || granularity > 1.0) {
5221 qWarning("QGraphicsItem::setBoundingRegionGranularity: invalid granularity %g", granularity);
5224 if (granularity == 0.0) {
5225 d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity);
5226 d_ptr->hasBoundingRegionGranularity = 0;
5229 d_ptr->hasBoundingRegionGranularity = 1;
5230 d_ptr->setExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity,
5231 QVariant::fromValue<qreal>(granularity));
5235 \fn virtual void QGraphicsItem::paint(QPainter *painter, const
5236 QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0
5238 This function, which is usually called by QGraphicsView, paints the
5239 contents of an item in local coordinates.
5241 Reimplement this function in a QGraphicsItem subclass to provide the
5242 item's painting implementation, using \a painter. The \a option parameter
5243 provides style options for the item, such as its state, exposed area and
5244 its level-of-detail hints. The \a widget argument is optional. If
5245 provided, it points to the widget that is being painted on; otherwise, it
5246 is 0. For cached painting, \a widget is always 0.
5248 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 10
5250 The painter's pen is 0-width by default, and its pen is initialized to the
5251 QPalette::Text brush from the paint device's palette. The brush is
5252 initialized to QPalette::Window.
5254 Make sure to constrain all painting inside the boundaries of
5255 boundingRect() to avoid rendering artifacts (as QGraphicsView does not
5256 clip the painter for you). In particular, when QPainter renders the
5257 outline of a shape using an assigned QPen, half of the outline will be
5258 drawn outside, and half inside, the shape you're rendering (e.g., with a
5259 pen width of 2 units, you must draw outlines 1 unit inside
5260 boundingRect()). QGraphicsItem does not support use of cosmetic pens with
5263 All painting is done in local coordinates.
5265 \sa setCacheMode(), QPen::width(), {Item Coordinates}, ItemUsesExtendedStyleOption
5270 Returns true if we can discard an update request; otherwise false.
5272 bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreVisibleBit, bool ignoreDirtyBit,
5273 bool ignoreOpacity) const
5275 // No scene, or if the scene is updating everything, means we have nothing
5276 // to do. The only exception is if the scene tracks the growing scene rect.
5278 || (!visible && !ignoreVisibleBit && !this->ignoreVisible)
5279 || (!ignoreDirtyBit && fullUpdatePending)
5280 || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent());
5286 int QGraphicsItemPrivate::depth() const
5288 if (itemDepth == -1)
5289 const_cast<QGraphicsItemPrivate *>(this)->resolveDepth();
5297 #ifndef QT_NO_GRAPHICSEFFECT
5298 void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively()
5300 QGraphicsItemPrivate *itemPrivate = this;
5302 if (itemPrivate->graphicsEffect) {
5303 itemPrivate->notifyInvalidated = 1;
5305 if (!itemPrivate->updateDueToGraphicsEffect)
5306 static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
5308 } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
5311 void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason)
5313 if (!mayHaveChildWithGraphicsEffect)
5316 for (int i = 0; i < children.size(); ++i) {
5317 QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data();
5318 if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity))
5320 if (childPrivate->graphicsEffect) {
5321 childPrivate->notifyInvalidated = 1;
5322 static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
5325 childPrivate->invalidateChildGraphicsEffectsRecursively(reason);
5328 #endif //QT_NO_GRAPHICSEFFECT
5333 void QGraphicsItemPrivate::invalidateDepthRecursively()
5335 if (itemDepth == -1)
5339 for (int i = 0; i < children.size(); ++i)
5340 children.at(i)->d_ptr->invalidateDepthRecursively();
5346 Resolves the stacking depth of this object and all its ancestors.
5348 void QGraphicsItemPrivate::resolveDepth()
5353 if (parent->d_ptr->itemDepth == -1)
5354 parent->d_ptr->resolveDepth();
5355 itemDepth = parent->d_ptr->itemDepth + 1;
5362 ### This function is almost identical to
5363 QGraphicsScenePrivate::registerTopLevelItem().
5365 void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
5367 // Remove all holes from the sibling index list. Now the max index
5368 // number is equal to the size of the children list.
5369 ensureSequentialSiblingIndex();
5370 needSortChildren = 1; // ### maybe 0
5371 child->d_ptr->siblingIndex = children.size();
5372 children.append(child);
5374 emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
5380 ### This function is almost identical to
5381 QGraphicsScenePrivate::unregisterTopLevelItem().
5383 void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
5385 // When removing elements in the middle of the children list,
5386 // there will be a "gap" in the list of sibling indexes (0,1,3,4).
5387 if (!holesInSiblingIndex)
5388 holesInSiblingIndex = child->d_ptr->siblingIndex != children.size() - 1;
5389 if (sequentialOrdering && !holesInSiblingIndex)
5390 children.removeAt(child->d_ptr->siblingIndex);
5392 children.removeOne(child);
5393 // NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
5394 // the child is not guaranteed to be at the index after the list is sorted.
5395 // (see ensureSortedChildren()).
5396 child->d_ptr->siblingIndex = -1;
5398 emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
5404 QGraphicsItemCache *QGraphicsItemPrivate::maybeExtraItemCache() const
5406 return (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5412 QGraphicsItemCache *QGraphicsItemPrivate::extraItemCache() const
5414 QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5416 QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this);
5417 c = new QGraphicsItemCache;
5418 that->setExtra(ExtraCacheData, QVariant::fromValue<void *>(c));
5426 void QGraphicsItemPrivate::removeExtraItemCache()
5428 QGraphicsItemCache *c = (QGraphicsItemCache *)qvariant_cast<void *>(extra(ExtraCacheData));
5433 unsetExtra(ExtraCacheData);
5436 void QGraphicsItemPrivate::updatePaintedViewBoundingRects(bool updateChildren)
5441 for (int i = 0; i < scene->d_func()->views.size(); ++i) {
5442 QGraphicsViewPrivate *viewPrivate = scene->d_func()->views.at(i)->d_func();
5443 QRect rect = paintedViewBoundingRects.value(viewPrivate->viewport);
5444 rect.translate(viewPrivate->dirtyScrollOffset);
5445 viewPrivate->updateRect(rect);
5448 if (updateChildren) {
5449 for (int i = 0; i < children.size(); ++i)
5450 children.at(i)->d_ptr->updatePaintedViewBoundingRects(true);
5454 // Traverses all the ancestors up to the top-level and updates the pointer to
5455 // always point to the top-most item that has a dirty scene transform.
5456 // It then backtracks to the top-most dirty item and start calculating the
5457 // scene transform by combining the item's transform (+pos) with the parent's
5458 // cached scene transform (which we at this point know for sure is valid).
5459 void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem)
5461 Q_ASSERT(topMostDirtyItem);
5463 if (dirtySceneTransform)
5464 *topMostDirtyItem = q_ptr;
5467 parent->d_ptr->ensureSceneTransformRecursive(topMostDirtyItem);
5469 if (*topMostDirtyItem == q_ptr) {
5470 if (!dirtySceneTransform)
5471 return; // OK, neither my ancestors nor I have dirty scene transforms.
5472 *topMostDirtyItem = 0;
5473 } else if (*topMostDirtyItem) {
5474 return; // Continue backtrack.
5477 // This item and all its descendants have dirty scene transforms.
5478 // We're about to validate this item's scene transform, so we have to
5479 // invalidate all the children; otherwise there's no way for the descendants
5480 // to detect that the ancestor has changed.
5481 invalidateChildrenSceneTransform();
5483 // COMBINE my transform with the parent's scene transform.
5484 updateSceneTransformFromParent();
5485 Q_ASSERT(!dirtySceneTransform);
5491 void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
5493 // Update focus child chain. Stop at panels, or if this item
5494 // is hidden, stop at the first item with a visible parent.
5495 QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
5496 if (parent->panel() != q_ptr->panel())
5500 // Clear any existing ancestor's subFocusItem.
5501 if (parent != q_ptr && parent->d_ptr->subFocusItem) {
5502 if (parent->d_ptr->subFocusItem == q_ptr)
5504 parent->d_ptr->subFocusItem->d_ptr->clearSubFocus(0, stopItem);
5506 parent->d_ptr->subFocusItem = q_ptr;
5507 parent->d_ptr->subFocusItemChange();
5508 } while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
5510 if (scene && !scene->isActive()) {
5511 scene->d_func()->passiveFocusItem = subFocusItem;
5512 scene->d_func()->lastFocusItem = subFocusItem;
5519 void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem, QGraphicsItem *stopItem)
5521 // Reset sub focus chain.
5522 QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
5524 if (parent->d_ptr->subFocusItem != q_ptr)
5526 parent->d_ptr->subFocusItem = 0;
5527 if (parent != stopItem && !parent->isAncestorOf(stopItem))
5528 parent->d_ptr->subFocusItemChange();
5529 } while (!parent->isPanel() && (parent = parent->d_ptr->parent));
5535 Sets the focusProxy pointer to 0 for all items that have this item as their
5538 void QGraphicsItemPrivate::resetFocusProxy()
5540 for (int i = 0; i < focusProxyRefs.size(); ++i)
5541 *focusProxyRefs.at(i) = 0;
5542 focusProxyRefs.clear();
5548 Subclasses can reimplement this function to be notified when subFocusItem
5551 void QGraphicsItemPrivate::subFocusItemChange()
5558 Subclasses can reimplement this function to be notified when an item
5559 becomes a focusScopeItem (or is no longer a focusScopeItem).
5561 void QGraphicsItemPrivate::focusScopeItemChange(bool isSubFocusItem)
5563 Q_UNUSED(isSubFocusItem);
5569 Subclasses can reimplement this function to be notified when its
5570 siblingIndex order is changed.
5572 void QGraphicsItemPrivate::siblingOrderChange()
5579 Tells us if it is a proxy widget
5581 bool QGraphicsItemPrivate::isProxyWidget() const
5587 Schedules a redraw of the area covered by \a rect in this item. You can
5588 call this function whenever your item needs to be redrawn, such as if it
5589 changes appearance or size.
5591 This function does not cause an immediate paint; instead it schedules a
5592 paint request that is processed by QGraphicsView after control reaches the
5593 event loop. The item will only be redrawn if it is visible in any
5596 As a side effect of the item being repainted, other items that overlap the
5597 area \a rect may also be repainted.
5599 If the item is invisible (i.e., isVisible() returns false), this function
5602 \sa paint(), boundingRect()
5604 void QGraphicsItem::update(const QRectF &rect)
5606 if (rect.isEmpty() && !rect.isNull())
5609 // Make sure we notify effects about invalidated source.
5610 #ifndef QT_NO_GRAPHICSEFFECT
5611 d_ptr->invalidateParentGraphicsEffectsRecursively();
5612 #endif //QT_NO_GRAPHICSEFFECT
5614 if (CacheMode(d_ptr->cacheMode) != NoCache) {
5615 // Invalidate cache.
5616 QGraphicsItemCache *cache = d_ptr->extraItemCache();
5617 if (!cache->allExposed) {
5618 if (rect.isNull()) {
5619 cache->allExposed = true;
5620 cache->exposed.clear();
5622 cache->exposed.append(rect);
5625 // Only invalidate cache; item is already dirty.
5626 if (d_ptr->fullUpdatePending)
5631 d_ptr->scene->d_func()->markDirty(this, rect);
5636 Scrolls the contents of \a rect by \a dx, \a dy. If \a rect is a null rect
5637 (the default), the item's bounding rect is scrolled.
5639 Scrolling provides a fast alternative to simply redrawing when the
5640 contents of the item (or parts of the item) are shifted vertically or
5641 horizontally. Depending on the current transformation and the capabilities
5642 of the paint device (i.e., the viewport), this operation may consist of
5643 simply moving pixels from one location to another using memmove(). In most
5644 cases this is faster than rerendering the entire area.
5646 After scrolling, the item will issue an update for the newly exposed
5647 areas. If scrolling is not supported (e.g., you are rendering to an OpenGL
5648 viewport, which does not benefit from scroll optimizations), this function
5649 is equivalent to calling update(\a rect).
5651 \b{Note:} Scrolling is only supported when QGraphicsItem::ItemCoordinateCache
5652 is enabled; in all other cases calling this function is equivalent to calling
5653 update(\a rect). If you for sure know that the item is opaque and not overlapped
5654 by other items, you can map the \a rect to viewport coordinates and scroll the
5657 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 19
5661 void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
5664 if (dx == 0.0 && dy == 0.0)
5669 // Accelerated scrolling means moving pixels from one location to another
5670 // and only redraw the newly exposed area. The following requirements must
5671 // be fulfilled in order to do that:
5673 // 1) Item is opaque.
5674 // 2) Item is not overlapped by other items.
5676 // There's (yet) no way to detect whether an item is opaque or not, which means
5677 // we cannot do accelerated scrolling unless the cache is enabled. In case of using
5678 // DeviceCoordinate cache we also have to take the device transform into account in
5679 // order to determine whether we can do accelerated scrolling or not. That's left out
5680 // for simplicity here, but it is definitely something we can consider in the future
5681 // as a performance improvement.
5682 if (d->cacheMode != QGraphicsItem::ItemCoordinateCache
5683 || !qFuzzyIsNull(dx - int(dx)) || !qFuzzyIsNull(dy - int(dy))) {
5688 QGraphicsItemCache *cache = d->extraItemCache();
5689 if (cache->allExposed || cache->fixedSize.isValid()) {
5690 // Cache is either invalidated or item is scaled (see QGraphicsItem::setCacheMode).
5695 // Find pixmap in cache.
5696 QPixmap cachedPixmap;
5697 if (!QPixmapCache::find(cache->key, &cachedPixmap)) {
5702 QRect scrollRect = (rect.isNull() ? boundingRect() : rect).toAlignedRect();
5703 if (!scrollRect.intersects(cache->boundingRect))
5704 return; // Nothing to scroll.
5706 // Remove from cache to avoid deep copy when modifying.
5707 QPixmapCache::remove(cache->key);
5710 cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed);
5712 // Reinsert into cache.
5713 cache->key = QPixmapCache::insert(cachedPixmap);
5715 // Translate the existing expose.
5716 for (int i = 0; i < cache->exposed.size(); ++i) {
5717 QRectF &e = cache->exposed[i];
5718 if (!rect.isNull() && !e.intersects(rect))
5720 e.translate(dx, dy);
5723 // Append newly exposed areas. Note that the exposed region is currently
5724 // in pixmap coordinates, so we have to translate it to item coordinates.
5725 exposed.translate(cache->boundingRect.topLeft());
5726 const QVector<QRect> exposedRects = exposed.rects();
5727 for (int i = 0; i < exposedRects.size(); ++i)
5728 cache->exposed += exposedRects.at(i);
5730 // Trigger update. This will redraw the newly exposed area and make sure
5731 // the pixmap is re-blitted in case there are overlapping items.
5732 d->scene->d_func()->markDirty(this, rect);
5736 \fn void QGraphicsItem::update(qreal x, qreal y, qreal width, qreal height)
5739 This convenience function is equivalent to calling update(QRectF(\a x, \a
5740 y, \a width, \a height)).
5744 Maps the point \a point, which is in this item's coordinate system, to \a
5745 item's coordinate system, and returns the mapped coordinate.
5747 If \a item is 0, this function returns the same as mapToScene().
5749 \sa itemTransform(), mapToParent(), mapToScene(), transform(), mapFromItem(), {The Graphics
5750 View Coordinate System}
5752 QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF &point) const
5755 return itemTransform(item).map(point);
5756 return mapToScene(point);
5760 \fn QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y) const
5763 This convenience function is equivalent to calling mapToItem(\a item,
5764 QPointF(\a x, \a y)).
5768 Maps the point \a point, which is in this item's coordinate system, to its
5769 parent's coordinate system, and returns the mapped coordinate. If the item
5770 has no parent, \a point will be mapped to the scene's coordinate system.
5772 \sa mapToItem(), mapToScene(), transform(), mapFromParent(), {The Graphics
5773 View Coordinate System}
5775 QPointF QGraphicsItem::mapToParent(const QPointF &point) const
5778 if (!d_ptr->transformData)
5779 return point + d_ptr->pos;
5780 return d_ptr->transformToParent().map(point);
5784 \fn QPointF QGraphicsItem::mapToParent(qreal x, qreal y) const
5787 This convenience function is equivalent to calling mapToParent(QPointF(\a
5792 Maps the point \a point, which is in this item's coordinate system, to the
5793 scene's coordinate system, and returns the mapped coordinate.
5795 \sa mapToItem(), mapToParent(), transform(), mapFromScene(), {The Graphics
5796 View Coordinate System}
5798 QPointF QGraphicsItem::mapToScene(const QPointF &point) const
5800 if (d_ptr->hasTranslateOnlySceneTransform())
5801 return QPointF(point.x() + d_ptr->sceneTransform.dx(), point.y() + d_ptr->sceneTransform.dy());
5802 return d_ptr->sceneTransform.map(point);
5806 \fn QPointF QGraphicsItem::mapToScene(qreal x, qreal y) const
5809 This convenience function is equivalent to calling mapToScene(QPointF(\a
5814 Maps the rectangle \a rect, which is in this item's coordinate system, to
5815 \a item's coordinate system, and returns the mapped rectangle as a polygon.
5817 If \a item is 0, this function returns the same as mapToScene().
5819 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5820 Graphics View Coordinate System}
5822 QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect) const
5825 return itemTransform(item).map(rect);
5826 return mapToScene(rect);
5830 \fn QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
5833 This convenience function is equivalent to calling mapToItem(item, QRectF(\a x, \a y, \a w, \a h)).
5837 Maps the rectangle \a rect, which is in this item's coordinate system, to
5838 its parent's coordinate system, and returns the mapped rectangle as a
5839 polygon. If the item has no parent, \a rect will be mapped to the scene's
5842 \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
5845 QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
5848 if (!d_ptr->transformData)
5849 return rect.translated(d_ptr->pos);
5850 return d_ptr->transformToParent().map(rect);
5854 \fn QPolygonF QGraphicsItem::mapToParent(qreal x, qreal y, qreal w, qreal h) const
5857 This convenience function is equivalent to calling mapToParent(QRectF(\a x, \a y, \a w, \a h)).
5861 Maps the rectangle \a rect, which is in this item's coordinate system, to
5862 the scene's coordinate system, and returns the mapped rectangle as a polygon.
5864 \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
5867 QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const
5869 if (d_ptr->hasTranslateOnlySceneTransform())
5870 return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
5871 return d_ptr->sceneTransform.map(rect);
5875 \fn QPolygonF QGraphicsItem::mapToScene(qreal x, qreal y, qreal w, qreal h) const
5878 This convenience function is equivalent to calling mapToScene(QRectF(\a x, \a y, \a w, \a h)).
5884 Maps the rectangle \a rect, which is in this item's coordinate system, to
5885 \a item's coordinate system, and returns the mapped rectangle as a new
5886 rectangle (i.e., the bounding rectangle of the resulting polygon).
5888 If \a item is 0, this function returns the same as mapRectToScene().
5890 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5891 Graphics View Coordinate System}
5893 QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, const QRectF &rect) const
5896 return itemTransform(item).mapRect(rect);
5897 return mapRectToScene(rect);
5901 \fn QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
5904 This convenience function is equivalent to calling mapRectToItem(item, QRectF(\a x, \a y, \a w, \a h)).
5910 Maps the rectangle \a rect, which is in this item's coordinate system, to
5911 its parent's coordinate system, and returns the mapped rectangle as a new
5912 rectangle (i.e., the bounding rectangle of the resulting polygon).
5914 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5915 Graphics View Coordinate System}
5917 QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const
5920 if (!d_ptr->transformData)
5921 return rect.translated(d_ptr->pos);
5922 return d_ptr->transformToParent().mapRect(rect);
5926 \fn QRectF QGraphicsItem::mapRectToParent(qreal x, qreal y, qreal w, qreal h) const
5929 This convenience function is equivalent to calling mapRectToParent(QRectF(\a x, \a y, \a w, \a h)).
5935 Maps the rectangle \a rect, which is in this item's coordinate system, to
5936 the scene coordinate system, and returns the mapped rectangle as a new
5937 rectangle (i.e., the bounding rectangle of the resulting polygon).
5939 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5940 Graphics View Coordinate System}
5942 QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const
5944 if (d_ptr->hasTranslateOnlySceneTransform())
5945 return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
5946 return d_ptr->sceneTransform.mapRect(rect);
5950 \fn QRectF QGraphicsItem::mapRectToScene(qreal x, qreal y, qreal w, qreal h) const
5953 This convenience function is equivalent to calling mapRectToScene(QRectF(\a x, \a y, \a w, \a h)).
5959 Maps the rectangle \a rect, which is in \a item's coordinate system, to
5960 this item's coordinate system, and returns the mapped rectangle as a new
5961 rectangle (i.e., the bounding rectangle of the resulting polygon).
5963 If \a item is 0, this function returns the same as mapRectFromScene().
5965 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5966 Graphics View Coordinate System}
5968 QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, const QRectF &rect) const
5971 return item->itemTransform(this).mapRect(rect);
5972 return mapRectFromScene(rect);
5976 \fn QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
5979 This convenience function is equivalent to calling mapRectFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
5985 Maps the rectangle \a rect, which is in this item's parent's coordinate
5986 system, to this item's coordinate system, and returns the mapped rectangle
5987 as a new rectangle (i.e., the bounding rectangle of the resulting
5990 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
5991 Graphics View Coordinate System}
5993 QRectF QGraphicsItem::mapRectFromParent(const QRectF &rect) const
5996 if (!d_ptr->transformData)
5997 return rect.translated(-d_ptr->pos);
5998 return d_ptr->transformToParent().inverted().mapRect(rect);
6002 \fn QRectF QGraphicsItem::mapRectFromParent(qreal x, qreal y, qreal w, qreal h) const
6005 This convenience function is equivalent to calling mapRectFromParent(QRectF(\a x, \a y, \a w, \a h)).
6011 Maps the rectangle \a rect, which is in scene coordinates, to this item's
6012 coordinate system, and returns the mapped rectangle as a new rectangle
6013 (i.e., the bounding rectangle of the resulting polygon).
6015 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6016 Graphics View Coordinate System}
6018 QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const
6020 if (d_ptr->hasTranslateOnlySceneTransform())
6021 return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6022 return d_ptr->sceneTransform.inverted().mapRect(rect);
6026 \fn QRectF QGraphicsItem::mapRectFromScene(qreal x, qreal y, qreal w, qreal h) const
6029 This convenience function is equivalent to calling mapRectFromScene(QRectF(\a x, \a y, \a w, \a h)).
6033 Maps the polygon \a polygon, which is in this item's coordinate system, to
6034 \a item's coordinate system, and returns the mapped polygon.
6036 If \a item is 0, this function returns the same as mapToScene().
6038 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6039 Graphics View Coordinate System}
6041 QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &polygon) const
6044 return itemTransform(item).map(polygon);
6045 return mapToScene(polygon);
6049 Maps the polygon \a polygon, which is in this item's coordinate system, to
6050 its parent's coordinate system, and returns the mapped polygon. If the
6051 item has no parent, \a polygon will be mapped to the scene's coordinate
6054 \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
6057 QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
6060 if (!d_ptr->transformData)
6061 return polygon.translated(d_ptr->pos);
6062 return d_ptr->transformToParent().map(polygon);
6066 Maps the polygon \a polygon, which is in this item's coordinate system, to
6067 the scene's coordinate system, and returns the mapped polygon.
6069 \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
6072 QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const
6074 if (d_ptr->hasTranslateOnlySceneTransform())
6075 return polygon.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6076 return d_ptr->sceneTransform.map(polygon);
6080 Maps the path \a path, which is in this item's coordinate system, to
6081 \a item's coordinate system, and returns the mapped path.
6083 If \a item is 0, this function returns the same as mapToScene().
6085 \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
6086 Graphics View Coordinate System}
6088 QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterPath &path) const
6091 return itemTransform(item).map(path);
6092 return mapToScene(path);
6096 Maps the path \a path, which is in this item's coordinate system, to
6097 its parent's coordinate system, and returns the mapped path. If the
6098 item has no parent, \a path will be mapped to the scene's coordinate
6101 \sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
6104 QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
6107 if (!d_ptr->transformData)
6108 return path.translated(d_ptr->pos);
6109 return d_ptr->transformToParent().map(path);
6113 Maps the path \a path, which is in this item's coordinate system, to
6114 the scene's coordinate system, and returns the mapped path.
6116 \sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
6119 QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const
6121 if (d_ptr->hasTranslateOnlySceneTransform())
6122 return path.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
6123 return d_ptr->sceneTransform.map(path);
6127 Maps the point \a point, which is in \a item's coordinate system, to this
6128 item's coordinate system, and returns the mapped coordinate.
6130 If \a item is 0, this function returns the same as mapFromScene().
6132 \sa itemTransform(), mapFromParent(), mapFromScene(), transform(), mapToItem(), {The Graphics
6133 View Coordinate System}
6135 QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &point) const
6138 return item->itemTransform(this).map(point);
6139 return mapFromScene(point);
6143 \fn QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y) const
6146 This convenience function is equivalent to calling mapFromItem(\a item,
6147 QPointF(\a x, \a y)).
6151 Maps the point \a point, which is in this item's parent's coordinate
6152 system, to this item's coordinate system, and returns the mapped
6155 \sa mapFromItem(), mapFromScene(), transform(), mapToParent(), {The Graphics
6156 View Coordinate System}
6158 QPointF QGraphicsItem::mapFromParent(const QPointF &point) const
6161 if (d_ptr->transformData)
6162 return d_ptr->transformToParent().inverted().map(point);
6163 return point - d_ptr->pos;
6167 \fn QPointF QGraphicsItem::mapFromParent(qreal x, qreal y) const
6170 This convenience function is equivalent to calling
6171 mapFromParent(QPointF(\a x, \a y)).
6175 Maps the point \a point, which is in this item's scene's coordinate
6176 system, to this item's coordinate system, and returns the mapped
6179 \sa mapFromItem(), mapFromParent(), transform(), mapToScene(), {The Graphics
6180 View Coordinate System}
6182 QPointF QGraphicsItem::mapFromScene(const QPointF &point) const
6184 if (d_ptr->hasTranslateOnlySceneTransform())
6185 return QPointF(point.x() - d_ptr->sceneTransform.dx(), point.y() - d_ptr->sceneTransform.dy());
6186 return d_ptr->sceneTransform.inverted().map(point);
6190 \fn QPointF QGraphicsItem::mapFromScene(qreal x, qreal y) const
6193 This convenience function is equivalent to calling mapFromScene(QPointF(\a
6198 Maps the rectangle \a rect, which is in \a item's coordinate system, to
6199 this item's coordinate system, and returns the mapped rectangle as a
6202 If \a item is 0, this function returns the same as mapFromScene()
6204 \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The Graphics View Coordinate
6207 QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QRectF &rect) const
6210 return item->itemTransform(this).map(rect);
6211 return mapFromScene(rect);
6215 \fn QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
6218 This convenience function is equivalent to calling mapFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
6222 Maps the rectangle \a rect, which is in this item's parent's coordinate
6223 system, to this item's coordinate system, and returns the mapped rectangle
6226 \sa mapToParent(), mapFromItem(), transform(), {The Graphics View Coordinate
6229 QPolygonF QGraphicsItem::mapFromParent(const QRectF &rect) const
6232 if (!d_ptr->transformData)
6233 return rect.translated(-d_ptr->pos);
6234 return d_ptr->transformToParent().inverted().map(rect);
6238 \fn QPolygonF QGraphicsItem::mapFromParent(qreal x, qreal y, qreal w, qreal h) const
6241 This convenience function is equivalent to calling mapFromItem(QRectF(\a x, \a y, \a w, \a h)).
6245 Maps the rectangle \a rect, which is in this item's scene's coordinate
6246 system, to this item's coordinate system, and returns the mapped rectangle
6249 \sa mapToScene(), mapFromItem(), transform(), {The Graphics View Coordinate
6252 QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const
6254 if (d_ptr->hasTranslateOnlySceneTransform())
6255 return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6256 return d_ptr->sceneTransform.inverted().map(rect);
6260 \fn QPolygonF QGraphicsItem::mapFromScene(qreal x, qreal y, qreal w, qreal h) const
6263 This convenience function is equivalent to calling mapFromScene(QRectF(\a x, \a y, \a w, \a h)).
6267 Maps the polygon \a polygon, which is in \a item's coordinate system, to
6268 this item's coordinate system, and returns the mapped polygon.
6270 If \a item is 0, this function returns the same as mapFromScene().
6272 \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The
6273 Graphics View Coordinate System}
6275 QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPolygonF &polygon) const
6278 return item->itemTransform(this).map(polygon);
6279 return mapFromScene(polygon);
6283 Maps the polygon \a polygon, which is in this item's parent's coordinate
6284 system, to this item's coordinate system, and returns the mapped polygon.
6286 \sa mapToParent(), mapToItem(), transform(), {The Graphics View Coordinate
6289 QPolygonF QGraphicsItem::mapFromParent(const QPolygonF &polygon) const
6292 if (!d_ptr->transformData)
6293 return polygon.translated(-d_ptr->pos);
6294 return d_ptr->transformToParent().inverted().map(polygon);
6298 Maps the polygon \a polygon, which is in this item's scene's coordinate
6299 system, to this item's coordinate system, and returns the mapped polygon.
6301 \sa mapToScene(), mapFromParent(), transform(), {The Graphics View Coordinate
6304 QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const
6306 if (d_ptr->hasTranslateOnlySceneTransform())
6307 return polygon.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6308 return d_ptr->sceneTransform.inverted().map(polygon);
6312 Maps the path \a path, which is in \a item's coordinate system, to
6313 this item's coordinate system, and returns the mapped path.
6315 If \a item is 0, this function returns the same as mapFromScene().
6317 \sa itemTransform(), mapFromParent(), mapFromScene(), mapToItem(), {The
6318 Graphics View Coordinate System}
6320 QPainterPath QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPainterPath &path) const
6323 return item->itemTransform(this).map(path);
6324 return mapFromScene(path);
6328 Maps the path \a path, which is in this item's parent's coordinate
6329 system, to this item's coordinate system, and returns the mapped path.
6331 \sa mapFromScene(), mapFromItem(), mapToParent(), {The Graphics View
6334 QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const
6337 if (!d_ptr->transformData)
6338 return path.translated(-d_ptr->pos);
6339 return d_ptr->transformToParent().inverted().map(path);
6343 Maps the path \a path, which is in this item's scene's coordinate
6344 system, to this item's coordinate system, and returns the mapped path.
6346 \sa mapFromParent(), mapFromItem(), mapToScene(), {The Graphics View
6349 QPainterPath QGraphicsItem::mapFromScene(const QPainterPath &path) const
6351 if (d_ptr->hasTranslateOnlySceneTransform())
6352 return path.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
6353 return d_ptr->sceneTransform.inverted().map(path);
6357 Returns true if this item is an ancestor of \a child (i.e., if this item
6358 is \a child's parent, or one of \a child's parent's ancestors).
6362 bool QGraphicsItem::isAncestorOf(const QGraphicsItem *child) const
6364 if (!child || child == this)
6366 if (child->d_ptr->depth() < d_ptr->depth())
6368 const QGraphicsItem *ancestor = child;
6369 while ((ancestor = ancestor->d_ptr->parent)) {
6370 if (ancestor == this)
6379 Returns the closest common ancestor item of this item and \a other, or 0
6380 if either \a other is 0, or there is no common ancestor.
6384 QGraphicsItem *QGraphicsItem::commonAncestorItem(const QGraphicsItem *other) const
6389 return const_cast<QGraphicsItem *>(this);
6390 const QGraphicsItem *thisw = this;
6391 const QGraphicsItem *otherw = other;
6392 int thisDepth = d_ptr->depth();
6393 int otherDepth = other->d_ptr->depth();
6394 while (thisDepth > otherDepth) {
6395 thisw = thisw->d_ptr->parent;
6398 while (otherDepth > thisDepth) {
6399 otherw = otherw->d_ptr->parent;
6402 while (thisw && thisw != otherw) {
6403 thisw = thisw->d_ptr->parent;
6404 otherw = otherw->d_ptr->parent;
6406 return const_cast<QGraphicsItem *>(thisw);
6411 Returns true if this item is currently under the mouse cursor in one of
6412 the views; otherwise, false is returned.
6414 \sa QGraphicsScene::views(), QCursor::pos()
6416 bool QGraphicsItem::isUnderMouse() const
6418 Q_D(const QGraphicsItem);
6422 QPoint cursorPos = QCursor::pos();
6423 foreach (QGraphicsView *view, d->scene->views()) {
6424 if (contains(mapFromScene(view->mapToScene(view->mapFromGlobal(cursorPos)))))
6431 Returns this item's custom data for the key \a key as a QVariant.
6433 Custom item data is useful for storing arbitrary properties in any
6436 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 11
6438 Qt does not use this feature for storing data; it is provided solely
6439 for the convenience of the user.
6443 QVariant QGraphicsItem::data(int key) const
6445 QGraphicsItemCustomDataStore *store = qt_dataStore();
6446 if (!store->data.contains(this))
6448 return store->data.value(this).value(key);
6452 Sets this item's custom data for the key \a key to \a value.
6454 Custom item data is useful for storing arbitrary properties for any
6455 item. Qt does not use this feature for storing data; it is provided solely
6456 for the convenience of the user.
6460 void QGraphicsItem::setData(int key, const QVariant &value)
6462 qt_dataStore()->data[this][key] = value;
6466 \fn T qgraphicsitem_cast(QGraphicsItem *item)
6467 \relates QGraphicsItem
6470 Returns the given \a item cast to type T if \a item is of type T;
6471 otherwise, 0 is returned.
6473 \note To make this function work correctly with custom items, reimplement
6474 the \l{QGraphicsItem::}{type()} function for each custom QGraphicsItem
6477 \sa QGraphicsItem::type(), QGraphicsItem::UserType
6481 Returns the type of an item as an int. All standard graphicsitem classes
6482 are associated with a unique value; see QGraphicsItem::Type. This type
6483 information is used by qgraphicsitem_cast() to distinguish between types.
6485 The default implementation (in QGraphicsItem) returns UserType.
6487 To enable use of qgraphicsitem_cast() with a custom item, reimplement this
6488 function and declare a Type enum value equal to your custom item's type.
6489 Custom items must return a value larger than or equal to UserType (65536).
6493 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp QGraphicsItem type
6497 int QGraphicsItem::type() const
6499 return (int)UserType;
6503 Installs an event filter for this item on \a filterItem, causing
6504 all events for this item to first pass through \a filterItem's
6505 sceneEventFilter() function.
6507 To filter another item's events, install this item as an event filter
6508 for the other item. Example:
6510 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 12
6512 An item can only filter events for other items in the same
6513 scene. Also, an item cannot filter its own events; instead, you
6514 can reimplement sceneEvent() directly.
6516 Items must belong to a scene for scene event filters to be installed and
6519 \sa removeSceneEventFilter(), sceneEventFilter(), sceneEvent()
6521 void QGraphicsItem::installSceneEventFilter(QGraphicsItem *filterItem)
6523 if (!d_ptr->scene) {
6524 qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
6525 " on items in a scene.");
6528 if (d_ptr->scene != filterItem->scene()) {
6529 qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
6530 " on items in the same scene.");
6533 d_ptr->scene->d_func()->installSceneEventFilter(this, filterItem);
6537 Removes an event filter on this item from \a filterItem.
6539 \sa installSceneEventFilter()
6541 void QGraphicsItem::removeSceneEventFilter(QGraphicsItem *filterItem)
6543 if (!d_ptr->scene || d_ptr->scene != filterItem->scene())
6545 d_ptr->scene->d_func()->removeSceneEventFilter(this, filterItem);
6549 Filters events for the item \a watched. \a event is the filtered
6552 Reimplementing this function in a subclass makes it possible
6553 for the item to be used as an event filter for other items,
6554 intercepting all the events send to those items before they are
6557 Reimplementations must return true to prevent further processing of
6558 a given event, ensuring that it will not be delivered to the watched
6559 item, or return false to indicate that the event should be propagated
6560 further by the event system.
6562 \sa installSceneEventFilter()
6564 bool QGraphicsItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
6572 This virtual function receives events to this item. Reimplement
6573 this function to intercept events before they are dispatched to
6574 the specialized event handlers contextMenuEvent(), focusInEvent(),
6575 focusOutEvent(), hoverEnterEvent(), hoverMoveEvent(),
6576 hoverLeaveEvent(), keyPressEvent(), keyReleaseEvent(),
6577 mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent(), and
6578 mouseDoubleClickEvent().
6580 Returns true if the event was recognized and handled; otherwise, (e.g., if
6581 the event type was not recognized,) false is returned.
6583 \a event is the intercepted event.
6585 bool QGraphicsItem::sceneEvent(QEvent *event)
6587 if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents) {
6588 if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverLeave
6589 || event->type() == QEvent::DragEnter || event->type() == QEvent::DragLeave) {
6590 // Hover enter and hover leave events for children are ignored;
6591 // hover move events are forwarded.
6595 QGraphicsItem *handler = this;
6597 handler = handler->d_ptr->parent;
6599 } while (handler->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents);
6600 // Forward the event to the closest parent that handles child
6601 // events, mapping existing item-local coordinates to its
6602 // coordinate system.
6603 d_ptr->remapItemPos(event, handler);
6604 handler->sceneEvent(event);
6608 if (event->type() == QEvent::FocusOut) {
6609 focusOutEvent(static_cast<QFocusEvent *>(event));
6613 if (!d_ptr->visible) {
6618 switch (event->type()) {
6619 case QEvent::FocusIn:
6620 focusInEvent(static_cast<QFocusEvent *>(event));
6622 case QEvent::GraphicsSceneContextMenu:
6623 contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event));
6625 case QEvent::GraphicsSceneDragEnter:
6626 dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6628 case QEvent::GraphicsSceneDragMove:
6629 dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6631 case QEvent::GraphicsSceneDragLeave:
6632 dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6634 case QEvent::GraphicsSceneDrop:
6635 dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
6637 case QEvent::GraphicsSceneHoverEnter:
6638 hoverEnterEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6640 case QEvent::GraphicsSceneHoverMove:
6641 hoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6643 case QEvent::GraphicsSceneHoverLeave:
6644 hoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
6646 case QEvent::GraphicsSceneMouseMove:
6647 mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6649 case QEvent::GraphicsSceneMousePress:
6650 mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6652 case QEvent::GraphicsSceneMouseRelease:
6653 mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6655 case QEvent::GraphicsSceneMouseDoubleClick:
6656 mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
6658 case QEvent::GraphicsSceneWheel:
6659 wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
6661 case QEvent::KeyPress: {
6662 QKeyEvent *k = static_cast<QKeyEvent *>(event);
6663 if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
6664 if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
6666 if (k->key() == Qt::Key_Backtab
6667 || (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
6668 if (d_ptr->isWidget) {
6669 res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(false);
6670 } else if (d_ptr->scene) {
6671 res = d_ptr->scene->focusNextPrevChild(false);
6673 } else if (k->key() == Qt::Key_Tab) {
6674 if (d_ptr->isWidget) {
6675 res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(true);
6676 } else if (d_ptr->scene) {
6677 res = d_ptr->scene->focusNextPrevChild(true);
6685 keyPressEvent(static_cast<QKeyEvent *>(event));
6688 case QEvent::KeyRelease:
6689 keyReleaseEvent(static_cast<QKeyEvent *>(event));
6691 case QEvent::InputMethod:
6692 inputMethodEvent(static_cast<QInputMethodEvent *>(event));
6694 case QEvent::WindowActivate:
6695 case QEvent::WindowDeactivate:
6696 // Propagate panel activation.
6698 for (int i = 0; i < d_ptr->children.size(); ++i) {
6699 QGraphicsItem *child = d_ptr->children.at(i);
6700 if (child->isVisible() && !child->isPanel()) {
6701 if (!(child->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents))
6702 d_ptr->scene->sendEvent(child, event);
6715 This event handler can be reimplemented in a subclass to process context
6716 menu events. The \a event parameter contains details about the event to
6719 If you ignore the event, (i.e., by calling QEvent::ignore(),) \a event
6720 will propagate to any item beneath this item. If no items accept the
6721 event, it will be ignored by the scene, and propagate to the view.
6723 It's common to open a QMenu in response to receiving a context menu
6726 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 13
6728 The default implementation ignores the event.
6732 void QGraphicsItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
6738 This event handler, for event \a event, can be reimplemented to receive
6739 drag enter events for this item. Drag enter events are generated as the
6740 cursor enters the item's area.
6742 By accepting the event, (i.e., by calling QEvent::accept(),) the item will
6743 accept drop events, in addition to receiving drag move and drag
6744 leave. Otherwise, the event will be ignored and propagate to the item
6745 beneath. If the event is accepted, the item will receive a drag move event
6746 before control goes back to the event loop.
6748 A common implementation of dragEnterEvent accepts or ignores \a event
6749 depending on the associated mime data in \a event. Example:
6751 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 14
6753 Items do not receive drag and drop events by default; to enable this
6754 feature, call \c setAcceptDrops(true).
6756 The default implementation does nothing.
6758 \sa dropEvent(), dragMoveEvent(), dragLeaveEvent()
6760 void QGraphicsItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
6763 // binary compatibility workaround between 4.4 and 4.5
6764 if (d->isProxyWidget())
6765 static_cast<QGraphicsProxyWidget*>(this)->dragEnterEvent(event);
6769 This event handler, for event \a event, can be reimplemented to receive
6770 drag leave events for this item. Drag leave events are generated as the
6771 cursor leaves the item's area. Most often you will not need to reimplement
6772 this function, but it can be useful for resetting state in your item
6773 (e.g., highlighting).
6775 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6777 Items do not receive drag and drop events by default; to enable this
6778 feature, call \c setAcceptDrops(true).
6780 The default implementation does nothing.
6782 \sa dragEnterEvent(), dropEvent(), dragMoveEvent()
6784 void QGraphicsItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
6787 // binary compatibility workaround between 4.4 and 4.5
6788 if (d->isProxyWidget())
6789 static_cast<QGraphicsProxyWidget*>(this)->dragLeaveEvent(event);
6793 This event handler, for event \a event, can be reimplemented to receive
6794 drag move events for this item. Drag move events are generated as the
6795 cursor moves around inside the item's area. Most often you will not need
6796 to reimplement this function; it is used to indicate that only parts of
6797 the item can accept drops.
6799 Calling QEvent::ignore() or QEvent::accept() on \a event toggles whether
6800 or not the item will accept drops at the position from the event. By
6801 default, \a event is accepted, indicating that the item allows drops at
6802 the specified position.
6804 Items do not receive drag and drop events by default; to enable this
6805 feature, call \c setAcceptDrops(true).
6807 The default implementation does nothing.
6809 \sa dropEvent(), dragEnterEvent(), dragLeaveEvent()
6811 void QGraphicsItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
6814 // binary compatibility workaround between 4.4 and 4.5
6815 if (d->isProxyWidget())
6816 static_cast<QGraphicsProxyWidget*>(this)->dragMoveEvent(event);
6820 This event handler, for event \a event, can be reimplemented to receive
6821 drop events for this item. Items can only receive drop events if the last
6822 drag move event was accepted.
6824 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6826 Items do not receive drag and drop events by default; to enable this
6827 feature, call \c setAcceptDrops(true).
6829 The default implementation does nothing.
6831 \sa dragEnterEvent(), dragMoveEvent(), dragLeaveEvent()
6833 void QGraphicsItem::dropEvent(QGraphicsSceneDragDropEvent *event)
6836 // binary compatibility workaround between 4.4 and 4.5
6837 if (d->isProxyWidget())
6838 static_cast<QGraphicsProxyWidget*>(this)->dropEvent(event);
6842 This event handler, for event \a event, can be reimplemented to receive
6843 focus in events for this item. The default implementation calls
6846 \sa focusOutEvent(), sceneEvent(), setFocus()
6848 void QGraphicsItem::focusInEvent(QFocusEvent *event)
6855 This event handler, for event \a event, can be reimplemented to receive
6856 focus out events for this item. The default implementation does nothing.
6858 \sa focusInEvent(), sceneEvent(), setFocus()
6860 void QGraphicsItem::focusOutEvent(QFocusEvent *event)
6867 This event handler, for event \a event, can be reimplemented to receive
6868 hover enter events for this item. The default implementation calls
6869 update(); otherwise it does nothing.
6871 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6873 \sa hoverMoveEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
6875 void QGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
6882 This event handler, for event \a event, can be reimplemented to receive
6883 hover move events for this item. The default implementation does nothing.
6885 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6887 \sa hoverEnterEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
6889 void QGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
6895 This event handler, for event \a event, can be reimplemented to receive
6896 hover leave events for this item. The default implementation calls
6897 update(); otherwise it does nothing.
6899 Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
6901 \sa hoverEnterEvent(), hoverMoveEvent(), sceneEvent(), setAcceptHoverEvents()
6903 void QGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
6910 This event handler, for event \a event, can be reimplemented to
6911 receive key press events for this item. The default implementation
6912 ignores the event. If you reimplement this handler, the event will by
6913 default be accepted.
6915 Note that key events are only received for items that set the
6916 ItemIsFocusable flag, and that have keyboard input focus.
6918 \sa keyReleaseEvent(), setFocus(), QGraphicsScene::setFocusItem(),
6921 void QGraphicsItem::keyPressEvent(QKeyEvent *event)
6927 This event handler, for event \a event, can be reimplemented to receive
6928 key release events for this item. The default implementation
6929 ignores the event. If you reimplement this handler, the event will by
6930 default be accepted.
6932 Note that key events are only received for items that set the
6933 ItemIsFocusable flag, and that have keyboard input focus.
6935 \sa keyPressEvent(), setFocus(), QGraphicsScene::setFocusItem(),
6938 void QGraphicsItem::keyReleaseEvent(QKeyEvent *event)
6944 This event handler, for event \a event, can be reimplemented to
6945 receive mouse press events for this item. Mouse press events are
6946 only delivered to items that accept the mouse button that is
6947 pressed. By default, an item accepts all mouse buttons, but you
6948 can change this by calling setAcceptedMouseButtons().
6950 The mouse press event decides which item should become the mouse
6951 grabber (see QGraphicsScene::mouseGrabberItem()). If you do not
6952 reimplement this function, the press event will propagate to any
6953 topmost item beneath this item, and no other mouse events will be
6954 delivered to this item.
6956 If you do reimplement this function, \a event will by default be
6957 accepted (see QEvent::accept()), and this item is then the mouse
6958 grabber. This allows the item to receive future move, release and
6959 doubleclick events. If you call QEvent::ignore() on \a event, this
6960 item will lose the mouse grab, and \a event will propagate to any
6961 topmost item beneath. No further mouse events will be delivered to
6962 this item unless a new mouse press event is received.
6964 The default implementation handles basic item interaction, such as
6965 selection and moving. If you want to keep the base implementation
6966 when reimplementing this function, call
6967 QGraphicsItem::mousePressEvent() in your reimplementation.
6969 The event is \l{QEvent::ignore()}d for items that are neither
6970 \l{QGraphicsItem::ItemIsMovable}{movable} nor
6971 \l{QGraphicsItem::ItemIsSelectable}{selectable}.
6973 \sa mouseMoveEvent(), mouseReleaseEvent(),
6974 mouseDoubleClickEvent(), sceneEvent()
6976 void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
6978 if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
6979 bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
6981 if (!d_ptr->selected) {
6982 if (QGraphicsScene *scene = d_ptr->scene) {
6983 ++scene->d_func()->selectionChanging;
6984 scene->clearSelection();
6985 --scene->d_func()->selectionChanging;
6990 } else if (!(flags() & ItemIsMovable)) {
6993 if (d_ptr->isWidget) {
6994 // Qt::Popup closes when you click outside.
6995 QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
6996 if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
6998 if (!w->rect().contains(event->pos()))
7007 bool _qt_movableAncestorIsSelected(const QGraphicsItem *item)
7009 const QGraphicsItem *parent = item->parentItem();
7010 return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
7013 bool QGraphicsItemPrivate::movableAncestorIsSelected(const QGraphicsItem *item)
7015 const QGraphicsItem *parent = item->d_ptr->parent;
7016 return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
7020 This event handler, for event \a event, can be reimplemented to
7021 receive mouse move events for this item. If you do receive this
7022 event, you can be certain that this item also received a mouse
7023 press event, and that this item is the current mouse grabber.
7025 Calling QEvent::ignore() or QEvent::accept() on \a event has no
7028 The default implementation handles basic item interaction, such as
7029 selection and moving. If you want to keep the base implementation
7030 when reimplementing this function, call
7031 QGraphicsItem::mouseMoveEvent() in your reimplementation.
7033 Please note that mousePressEvent() decides which graphics item it
7034 is that receives mouse events. See the mousePressEvent()
7035 description for details.
7037 \sa mousePressEvent(), mouseReleaseEvent(),
7038 mouseDoubleClickEvent(), sceneEvent()
7040 void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
7042 if ((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) {
7043 // Determine the list of items that need to be moved.
7044 QList<QGraphicsItem *> selectedItems;
7045 QHash<QGraphicsItem *, QPointF> initialPositions;
7047 selectedItems = d_ptr->scene->selectedItems();
7048 initialPositions = d_ptr->scene->d_func()->movingItemsInitialPositions;
7049 if (initialPositions.isEmpty()) {
7050 foreach (QGraphicsItem *item, selectedItems)
7051 initialPositions[item] = item->pos();
7052 initialPositions[this] = pos();
7054 d_ptr->scene->d_func()->movingItemsInitialPositions = initialPositions;
7057 // Find the active view.
7058 QGraphicsView *view = 0;
7059 if (event->widget())
7060 view = qobject_cast<QGraphicsView *>(event->widget()->parentWidget());
7062 // Move all selected items
7064 bool movedMe = false;
7065 while (i <= selectedItems.size()) {
7066 QGraphicsItem *item = 0;
7067 if (i < selectedItems.size())
7068 item = selectedItems.at(i);
7072 // Slightly clumsy-looking way to ensure that "this" is part
7073 // of the list of items to move, this is to avoid allocations
7074 // (appending this item to the list of selected items causes a
7081 if ((item->flags() & ItemIsMovable) && !QGraphicsItemPrivate::movableAncestorIsSelected(item)) {
7082 QPointF currentParentPos;
7083 QPointF buttonDownParentPos;
7084 if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorIgnoresTransformations) {
7085 // Items whose ancestors ignore transformations need to
7086 // map screen coordinates to local coordinates, then map
7087 // those to the parent.
7088 QTransform viewToItemTransform = (item->deviceTransform(view->viewportTransform())).inverted();
7089 currentParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))));
7090 buttonDownParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))));
7091 } else if (item->flags() & ItemIgnoresTransformations) {
7092 // Root items that ignore transformations need to
7093 // calculate their diff by mapping viewport coordinates
7094 // directly to parent coordinates.
7096 QTransform itemTransform;
7097 if (item->d_ptr->transformData)
7098 itemTransform = item->d_ptr->transformData->computedFullTransform();
7099 itemTransform.translate(item->d_ptr->pos.x(), item->d_ptr->pos.y());
7100 QTransform viewToParentTransform = itemTransform
7101 * (item->sceneTransform() * view->viewportTransform()).inverted();
7102 currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos())));
7103 buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton))));
7105 // All other items simply map from the scene.
7106 currentParentPos = item->mapToParent(item->mapFromScene(event->scenePos()));
7107 buttonDownParentPos = item->mapToParent(item->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)));
7110 item->setPos(initialPositions.value(item) + currentParentPos - buttonDownParentPos);
7112 if (item->flags() & ItemIsSelectable)
7113 item->setSelected(true);
7124 This event handler, for event \a event, can be reimplemented to
7125 receive mouse release events for this item.
7127 Calling QEvent::ignore() or QEvent::accept() on \a event has no
7130 The default implementation handles basic item interaction, such as
7131 selection and moving. If you want to keep the base implementation
7132 when reimplementing this function, call
7133 QGraphicsItem::mouseReleaseEvent() in your reimplementation.
7135 Please note that mousePressEvent() decides which graphics item it
7136 is that receives mouse events. See the mousePressEvent()
7137 description for details.
7139 \sa mousePressEvent(), mouseMoveEvent(), mouseDoubleClickEvent(),
7142 void QGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
7144 if (flags() & ItemIsSelectable) {
7145 bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
7146 if (event->scenePos() == event->buttonDownScenePos(Qt::LeftButton)) {
7147 // The item didn't move
7149 setSelected(!isSelected());
7151 bool selectionChanged = false;
7152 if (QGraphicsScene *scene = d_ptr->scene) {
7153 ++scene->d_func()->selectionChanging;
7154 // Clear everything but this item. Bypass
7155 // QGraphicsScene::clearSelection()'s default behavior by
7156 // temporarily removing this item from the selection list.
7157 if (d_ptr->selected) {
7158 scene->d_func()->selectedItems.remove(this);
7159 foreach (QGraphicsItem *item, scene->d_func()->selectedItems) {
7160 if (item->isSelected()) {
7161 selectionChanged = true;
7166 scene->clearSelection();
7167 if (d_ptr->selected)
7168 scene->d_func()->selectedItems.insert(this);
7169 --scene->d_func()->selectionChanging;
7170 if (selectionChanged)
7171 emit d_ptr->scene->selectionChanged();
7177 if (d_ptr->scene && !event->buttons())
7178 d_ptr->scene->d_func()->movingItemsInitialPositions.clear();
7182 This event handler, for event \a event, can be reimplemented to
7183 receive mouse doubleclick events for this item.
7185 When doubleclicking an item, the item will first receive a mouse
7186 press event, followed by a release event (i.e., a click), then a
7187 doubleclick event, and finally a release event.
7189 Calling QEvent::ignore() or QEvent::accept() on \a event has no
7192 The default implementation calls mousePressEvent(). If you want to
7193 keep the base implementation when reimplementing this function,
7194 call QGraphicsItem::mouseDoubleClickEvent() in your
7197 Note that an item will not receive double click events if it is
7198 neither \l {QGraphicsItem::ItemIsSelectable}{selectable} nor
7199 \l{QGraphicsItem::ItemIsMovable}{movable} (single mouse clicks are
7200 ignored in this case, and that stops the generation of double
7203 \sa mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), sceneEvent()
7205 void QGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
7207 mousePressEvent(event);
7211 This event handler, for event \a event, can be reimplemented to receive
7212 wheel events for this item. If you reimplement this function, \a event
7213 will be accepted by default.
7215 If you ignore the event, (i.e., by calling QEvent::ignore(),) it will
7216 propagate to any item beneath this item. If no items accept the event, it
7217 will be ignored by the scene, and propagate to the view (e.g., the view's
7218 vertical scroll bar).
7220 The default implementation ignores the event.
7224 void QGraphicsItem::wheelEvent(QGraphicsSceneWheelEvent *event)
7230 This event handler, for event \a event, can be reimplemented to receive
7231 input method events for this item. The default implementation ignores the
7234 \sa inputMethodQuery(), sceneEvent()
7236 void QGraphicsItem::inputMethodEvent(QInputMethodEvent *event)
7242 This method is only relevant for input items. It is used by the
7243 input method to query a set of properties of the item to be able
7244 to support complex input method operations, such as support for
7245 surrounding text and reconversions. \a query specifies which
7246 property is queried.
7248 \sa inputMethodEvent(), QInputMethodEvent
7250 QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const
7257 Returns the current input method hints of this item.
7259 Input method hints are only relevant for input items.
7260 The hints are used by the input method to indicate how it should operate.
7261 For example, if the Qt::ImhNumbersOnly flag is set, the input method may change
7262 its visual components to reflect that only numbers can be entered.
7264 The effect may vary between input method implementations.
7268 \sa setInputMethodHints(), inputMethodQuery()
7270 Qt::InputMethodHints QGraphicsItem::inputMethodHints() const
7272 Q_D(const QGraphicsItem);
7277 Sets the current input method hints of this item to \a hints.
7281 \sa inputMethodHints(), inputMethodQuery()
7283 void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
7289 d->scene->d_func()->updateInputMethodSensitivityInViews();
7290 QWidget *fw = QApplication::focusWidget();
7293 qApp->inputMethod()->update(Qt::ImHints);
7297 Updates the item's micro focus.
7303 void QGraphicsItem::updateMicroFocus()
7305 #if !defined(QT_NO_IM) && defined(Q_WS_X11)
7306 if (QWidget *fw = QApplication::focusWidget()) {
7308 for (int i = 0 ; i < scene()->views().count() ; ++i) {
7309 if (scene()->views().at(i) == fw) {
7311 qApp->inputMethod()->update(Qt::ImQueryAll);
7313 #ifndef QT_NO_ACCESSIBILITY
7314 // ##### is this correct
7315 if (toGraphicsObject())
7316 QAccessible::updateAccessibility(toGraphicsObject(), 0, QAccessible::StateChanged);
7328 This virtual function is called by QGraphicsItem to notify custom items
7329 that some part of the item's state changes. By reimplementing this
7330 function, your can react to a change, and in some cases, (depending on \a
7331 change,) adjustments can be made.
7333 \a change is the parameter of the item that is changing. \a value is the
7334 new value; the type of the value depends on \a change.
7338 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 15
7340 The default implementation does nothing, and returns \a value.
7342 Note: Certain QGraphicsItem functions cannot be called in a
7343 reimplementation of this function; see the GraphicsItemChange
7344 documentation for details.
7346 \sa GraphicsItemChange
7348 QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value)
7357 Note: This is provided as a hook to avoid future problems related
7358 to adding virtual functions.
7360 bool QGraphicsItem::supportsExtension(Extension extension) const
7362 Q_UNUSED(extension);
7369 Note: This is provided as a hook to avoid future problems related
7370 to adding virtual functions.
7372 void QGraphicsItem::setExtension(Extension extension, const QVariant &variant)
7374 Q_UNUSED(extension);
7381 Note: This is provided as a hook to avoid future problems related
7382 to adding virtual functions.
7384 QVariant QGraphicsItem::extension(const QVariant &variant) const
7393 Adds this item to the scene's index. Called in conjunction with
7394 removeFromIndex() to ensure the index bookkeeping is correct when
7395 the item's position, transformation or shape changes.
7397 void QGraphicsItem::addToIndex()
7399 if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
7400 // ### add to child index only if applicable
7404 d_ptr->scene->d_func()->index->addItem(this);
7410 Removes this item from the scene's index. Called in conjunction
7411 with addToIndex() to ensure the index bookkeeping is correct when
7412 the item's position, transformation or shape changes.
7414 void QGraphicsItem::removeFromIndex()
7416 if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
7417 // ### remove from child index only if applicable
7421 d_ptr->scene->d_func()->index->removeItem(this);
7425 Prepares the item for a geometry change. Call this function before
7426 changing the bounding rect of an item to keep QGraphicsScene's index up to
7429 prepareGeometryChange() will call update() if this is necessary.
7433 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 16
7437 void QGraphicsItem::prepareGeometryChange()
7439 if (d_ptr->inDestructor)
7442 d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true;
7443 d_ptr->geometryChanged = 1;
7444 d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
7445 d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper;
7447 QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
7448 scenePrivate->index->prepareBoundingRectChange(this);
7449 scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false,
7450 /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false,
7451 /*updateBoundingRect=*/true);
7453 // For compatibility reasons, we have to update the item's old geometry
7454 // if someone is connected to the changed signal or the scene has no views.
7455 // Note that this has to be done *after* markDirty to ensure that
7456 // _q_processDirtyItems is called before _q_emitUpdated.
7457 if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
7458 || scenePrivate->views.isEmpty()) {
7459 if (d_ptr->hasTranslateOnlySceneTransform()) {
7460 d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
7461 d_ptr->sceneTransform.dy()));
7463 d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect()));
7468 d_ptr->markParentDirty(/*updateBoundingRect=*/true);
7474 Highlights \a item as selected.
7476 NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in
7477 qgraphicssvgitem.cpp!
7479 static void qt_graphicsItem_highlightSelected(
7480 QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option)
7482 const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1));
7483 if (qFuzzyIsNull(qMax(murect.width(), murect.height())))
7486 const QRectF mbrect = painter->transform().mapRect(item->boundingRect());
7487 if (qMin(mbrect.width(), mbrect.height()) < qreal(1.0))
7491 switch (item->type()) {
7492 case QGraphicsEllipseItem::Type:
7493 itemPenWidth = static_cast<QGraphicsEllipseItem *>(item)->pen().widthF();
7495 case QGraphicsPathItem::Type:
7496 itemPenWidth = static_cast<QGraphicsPathItem *>(item)->pen().widthF();
7498 case QGraphicsPolygonItem::Type:
7499 itemPenWidth = static_cast<QGraphicsPolygonItem *>(item)->pen().widthF();
7501 case QGraphicsRectItem::Type:
7502 itemPenWidth = static_cast<QGraphicsRectItem *>(item)->pen().widthF();
7504 case QGraphicsSimpleTextItem::Type:
7505 itemPenWidth = static_cast<QGraphicsSimpleTextItem *>(item)->pen().widthF();
7507 case QGraphicsLineItem::Type:
7508 itemPenWidth = static_cast<QGraphicsLineItem *>(item)->pen().widthF();
7513 const qreal pad = itemPenWidth / 2;
7515 const qreal penWidth = 0; // cosmetic pen
7517 const QColor fgcolor = option->palette.windowText().color();
7518 const QColor bgcolor( // ensure good contrast against fgcolor
7519 fgcolor.red() > 127 ? 0 : 255,
7520 fgcolor.green() > 127 ? 0 : 255,
7521 fgcolor.blue() > 127 ? 0 : 255);
7523 painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
7524 painter->setBrush(Qt::NoBrush);
7525 painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
7527 painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
7528 painter->setBrush(Qt::NoBrush);
7529 painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
7533 \class QGraphicsObject
7534 \brief The QGraphicsObject class provides a base class for all graphics items that
7535 require signals, slots and properties.
7537 \ingroup graphicsview-api
7540 The class extends a QGraphicsItem with QObject's signal/slot and property mechanisms.
7541 It maps many of QGraphicsItem's basic setters and getters to properties and adds notification
7542 signals for many of them.
7544 \section1 Parents and Children
7546 Each graphics object can be constructed with a parent item. This ensures that the
7547 item will be destroyed when its parent item is destroyed. Although QGraphicsObject
7548 inherits from both QObject and QGraphicsItem, you should use the functions provided
7549 by QGraphicsItem, \e not QObject, to manage the relationships between parent and
7552 The relationships between items can be explored using the parentItem() and childItems()
7553 functions. In the hierarchy of items in a scene, the parentObject() and parentWidget()
7554 functions are the equivalent of the QWidget::parent() and QWidget::parentWidget()
7555 functions for QWidget subclasses.
7561 Constructs a QGraphicsObject with \a parent.
7563 QGraphicsObject::QGraphicsObject(QGraphicsItem *parent)
7564 : QGraphicsItem(parent)
7566 QGraphicsItem::d_ptr->isObject = true;
7572 QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent)
7573 : QGraphicsItem(dd, parent)
7575 QGraphicsItem::d_ptr->isObject = true;
7581 bool QGraphicsObject::event(QEvent *ev)
7583 if (ev->type() == QEvent::StyleAnimationUpdate) {
7587 return QObject::event(ev);
7590 #ifndef QT_NO_GESTURES
7592 Subscribes the graphics object to the given \a gesture with specific \a flags.
7594 \sa ungrabGesture(), QGestureEvent
7596 void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureFlags flags)
7598 bool contains = QGraphicsItem::d_ptr->gestureContext.contains(gesture);
7599 QGraphicsItem::d_ptr->gestureContext.insert(gesture, flags);
7600 if (!contains && QGraphicsItem::d_ptr->scene)
7601 QGraphicsItem::d_ptr->scene->d_func()->grabGesture(this, gesture);
7605 Unsubscribes the graphics object from the given \a gesture.
7607 \sa grabGesture(), QGestureEvent
7609 void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
7611 if (QGraphicsItem::d_ptr->gestureContext.remove(gesture) && QGraphicsItem::d_ptr->scene)
7612 QGraphicsItem::d_ptr->scene->d_func()->ungrabGesture(this, gesture);
7614 #endif // QT_NO_GESTURES
7617 Updates the item's micro focus. This is slot for convenience.
7623 void QGraphicsObject::updateMicroFocus()
7625 QGraphicsItem::updateMicroFocus();
7628 void QGraphicsItemPrivate::children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item)
7631 QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(list->object);
7632 if (QGraphicsItemPrivate::get(graphicsObject)->sendParentChangeNotification) {
7633 item->setParentItem(graphicsObject);
7635 QGraphicsItemPrivate::get(item)->setParentItemHelper(graphicsObject, 0, 0);
7640 int QGraphicsItemPrivate::children_count(QDeclarativeListProperty<QGraphicsObject> *list)
7642 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7643 return d->children.count();
7646 QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGraphicsObject> *list, int index)
7648 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7649 if (index >= 0 && index < d->children.count())
7650 return d->children.at(index)->toGraphicsObject();
7655 void QGraphicsItemPrivate::children_clear(QDeclarativeListProperty<QGraphicsObject> *list)
7657 QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
7658 int childCount = d->children.count();
7659 if (d->sendParentChangeNotification) {
7660 for (int index = 0; index < childCount; index++)
7661 d->children.at(0)->setParentItem(0);
7663 for (int index = 0; index < childCount; index++)
7664 QGraphicsItemPrivate::get(d->children.at(0))->setParentItemHelper(0, 0, 0);
7669 Returns a list of this item's children.
7671 The items are sorted by stacking order. This takes into account both the
7672 items' insertion order and their Z-values.
7675 QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList()
7679 QGraphicsObject *that = static_cast<QGraphicsObject *>(q);
7680 return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append,
7681 children_count, children_at, children_clear);
7683 //QGraphicsItem is not supported for this property
7684 return QDeclarativeListProperty<QGraphicsObject>();
7690 Returns the width of the item
7691 Reimplemented by QGraphicsWidget
7693 qreal QGraphicsItemPrivate::width() const
7700 Set the width of the item
7701 Reimplemented by QGraphicsWidget
7703 void QGraphicsItemPrivate::setWidth(qreal w)
7710 Reset the width of the item
7711 Reimplemented by QGraphicsWidget
7713 void QGraphicsItemPrivate::resetWidth()
7719 Returns the height of the item
7720 Reimplemented by QGraphicsWidget
7722 qreal QGraphicsItemPrivate::height() const
7729 Set the height of the item
7730 Reimplemented by QGraphicsWidget
7732 void QGraphicsItemPrivate::setHeight(qreal h)
7739 Reset the height of the item
7740 Reimplemented by QGraphicsWidget
7742 void QGraphicsItemPrivate::resetHeight()
7747 \property QGraphicsObject::children
7753 \property QGraphicsObject::width
7759 \property QGraphicsObject::height
7765 \property QGraphicsObject::parent
7766 \brief the parent of the item
7768 \note The item's parent is set independently of the parent object returned
7769 by QObject::parent().
7771 \sa QGraphicsItem::setParentItem(), QGraphicsItem::parentObject()
7775 \property QGraphicsObject::opacity
7776 \brief the opacity of the item
7778 \sa QGraphicsItem::setOpacity(), QGraphicsItem::opacity()
7782 \fn QGraphicsObject::opacityChanged()
7784 This signal gets emitted whenever the opacity of the item changes
7786 \sa QGraphicsItem::opacity()
7790 \fn QGraphicsObject::parentChanged()
7792 This signal gets emitted whenever the parent of the item changes
7796 \property QGraphicsObject::pos
7797 \brief the position of the item
7799 Describes the items position.
7801 \sa QGraphicsItem::setPos(), QGraphicsItem::pos()
7805 \property QGraphicsObject::x
7806 \brief the x position of the item
7808 Describes the items x position.
7810 \sa QGraphicsItem::setX(), setPos()
7814 \fn QGraphicsObject::xChanged()
7816 This signal gets emitted whenever the x position of the item changes
7822 \property QGraphicsObject::y
7823 \brief the y position of the item
7825 Describes the items y position.
7827 \sa QGraphicsItem::setY(), setPos()
7831 \fn QGraphicsObject::yChanged()
7833 This signal gets emitted whenever the y position of the item changes.
7839 \property QGraphicsObject::z
7840 \brief the z value of the item
7842 Describes the items z value.
7844 \sa QGraphicsItem::setZValue(), zValue()
7848 \fn QGraphicsObject::zChanged()
7850 This signal gets emitted whenever the z value of the item changes.
7856 \property QGraphicsObject::rotation
7857 This property holds the rotation of the item in degrees.
7859 This specifies how many degrees to rotate the item around its transformOrigin.
7860 The default rotation is 0 degrees (i.e. not rotated at all).
7864 \fn QGraphicsObject::rotationChanged()
7866 This signal gets emitted whenever the roation of the item changes.
7870 \property QGraphicsObject::scale
7871 This property holds the scale of the item.
7873 A scale of less than 1 means the item will be displayed smaller than
7874 normal, and a scale of greater than 1 means the item will be
7875 displayed larger than normal. A negative scale means the item will
7878 By default, items are displayed at a scale of 1 (i.e. at their
7881 Scaling is from the item's transformOrigin.
7885 \fn void QGraphicsObject::scaleChanged()
7887 This signal is emitted when the scale of the item changes.
7892 \property QGraphicsObject::enabled
7893 \brief whether the item is enabled or not
7895 This property is declared in QGraphicsItem.
7897 By default, this property is true.
7899 \sa QGraphicsItem::isEnabled(), QGraphicsItem::setEnabled()
7903 \fn void QGraphicsObject::enabledChanged()
7905 This signal gets emitted whenever the item get's enabled or disabled.
7911 \property QGraphicsObject::visible
7912 \brief whether the item is visible or not
7914 This property is declared in QGraphicsItem.
7916 By default, this property is true.
7918 \sa QGraphicsItem::isVisible(), QGraphicsItem::setVisible()
7922 \fn QGraphicsObject::visibleChanged()
7924 This signal gets emitted whenever the visibility of the item changes
7930 \fn const QObjectList &QGraphicsObject::children() const
7933 This function returns the same value as QObject::children(). It's
7934 provided to differentiate between the obsolete member
7935 QGraphicsItem::children() and QObject::children(). QGraphicsItem now
7936 provides childItems() instead.
7940 \property QGraphicsObject::transformOriginPoint
7941 \brief the transformation origin
7943 This property sets a specific point in the items coordiante system as the
7944 origin for scale and rotation.
7946 \sa scale, rotation, QGraphicsItem::transformOriginPoint()
7950 \fn void QGraphicsObject::widthChanged()
7955 \fn void QGraphicsObject::heightChanged()
7961 \fn QGraphicsObject::childrenChanged()
7963 This signal gets emitted whenever the children list changes
7968 \property QGraphicsObject::effect
7970 \brief the effect attached to this item
7972 \sa QGraphicsItem::setGraphicsEffect(), QGraphicsItem::graphicsEffect()
7976 \class QAbstractGraphicsShapeItem
7977 \brief The QAbstractGraphicsShapeItem class provides a common base for
7980 \ingroup graphicsview-api
7983 This class does not fully implement an item by itself; in particular, it
7984 does not implement boundingRect() and paint(), which are inherited by
7987 You can subclass this item to provide a simple base implementation of
7988 accessors for the item's pen and brush.
7990 \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPathItem,
7991 QGraphicsPolygonItem, QGraphicsTextItem, QGraphicsLineItem,
7992 QGraphicsPixmapItem, {Graphics View Framework}
7995 class QAbstractGraphicsShapeItemPrivate : public QGraphicsItemPrivate
7997 Q_DECLARE_PUBLIC(QAbstractGraphicsShapeItem)
8003 // Cached bounding rectangle
8004 mutable QRectF boundingRect;
8008 Constructs a QAbstractGraphicsShapeItem. \a parent is passed to
8009 QGraphicsItem's constructor.
8011 QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QGraphicsItem *parent)
8012 : QGraphicsItem(*new QAbstractGraphicsShapeItemPrivate, parent)
8019 QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QAbstractGraphicsShapeItemPrivate &dd, QGraphicsItem *parent)
8020 : QGraphicsItem(dd, parent)
8025 Destroys a QAbstractGraphicsShapeItem.
8027 QAbstractGraphicsShapeItem::~QAbstractGraphicsShapeItem()
8032 Returns the item's pen. If no pen has been set, this function returns
8033 QPen(), a default black solid line pen with 1 width.
8035 QPen QAbstractGraphicsShapeItem::pen() const
8037 Q_D(const QAbstractGraphicsShapeItem);
8042 Sets the pen for this item to \a pen.
8044 The pen is used to draw the item's outline.
8048 void QAbstractGraphicsShapeItem::setPen(const QPen &pen)
8050 Q_D(QAbstractGraphicsShapeItem);
8053 prepareGeometryChange();
8055 d->boundingRect = QRectF();
8060 Returns the item's brush, or an empty brush if no brush has been set.
8064 QBrush QAbstractGraphicsShapeItem::brush() const
8066 Q_D(const QAbstractGraphicsShapeItem);
8071 Sets the item's brush to \a brush.
8073 The item's brush is used to fill the item.
8075 If you use a brush with a QGradient, the gradient
8076 is relative to the item's coordinate system.
8080 void QAbstractGraphicsShapeItem::setBrush(const QBrush &brush)
8082 Q_D(QAbstractGraphicsShapeItem);
8083 if (d->brush == brush)
8092 bool QAbstractGraphicsShapeItem::isObscuredBy(const QGraphicsItem *item) const
8094 return QGraphicsItem::isObscuredBy(item);
8100 QPainterPath QAbstractGraphicsShapeItem::opaqueArea() const
8102 Q_D(const QAbstractGraphicsShapeItem);
8103 if (d->brush.isOpaque())
8104 return isClipped() ? clipPath() : shape();
8105 return QGraphicsItem::opaqueArea();
8109 \class QGraphicsPathItem
8110 \brief The QGraphicsPathItem class provides a path item that you
8111 can add to a QGraphicsScene.
8113 \ingroup graphicsview-api
8116 To set the item's path, pass a QPainterPath to QGraphicsPathItem's
8117 constructor, or call the setPath() function. The path() function
8118 returns the current path.
8120 \image graphicsview-pathitem.png
8122 QGraphicsPathItem uses the path to provide a reasonable
8123 implementation of boundingRect(), shape(), and contains(). The
8124 paint() function draws the path using the item's associated pen
8125 and brush, which you can set by calling the setPen() and
8126 setBrush() functions.
8128 \sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
8129 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8133 class QGraphicsPathItemPrivate : public QAbstractGraphicsShapeItemPrivate
8135 Q_DECLARE_PUBLIC(QGraphicsPathItem)
8141 Constructs a QGraphicsPath item using \a path as the default path. \a
8142 parent is passed to QAbstractGraphicsShapeItem's constructor.
8144 \sa QGraphicsScene::addItem()
8146 QGraphicsPathItem::QGraphicsPathItem(const QPainterPath &path,
8147 QGraphicsItem *parent)
8148 : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent)
8150 if (!path.isEmpty())
8155 Constructs a QGraphicsPath. \a parent is passed to
8156 QAbstractGraphicsShapeItem's constructor.
8158 \sa QGraphicsScene::addItem()
8160 QGraphicsPathItem::QGraphicsPathItem(QGraphicsItem *parent)
8161 : QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent)
8166 Destroys the QGraphicsPathItem.
8168 QGraphicsPathItem::~QGraphicsPathItem()
8173 Returns the item's path as a QPainterPath. If no item has been set, an
8174 empty QPainterPath is returned.
8178 QPainterPath QGraphicsPathItem::path() const
8180 Q_D(const QGraphicsPathItem);
8185 Sets the item's path to be the given \a path.
8189 void QGraphicsPathItem::setPath(const QPainterPath &path)
8191 Q_D(QGraphicsPathItem);
8192 if (d->path == path)
8194 prepareGeometryChange();
8196 d->boundingRect = QRectF();
8203 QRectF QGraphicsPathItem::boundingRect() const
8205 Q_D(const QGraphicsPathItem);
8206 if (d->boundingRect.isNull()) {
8207 qreal pw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF();
8209 d->boundingRect = d->path.controlPointRect();
8211 d->boundingRect = shape().controlPointRect();
8214 return d->boundingRect;
8220 QPainterPath QGraphicsPathItem::shape() const
8222 Q_D(const QGraphicsPathItem);
8223 return qt_graphicsItem_shapeFromPath(d->path, d->pen);
8229 bool QGraphicsPathItem::contains(const QPointF &point) const
8231 return QAbstractGraphicsShapeItem::contains(point);
8237 void QGraphicsPathItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8240 Q_D(QGraphicsPathItem);
8242 painter->setPen(d->pen);
8243 painter->setBrush(d->brush);
8244 painter->drawPath(d->path);
8246 if (option->state & QStyle::State_Selected)
8247 qt_graphicsItem_highlightSelected(this, painter, option);
8253 bool QGraphicsPathItem::isObscuredBy(const QGraphicsItem *item) const
8255 return QAbstractGraphicsShapeItem::isObscuredBy(item);
8261 QPainterPath QGraphicsPathItem::opaqueArea() const
8263 return QAbstractGraphicsShapeItem::opaqueArea();
8269 int QGraphicsPathItem::type() const
8277 bool QGraphicsPathItem::supportsExtension(Extension extension) const
8279 Q_UNUSED(extension);
8286 void QGraphicsPathItem::setExtension(Extension extension, const QVariant &variant)
8288 Q_UNUSED(extension);
8295 QVariant QGraphicsPathItem::extension(const QVariant &variant) const
8302 \class QGraphicsRectItem
8303 \brief The QGraphicsRectItem class provides a rectangle item that you
8304 can add to a QGraphicsScene.
8306 \ingroup graphicsview-api
8309 To set the item's rectangle, pass a QRectF to QGraphicsRectItem's
8310 constructor, or call the setRect() function. The rect() function
8311 returns the current rectangle.
8313 \image graphicsview-rectitem.png
8315 QGraphicsRectItem uses the rectangle and the pen width to provide
8316 a reasonable implementation of boundingRect(), shape(), and
8317 contains(). The paint() function draws the rectangle using the
8318 item's associated pen and brush, which you can set by calling the
8319 setPen() and setBrush() functions.
8321 \note The rendering of invalid rectangles, such as those with negative
8322 widths or heights, is undefined. If you cannot be sure that you are
8323 using valid rectangles (for example, if you are creating
8324 rectangles using data from an unreliable source) then you should
8325 use QRectF::normalized() to create normalized rectangles, and use
8328 \sa QGraphicsPathItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
8329 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8333 class QGraphicsRectItemPrivate : public QAbstractGraphicsShapeItemPrivate
8335 Q_DECLARE_PUBLIC(QGraphicsRectItem)
8341 Constructs a QGraphicsRectItem, using \a rect as the default rectangle.
8342 \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8344 \sa QGraphicsScene::addItem()
8346 QGraphicsRectItem::QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent)
8347 : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent)
8353 \fn QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal width, qreal height,
8354 QGraphicsItem *parent)
8356 Constructs a QGraphicsRectItem with a default rectangle defined
8357 by (\a x, \a y) and the given \a width and \a height.
8359 \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8361 \sa QGraphicsScene::addItem()
8363 QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h,
8364 QGraphicsItem *parent)
8365 : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent)
8367 setRect(QRectF(x, y, w, h));
8371 Constructs a QGraphicsRectItem. \a parent is passed to
8372 QAbstractGraphicsShapeItem's constructor.
8374 \sa QGraphicsScene::addItem()
8376 QGraphicsRectItem::QGraphicsRectItem(QGraphicsItem *parent)
8377 : QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent)
8382 Destroys the QGraphicsRectItem.
8384 QGraphicsRectItem::~QGraphicsRectItem()
8389 Returns the item's rectangle.
8393 QRectF QGraphicsRectItem::rect() const
8395 Q_D(const QGraphicsRectItem);
8400 \fn void QGraphicsRectItem::setRect(const QRectF &rectangle)
8402 Sets the item's rectangle to be the given \a rectangle.
8406 void QGraphicsRectItem::setRect(const QRectF &rect)
8408 Q_D(QGraphicsRectItem);
8409 if (d->rect == rect)
8411 prepareGeometryChange();
8413 d->boundingRect = QRectF();
8418 \fn void QGraphicsRectItem::setRect(qreal x, qreal y, qreal width, qreal height)
8419 \fn void QGraphicsEllipseItem::setRect(qreal x, qreal y, qreal width, qreal height)
8421 Sets the item's rectangle to the rectangle defined by (\a x, \a y)
8422 and the given \a width and \a height.
8424 This convenience function is equivalent to calling \c
8425 {setRect(QRectF(x, y, width, height))}
8433 QRectF QGraphicsRectItem::boundingRect() const
8435 Q_D(const QGraphicsRectItem);
8436 if (d->boundingRect.isNull()) {
8437 qreal halfpw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF() / 2;
8438 d->boundingRect = d->rect;
8440 d->boundingRect.adjust(-halfpw, -halfpw, halfpw, halfpw);
8442 return d->boundingRect;
8448 QPainterPath QGraphicsRectItem::shape() const
8450 Q_D(const QGraphicsRectItem);
8452 path.addRect(d->rect);
8453 return qt_graphicsItem_shapeFromPath(path, d->pen);
8459 bool QGraphicsRectItem::contains(const QPointF &point) const
8461 return QAbstractGraphicsShapeItem::contains(point);
8467 void QGraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8470 Q_D(QGraphicsRectItem);
8472 painter->setPen(d->pen);
8473 painter->setBrush(d->brush);
8474 painter->drawRect(d->rect);
8476 if (option->state & QStyle::State_Selected)
8477 qt_graphicsItem_highlightSelected(this, painter, option);
8483 bool QGraphicsRectItem::isObscuredBy(const QGraphicsItem *item) const
8485 return QAbstractGraphicsShapeItem::isObscuredBy(item);
8491 QPainterPath QGraphicsRectItem::opaqueArea() const
8493 return QAbstractGraphicsShapeItem::opaqueArea();
8499 int QGraphicsRectItem::type() const
8507 bool QGraphicsRectItem::supportsExtension(Extension extension) const
8509 Q_UNUSED(extension);
8516 void QGraphicsRectItem::setExtension(Extension extension, const QVariant &variant)
8518 Q_UNUSED(extension);
8525 QVariant QGraphicsRectItem::extension(const QVariant &variant) const
8532 \class QGraphicsEllipseItem
8533 \brief The QGraphicsEllipseItem class provides an ellipse item that you
8534 can add to a QGraphicsScene.
8536 \ingroup graphicsview-api
8539 QGraphicsEllipseItem respresents an ellipse with a fill and an outline,
8540 and you can also use it for ellipse segments (see startAngle(),
8545 \li \inlineimage graphicsview-ellipseitem.png
8546 \li \inlineimage graphicsview-ellipseitem-pie.png
8549 To set the item's ellipse, pass a QRectF to QGraphicsEllipseItem's
8550 constructor, or call setRect(). The rect() function returns the
8551 current ellipse geometry.
8553 QGraphicsEllipseItem uses the rect and the pen width to provide a
8554 reasonable implementation of boundingRect(), shape(), and contains(). The
8555 paint() function draws the ellipse using the item's associated pen and
8556 brush, which you can set by calling setPen() and setBrush().
8558 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsPolygonItem,
8559 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8563 class QGraphicsEllipseItemPrivate : public QAbstractGraphicsShapeItemPrivate
8565 Q_DECLARE_PUBLIC(QGraphicsEllipseItem)
8567 inline QGraphicsEllipseItemPrivate()
8568 : startAngle(0), spanAngle(360 * 16)
8577 Constructs a QGraphicsEllipseItem using \a rect as the default rectangle.
8578 \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8580 \sa QGraphicsScene::addItem()
8582 QGraphicsEllipseItem::QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent)
8583 : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent)
8589 \fn QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent)
8592 Constructs a QGraphicsEllipseItem using the rectangle defined by (\a x, \a
8593 y) and the given \a width and \a height, as the default rectangle. \a
8594 parent is passed to QAbstractGraphicsShapeItem's constructor.
8596 \sa QGraphicsScene::addItem()
8598 QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h,
8599 QGraphicsItem *parent)
8600 : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent)
8608 Constructs a QGraphicsEllipseItem. \a parent is passed to
8609 QAbstractGraphicsShapeItem's constructor.
8611 \sa QGraphicsScene::addItem()
8613 QGraphicsEllipseItem::QGraphicsEllipseItem(QGraphicsItem *parent)
8614 : QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent)
8619 Destroys the QGraphicsEllipseItem.
8621 QGraphicsEllipseItem::~QGraphicsEllipseItem()
8626 Returns the item's ellipse geometry as a QRectF.
8628 \sa setRect(), QPainter::drawEllipse()
8630 QRectF QGraphicsEllipseItem::rect() const
8632 Q_D(const QGraphicsEllipseItem);
8637 Sets the item's ellipse geometry to \a rect. The rectangle's left edge
8638 defines the left edge of the ellipse, and the rectangle's top edge
8639 describes the top of the ellipse. The height and width of the rectangle
8640 describe the height and width of the ellipse.
8642 \sa rect(), QPainter::drawEllipse()
8644 void QGraphicsEllipseItem::setRect(const QRectF &rect)
8646 Q_D(QGraphicsEllipseItem);
8647 if (d->rect == rect)
8649 prepareGeometryChange();
8651 d->boundingRect = QRectF();
8656 Returns the start angle for an ellipse segment in 16ths of a degree. This
8657 angle is used together with spanAngle() for representing an ellipse
8658 segment (a pie). By default, the start angle is 0.
8660 \sa setStartAngle(), spanAngle()
8662 int QGraphicsEllipseItem::startAngle() const
8664 Q_D(const QGraphicsEllipseItem);
8665 return d->startAngle;
8669 Sets the start angle for an ellipse segment to \a angle, which is in 16ths
8670 of a degree. This angle is used together with spanAngle() for representing
8671 an ellipse segment (a pie). By default, the start angle is 0.
8673 \sa startAngle(), setSpanAngle(), QPainter::drawPie()
8675 void QGraphicsEllipseItem::setStartAngle(int angle)
8677 Q_D(QGraphicsEllipseItem);
8678 if (angle != d->startAngle) {
8679 prepareGeometryChange();
8680 d->boundingRect = QRectF();
8681 d->startAngle = angle;
8687 Returns the span angle of an ellipse segment in 16ths of a degree. This
8688 angle is used together with startAngle() for representing an ellipse
8689 segment (a pie). By default, this function returns 5760 (360 * 16, a full
8692 \sa setSpanAngle(), startAngle()
8694 int QGraphicsEllipseItem::spanAngle() const
8696 Q_D(const QGraphicsEllipseItem);
8697 return d->spanAngle;
8701 Sets the span angle for an ellipse segment to \a angle, which is in 16ths
8702 of a degree. This angle is used together with startAngle() to represent an
8703 ellipse segment (a pie). By default, the span angle is 5760 (360 * 16, a
8706 \sa spanAngle(), setStartAngle(), QPainter::drawPie()
8708 void QGraphicsEllipseItem::setSpanAngle(int angle)
8710 Q_D(QGraphicsEllipseItem);
8711 if (angle != d->spanAngle) {
8712 prepareGeometryChange();
8713 d->boundingRect = QRectF();
8714 d->spanAngle = angle;
8722 QRectF QGraphicsEllipseItem::boundingRect() const
8724 Q_D(const QGraphicsEllipseItem);
8725 if (d->boundingRect.isNull()) {
8726 qreal pw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF();
8727 if (pw == 0.0 && d->spanAngle == 360 * 16)
8728 d->boundingRect = d->rect;
8730 d->boundingRect = shape().controlPointRect();
8732 return d->boundingRect;
8738 QPainterPath QGraphicsEllipseItem::shape() const
8740 Q_D(const QGraphicsEllipseItem);
8742 if (d->rect.isNull())
8744 if (d->spanAngle != 360 * 16) {
8745 path.moveTo(d->rect.center());
8746 path.arcTo(d->rect, d->startAngle / 16.0, d->spanAngle / 16.0);
8748 path.addEllipse(d->rect);
8751 return qt_graphicsItem_shapeFromPath(path, d->pen);
8757 bool QGraphicsEllipseItem::contains(const QPointF &point) const
8759 return QAbstractGraphicsShapeItem::contains(point);
8765 void QGraphicsEllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
8768 Q_D(QGraphicsEllipseItem);
8770 painter->setPen(d->pen);
8771 painter->setBrush(d->brush);
8772 if ((d->spanAngle != 0) && (qAbs(d->spanAngle) % (360 * 16) == 0))
8773 painter->drawEllipse(d->rect);
8775 painter->drawPie(d->rect, d->startAngle, d->spanAngle);
8777 if (option->state & QStyle::State_Selected)
8778 qt_graphicsItem_highlightSelected(this, painter, option);
8784 bool QGraphicsEllipseItem::isObscuredBy(const QGraphicsItem *item) const
8786 return QAbstractGraphicsShapeItem::isObscuredBy(item);
8792 QPainterPath QGraphicsEllipseItem::opaqueArea() const
8794 return QAbstractGraphicsShapeItem::opaqueArea();
8800 int QGraphicsEllipseItem::type() const
8809 bool QGraphicsEllipseItem::supportsExtension(Extension extension) const
8811 Q_UNUSED(extension);
8818 void QGraphicsEllipseItem::setExtension(Extension extension, const QVariant &variant)
8820 Q_UNUSED(extension);
8827 QVariant QGraphicsEllipseItem::extension(const QVariant &variant) const
8834 \class QGraphicsPolygonItem
8835 \brief The QGraphicsPolygonItem class provides a polygon item that you
8836 can add to a QGraphicsScene.
8838 \ingroup graphicsview-api
8841 To set the item's polygon, pass a QPolygonF to
8842 QGraphicsPolygonItem's constructor, or call the setPolygon()
8843 function. The polygon() function returns the current polygon.
8845 \image graphicsview-polygonitem.png
8847 QGraphicsPolygonItem uses the polygon and the pen width to provide
8848 a reasonable implementation of boundingRect(), shape(), and
8849 contains(). The paint() function draws the polygon using the
8850 item's associated pen and brush, which you can set by calling the
8851 setPen() and setBrush() functions.
8853 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
8854 QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {Graphics
8858 class QGraphicsPolygonItemPrivate : public QAbstractGraphicsShapeItemPrivate
8860 Q_DECLARE_PUBLIC(QGraphicsPolygonItem)
8862 inline QGraphicsPolygonItemPrivate()
8863 : fillRule(Qt::OddEvenFill)
8867 Qt::FillRule fillRule;
8871 Constructs a QGraphicsPolygonItem with \a polygon as the default
8872 polygon. \a parent is passed to QAbstractGraphicsShapeItem's constructor.
8874 \sa QGraphicsScene::addItem()
8876 QGraphicsPolygonItem::QGraphicsPolygonItem(const QPolygonF &polygon, QGraphicsItem *parent)
8877 : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent)
8879 setPolygon(polygon);
8883 Constructs a QGraphicsPolygonItem. \a parent is passed to
8884 QAbstractGraphicsShapeItem's constructor.
8886 \sa QGraphicsScene::addItem()
8888 QGraphicsPolygonItem::QGraphicsPolygonItem(QGraphicsItem *parent)
8889 : QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent)
8894 Destroys the QGraphicsPolygonItem.
8896 QGraphicsPolygonItem::~QGraphicsPolygonItem()
8901 Returns the item's polygon, or an empty polygon if no polygon
8906 QPolygonF QGraphicsPolygonItem::polygon() const
8908 Q_D(const QGraphicsPolygonItem);
8913 Sets the item's polygon to be the given \a polygon.
8917 void QGraphicsPolygonItem::setPolygon(const QPolygonF &polygon)
8919 Q_D(QGraphicsPolygonItem);
8920 if (d->polygon == polygon)
8922 prepareGeometryChange();
8923 d->polygon = polygon;
8924 d->boundingRect = QRectF();
8929 Returns the fill rule of the polygon. The default fill rule is
8932 \sa setFillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
8934 Qt::FillRule QGraphicsPolygonItem::fillRule() const
8936 Q_D(const QGraphicsPolygonItem);
8941 Sets the fill rule of the polygon to \a rule. The default fill rule is
8944 \sa fillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
8946 void QGraphicsPolygonItem::setFillRule(Qt::FillRule rule)
8948 Q_D(QGraphicsPolygonItem);
8949 if (rule != d->fillRule) {
8958 QRectF QGraphicsPolygonItem::boundingRect() const
8960 Q_D(const QGraphicsPolygonItem);
8961 if (d->boundingRect.isNull()) {
8962 qreal pw = pen().style() == Qt::NoPen ? qreal(0) : pen().widthF();
8964 d->boundingRect = d->polygon.boundingRect();
8966 d->boundingRect = shape().controlPointRect();
8968 return d->boundingRect;
8974 QPainterPath QGraphicsPolygonItem::shape() const
8976 Q_D(const QGraphicsPolygonItem);
8978 path.addPolygon(d->polygon);
8979 return qt_graphicsItem_shapeFromPath(path, d->pen);
8985 bool QGraphicsPolygonItem::contains(const QPointF &point) const
8987 return QAbstractGraphicsShapeItem::contains(point);
8993 void QGraphicsPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
8995 Q_D(QGraphicsPolygonItem);
8997 painter->setPen(d->pen);
8998 painter->setBrush(d->brush);
8999 painter->drawPolygon(d->polygon, d->fillRule);
9001 if (option->state & QStyle::State_Selected)
9002 qt_graphicsItem_highlightSelected(this, painter, option);
9008 bool QGraphicsPolygonItem::isObscuredBy(const QGraphicsItem *item) const
9010 return QAbstractGraphicsShapeItem::isObscuredBy(item);
9016 QPainterPath QGraphicsPolygonItem::opaqueArea() const
9018 return QAbstractGraphicsShapeItem::opaqueArea();
9024 int QGraphicsPolygonItem::type() const
9032 bool QGraphicsPolygonItem::supportsExtension(Extension extension) const
9034 Q_UNUSED(extension);
9041 void QGraphicsPolygonItem::setExtension(Extension extension, const QVariant &variant)
9043 Q_UNUSED(extension);
9050 QVariant QGraphicsPolygonItem::extension(const QVariant &variant) const
9057 \class QGraphicsLineItem
9058 \brief The QGraphicsLineItem class provides a line item that you can add to a
9061 \ingroup graphicsview-api
9064 To set the item's line, pass a QLineF to QGraphicsLineItem's
9065 constructor, or call the setLine() function. The line() function
9066 returns the current line. By default the line is black with a
9067 width of 0, but you can change this by calling setPen().
9069 \image graphicsview-lineitem.png
9071 QGraphicsLineItem uses the line and the pen width to provide a reasonable
9072 implementation of boundingRect(), shape(), and contains(). The paint()
9073 function draws the line using the item's associated pen.
9075 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
9076 QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsPixmapItem,
9077 {Graphics View Framework}
9080 class QGraphicsLineItemPrivate : public QGraphicsItemPrivate
9082 Q_DECLARE_PUBLIC(QGraphicsLineItem)
9089 Constructs a QGraphicsLineItem, using \a line as the default line. \a
9090 parent is passed to QGraphicsItem's constructor.
9092 \sa QGraphicsScene::addItem()
9094 QGraphicsLineItem::QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent)
9095 : QGraphicsItem(*new QGraphicsLineItemPrivate, parent)
9101 Constructs a QGraphicsLineItem, using the line between (\a x1, \a y1) and
9102 (\a x2, \a y2) as the default line. \a parent is passed to
9103 QGraphicsItem's constructor.
9105 \sa QGraphicsScene::addItem()
9107 QGraphicsLineItem::QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent)
9108 : QGraphicsItem(*new QGraphicsLineItemPrivate, parent)
9110 setLine(x1, y1, x2, y2);
9116 Constructs a QGraphicsLineItem. \a parent is passed to QGraphicsItem's
9119 \sa QGraphicsScene::addItem()
9121 QGraphicsLineItem::QGraphicsLineItem(QGraphicsItem *parent)
9122 : QGraphicsItem(*new QGraphicsLineItemPrivate, parent)
9127 Destroys the QGraphicsLineItem.
9129 QGraphicsLineItem::~QGraphicsLineItem()
9134 Returns the item's pen, or a black solid 0-width pen if no pen has
9139 QPen QGraphicsLineItem::pen() const
9141 Q_D(const QGraphicsLineItem);
9146 Sets the item's pen to \a pen. If no pen is set, the line will be painted
9147 using a black solid 0-width pen.
9151 void QGraphicsLineItem::setPen(const QPen &pen)
9153 Q_D(QGraphicsLineItem);
9156 prepareGeometryChange();
9162 Returns the item's line, or a null line if no line has been set.
9166 QLineF QGraphicsLineItem::line() const
9168 Q_D(const QGraphicsLineItem);
9173 Sets the item's line to be the given \a line.
9177 void QGraphicsLineItem::setLine(const QLineF &line)
9179 Q_D(QGraphicsLineItem);
9180 if (d->line == line)
9182 prepareGeometryChange();
9188 \fn void QGraphicsLineItem::setLine(qreal x1, qreal y1, qreal x2, qreal y2)
9191 Sets the item's line to be the line between (\a x1, \a y1) and (\a
9194 This is the same as calling \c {setLine(QLineF(x1, y1, x2, y2))}.
9200 QRectF QGraphicsLineItem::boundingRect() const
9202 Q_D(const QGraphicsLineItem);
9203 if (d->pen.widthF() == 0.0) {
9204 const qreal x1 = d->line.p1().x();
9205 const qreal x2 = d->line.p2().x();
9206 const qreal y1 = d->line.p1().y();
9207 const qreal y2 = d->line.p2().y();
9208 qreal lx = qMin(x1, x2);
9209 qreal rx = qMax(x1, x2);
9210 qreal ty = qMin(y1, y2);
9211 qreal by = qMax(y1, y2);
9212 return QRectF(lx, ty, rx - lx, by - ty);
9214 return shape().controlPointRect();
9220 QPainterPath QGraphicsLineItem::shape() const
9222 Q_D(const QGraphicsLineItem);
9224 if (d->line == QLineF())
9227 path.moveTo(d->line.p1());
9228 path.lineTo(d->line.p2());
9229 return qt_graphicsItem_shapeFromPath(path, d->pen);
9235 bool QGraphicsLineItem::contains(const QPointF &point) const
9237 return QGraphicsItem::contains(point);
9243 void QGraphicsLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
9245 Q_D(QGraphicsLineItem);
9247 painter->setPen(d->pen);
9248 painter->drawLine(d->line);
9250 if (option->state & QStyle::State_Selected)
9251 qt_graphicsItem_highlightSelected(this, painter, option);
9257 bool QGraphicsLineItem::isObscuredBy(const QGraphicsItem *item) const
9259 return QGraphicsItem::isObscuredBy(item);
9265 QPainterPath QGraphicsLineItem::opaqueArea() const
9267 return QGraphicsItem::opaqueArea();
9273 int QGraphicsLineItem::type() const
9281 bool QGraphicsLineItem::supportsExtension(Extension extension) const
9283 Q_UNUSED(extension);
9290 void QGraphicsLineItem::setExtension(Extension extension, const QVariant &variant)
9292 Q_UNUSED(extension);
9299 QVariant QGraphicsLineItem::extension(const QVariant &variant) const
9306 \class QGraphicsPixmapItem
9307 \brief The QGraphicsPixmapItem class provides a pixmap item that you can add to
9310 \ingroup graphicsview-api
9313 To set the item's pixmap, pass a QPixmap to QGraphicsPixmapItem's
9314 constructor, or call the setPixmap() function. The pixmap()
9315 function returns the current pixmap.
9317 QGraphicsPixmapItem uses pixmap's optional alpha mask to provide a
9318 reasonable implementation of boundingRect(), shape(), and contains().
9320 \image graphicsview-pixmapitem.png
9322 The pixmap is drawn at the item's (0, 0) coordinate, as returned by
9323 offset(). You can change the drawing offset by calling setOffset().
9325 You can set the pixmap's transformation mode by calling
9326 setTransformationMode(). By default, Qt::FastTransformation is used, which
9327 provides fast, non-smooth scaling. Qt::SmoothTransformation enables
9328 QPainter::SmoothPixmapTransform on the painter, and the quality depends on
9329 the platform and viewport. The result is usually not as good as calling
9330 QPixmap::scale() directly. Call transformationMode() to get the current
9331 transformation mode for the item.
9333 \sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
9334 QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsLineItem,
9335 {Graphics View Framework}
9339 \enum QGraphicsPixmapItem::ShapeMode
9341 This enum describes how QGraphicsPixmapItem calculates its shape and
9344 The default value is MaskShape.
9346 \value MaskShape The shape is determined by calling QPixmap::mask().
9347 This shape includes only the opaque pixels of the pixmap.
9348 Because the shape is more complex, however, it can be slower than the other modes,
9349 and uses more memory.
9351 \value BoundingRectShape The shape is determined by tracing the outline of
9352 the pixmap. This is the fastest shape mode, but it does not take into account
9353 any transparent areas on the pixmap.
9355 \value HeuristicMaskShape The shape is determine by calling
9356 QPixmap::createHeuristicMask(). The performance and memory consumption
9357 is similar to MaskShape.
9359 extern QPainterPath qt_regionToPath(const QRegion ®ion);
9361 class QGraphicsPixmapItemPrivate : public QGraphicsItemPrivate
9363 Q_DECLARE_PUBLIC(QGraphicsPixmapItem)
9365 QGraphicsPixmapItemPrivate()
9366 : transformationMode(Qt::FastTransformation),
9367 shapeMode(QGraphicsPixmapItem::MaskShape),
9372 Qt::TransformationMode transformationMode;
9374 QGraphicsPixmapItem::ShapeMode shapeMode;
9380 shape = QPainterPath();
9381 switch (shapeMode) {
9382 case QGraphicsPixmapItem::MaskShape: {
9383 QBitmap mask = pixmap.mask();
9384 if (!mask.isNull()) {
9385 shape = qt_regionToPath(QRegion(mask).translated(offset.toPoint()));
9390 case QGraphicsPixmapItem::BoundingRectShape:
9391 shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
9393 case QGraphicsPixmapItem::HeuristicMaskShape:
9394 #ifndef QT_NO_IMAGE_HEURISTIC_MASK
9395 shape = qt_regionToPath(QRegion(pixmap.createHeuristicMask()).translated(offset.toPoint()));
9397 shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
9405 Constructs a QGraphicsPixmapItem, using \a pixmap as the default pixmap.
9406 \a parent is passed to QGraphicsItem's constructor.
9408 \sa QGraphicsScene::addItem()
9410 QGraphicsPixmapItem::QGraphicsPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent)
9411 : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent)
9417 Constructs a QGraphicsPixmapItem. \a parent is passed to QGraphicsItem's
9420 \sa QGraphicsScene::addItem()
9422 QGraphicsPixmapItem::QGraphicsPixmapItem(QGraphicsItem *parent)
9423 : QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent)
9428 Destroys the QGraphicsPixmapItem.
9430 QGraphicsPixmapItem::~QGraphicsPixmapItem()
9435 Sets the item's pixmap to \a pixmap.
9439 void QGraphicsPixmapItem::setPixmap(const QPixmap &pixmap)
9441 Q_D(QGraphicsPixmapItem);
9442 prepareGeometryChange();
9444 d->hasShape = false;
9449 Returns the item's pixmap, or an invalid QPixmap if no pixmap has been
9454 QPixmap QGraphicsPixmapItem::pixmap() const
9456 Q_D(const QGraphicsPixmapItem);
9461 Returns the transformation mode of the pixmap. The default mode is
9462 Qt::FastTransformation, which provides quick transformation with no
9465 \sa setTransformationMode()
9467 Qt::TransformationMode QGraphicsPixmapItem::transformationMode() const
9469 Q_D(const QGraphicsPixmapItem);
9470 return d->transformationMode;
9474 Sets the pixmap item's transformation mode to \a mode, and toggles an
9475 update of the item. The default mode is Qt::FastTransformation, which
9476 provides quick transformation with no smoothing.
9478 Qt::SmoothTransformation enables QPainter::SmoothPixmapTransform on the
9479 painter, and the quality depends on the platform and viewport. The result
9480 is usually not as good as calling QPixmap::scale() directly.
9482 \sa transformationMode()
9484 void QGraphicsPixmapItem::setTransformationMode(Qt::TransformationMode mode)
9486 Q_D(QGraphicsPixmapItem);
9487 if (mode != d->transformationMode) {
9488 d->transformationMode = mode;
9494 Returns the pixmap item's \e offset, which defines the point of the
9495 top-left corner of the pixmap, in local coordinates.
9499 QPointF QGraphicsPixmapItem::offset() const
9501 Q_D(const QGraphicsPixmapItem);
9506 Sets the pixmap item's offset to \a offset. QGraphicsPixmapItem will draw
9507 its pixmap using \a offset for its top-left corner.
9511 void QGraphicsPixmapItem::setOffset(const QPointF &offset)
9513 Q_D(QGraphicsPixmapItem);
9514 if (d->offset == offset)
9516 prepareGeometryChange();
9518 d->hasShape = false;
9523 \fn void QGraphicsPixmapItem::setOffset(qreal x, qreal y)
9526 This convenience function is equivalent to calling setOffset(QPointF(\a x, \a y)).
9532 QRectF QGraphicsPixmapItem::boundingRect() const
9534 Q_D(const QGraphicsPixmapItem);
9535 if (d->pixmap.isNull())
9537 if (d->flags & ItemIsSelectable) {
9539 return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
9541 return QRectF(d->offset, d->pixmap.size());
9548 QPainterPath QGraphicsPixmapItem::shape() const
9550 Q_D(const QGraphicsPixmapItem);
9552 QGraphicsPixmapItemPrivate *thatD = const_cast<QGraphicsPixmapItemPrivate *>(d);
9553 thatD->updateShape();
9554 thatD->hasShape = true;
9556 return d_func()->shape;
9562 bool QGraphicsPixmapItem::contains(const QPointF &point) const
9564 return QGraphicsItem::contains(point);
9570 void QGraphicsPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
9573 Q_D(QGraphicsPixmapItem);
9576 painter->setRenderHint(QPainter::SmoothPixmapTransform,
9577 (d->transformationMode == Qt::SmoothTransformation));
9579 painter->drawPixmap(d->offset, d->pixmap);
9581 if (option->state & QStyle::State_Selected)
9582 qt_graphicsItem_highlightSelected(this, painter, option);
9588 bool QGraphicsPixmapItem::isObscuredBy(const QGraphicsItem *item) const
9590 return QGraphicsItem::isObscuredBy(item);
9596 QPainterPath QGraphicsPixmapItem::opaqueArea() const
9604 int QGraphicsPixmapItem::type() const
9610 Returns the item's shape mode. The shape mode describes how
9611 QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
9613 \sa setShapeMode(), ShapeMode
9615 QGraphicsPixmapItem::ShapeMode QGraphicsPixmapItem::shapeMode() const
9617 return d_func()->shapeMode;
9621 Sets the item's shape mode to \a mode. The shape mode describes how
9622 QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
9624 \sa shapeMode(), ShapeMode
9626 void QGraphicsPixmapItem::setShapeMode(ShapeMode mode)
9628 Q_D(QGraphicsPixmapItem);
9629 if (d->shapeMode == mode)
9631 d->shapeMode = mode;
9632 d->hasShape = false;
9638 bool QGraphicsPixmapItem::supportsExtension(Extension extension) const
9640 Q_UNUSED(extension);
9647 void QGraphicsPixmapItem::setExtension(Extension extension, const QVariant &variant)
9649 Q_UNUSED(extension);
9656 QVariant QGraphicsPixmapItem::extension(const QVariant &variant) const
9663 \class QGraphicsTextItem
9664 \brief The QGraphicsTextItem class provides a text item that you can add to
9665 a QGraphicsScene to display formatted text.
9667 \ingroup graphicsview-api
9670 If you only need to show plain text in an item, consider using QGraphicsSimpleTextItem
9673 To set the item's text, pass a QString to QGraphicsTextItem's
9674 constructor, or call setHtml()/setPlainText().
9676 QGraphicsTextItem uses the text's formatted size and the associated font
9677 to provide a reasonable implementation of boundingRect(), shape(),
9678 and contains(). You can set the font by calling setFont().
9680 It is possible to make the item editable by setting the Qt::TextEditorInteraction flag
9681 using setTextInteractionFlags().
9683 The item's preferred text width can be set using setTextWidth() and obtained
9686 \note In order to align HTML text in the center, the item's text width must be set.
9688 \image graphicsview-textitem.png
9690 \note QGraphicsTextItem accepts \l{QGraphicsItem::acceptHoverEvents()}{hover events}
9691 by default. You can change this with \l{QGraphicsItem::}{setAcceptHoverEvents()}.
9693 \sa QGraphicsSimpleTextItem, QGraphicsPathItem, QGraphicsRectItem,
9694 QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
9695 QGraphicsLineItem, {Graphics View Framework}
9698 class QGraphicsTextItemPrivate
9701 QGraphicsTextItemPrivate()
9702 : control(0), pageNumber(0), useDefaultImpl(false), tabChangesFocus(false), clickCausedFocus(0)
9705 mutable QWidgetTextControl *control;
9706 QWidgetTextControl *textControl() const;
9708 inline QPointF controlOffset() const
9709 { return QPointF(0., pageNumber * control->document()->pageSize().height()); }
9710 inline void sendControlEvent(QEvent *e)
9711 { if (control) control->processEvent(e, controlOffset()); }
9713 void _q_updateBoundingRect(const QSizeF &);
9714 void _q_update(QRectF);
9715 void _q_ensureVisible(QRectF);
9716 bool _q_mouseOnEdge(QGraphicsSceneMouseEvent *);
9718 QRectF boundingRect;
9720 bool useDefaultImpl;
9721 bool tabChangesFocus;
9723 uint clickCausedFocus : 1;
9725 QGraphicsTextItem *qq;
9730 Constructs a QGraphicsTextItem, using \a text as the default plain
9731 text. \a parent is passed to QGraphicsItem's constructor.
9733 \sa QGraphicsScene::addItem()
9735 QGraphicsTextItem::QGraphicsTextItem(const QString &text, QGraphicsItem *parent)
9736 : QGraphicsObject(*new QGraphicsItemPrivate, parent),
9737 dd(new QGraphicsTextItemPrivate)
9740 if (!text.isEmpty())
9742 setAcceptDrops(true);
9743 setAcceptHoverEvents(true);
9744 setFlags(ItemUsesExtendedStyleOption);
9748 Constructs a QGraphicsTextItem. \a parent is passed to QGraphicsItem's
9751 \sa QGraphicsScene::addItem()
9753 QGraphicsTextItem::QGraphicsTextItem(QGraphicsItem *parent)
9754 : QGraphicsObject(*new QGraphicsItemPrivate, parent),
9755 dd(new QGraphicsTextItemPrivate)
9758 setAcceptDrops(true);
9759 setAcceptHoverEvents(true);
9760 setFlag(ItemUsesExtendedStyleOption);
9764 Destroys the QGraphicsTextItem.
9766 QGraphicsTextItem::~QGraphicsTextItem()
9772 Returns the item's text converted to HTML, or an empty QString if no text has been set.
9776 QString QGraphicsTextItem::toHtml() const
9778 #ifndef QT_NO_TEXTHTMLPARSER
9780 return dd->control->toHtml();
9786 Sets the item's text to \a text, assuming that text is HTML formatted. If
9787 the item has keyboard input focus, this function will also call
9788 ensureVisible() to ensure that the text is visible in all viewports.
9790 \sa toHtml(), hasFocus(), QGraphicsSimpleTextItem
9792 void QGraphicsTextItem::setHtml(const QString &text)
9794 dd->textControl()->setHtml(text);
9798 Returns the item's text converted to plain text, or an empty QString if no text has been set.
9802 QString QGraphicsTextItem::toPlainText() const
9805 return dd->control->toPlainText();
9810 Sets the item's text to \a text. If the item has keyboard input focus,
9811 this function will also call ensureVisible() to ensure that the text is
9812 visible in all viewports.
9814 \sa toHtml(), hasFocus()
9816 void QGraphicsTextItem::setPlainText(const QString &text)
9818 dd->textControl()->setPlainText(text);
9822 Returns the item's font, which is used to render the text.
9826 QFont QGraphicsTextItem::font() const
9830 return dd->control->document()->defaultFont();
9834 Sets the font used to render the text item to \a font.
9838 void QGraphicsTextItem::setFont(const QFont &font)
9840 dd->textControl()->document()->setDefaultFont(font);
9844 Sets the color for unformatted text to \a col.
9846 void QGraphicsTextItem::setDefaultTextColor(const QColor &col)
9848 QWidgetTextControl *c = dd->textControl();
9849 QPalette pal = c->palette();
9850 QColor old = pal.color(QPalette::Text);
9851 pal.setColor(QPalette::Text, col);
9858 Returns the default text color that is used to for unformatted text.
9860 QColor QGraphicsTextItem::defaultTextColor() const
9862 return dd->textControl()->palette().color(QPalette::Text);
9868 QRectF QGraphicsTextItem::boundingRect() const
9870 return dd->boundingRect;
9876 QPainterPath QGraphicsTextItem::shape() const
9879 return QPainterPath();
9881 path.addRect(dd->boundingRect);
9888 bool QGraphicsTextItem::contains(const QPointF &point) const
9890 return dd->boundingRect.contains(point);
9896 void QGraphicsTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
9902 QRectF r = option->exposedRect;
9903 painter->translate(-dd->controlOffset());
9904 r.translate(dd->controlOffset());
9906 QTextDocument *doc = dd->control->document();
9907 QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
9909 // the layout might need to expand the root frame to
9910 // the viewport if NoWrap is set
9912 layout->setViewport(dd->boundingRect);
9914 dd->control->drawContents(painter, r);
9917 layout->setViewport(QRect());
9922 if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
9923 qt_graphicsItem_highlightSelected(this, painter, option);
9929 bool QGraphicsTextItem::isObscuredBy(const QGraphicsItem *item) const
9931 return QGraphicsItem::isObscuredBy(item);
9937 QPainterPath QGraphicsTextItem::opaqueArea() const
9939 return QGraphicsItem::opaqueArea();
9945 int QGraphicsTextItem::type() const
9951 Sets the preferred width for the item's text. If the actual text
9952 is wider than the specified width then it will be broken into
9955 If \a width is set to -1 then the text will not be broken into
9956 multiple lines unless it is enforced through an explicit line
9957 break or a new paragraph.
9959 The default value is -1.
9961 Note that QGraphicsTextItem keeps a QTextDocument internally,
9962 which is used to calculate the text width.
9964 \sa textWidth(), QTextDocument::setTextWidth()
9966 void QGraphicsTextItem::setTextWidth(qreal width)
9968 dd->textControl()->setTextWidth(width);
9972 Returns the text width.
9974 The width is calculated with the QTextDocument that
9975 QGraphicsTextItem keeps internally.
9977 \sa setTextWidth(), QTextDocument::textWidth()
9979 qreal QGraphicsTextItem::textWidth() const
9983 return dd->control->textWidth();
9987 Adjusts the text item to a reasonable size.
9989 void QGraphicsTextItem::adjustSize()
9992 dd->control->adjustSize();
9996 Sets the text document \a document on the item.
9998 void QGraphicsTextItem::setDocument(QTextDocument *document)
10000 dd->textControl()->setDocument(document);
10001 dd->_q_updateBoundingRect(dd->control->size());
10005 Returns the item's text document.
10007 QTextDocument *QGraphicsTextItem::document() const
10009 return dd->textControl()->document();
10015 bool QGraphicsTextItem::sceneEvent(QEvent *event)
10017 QEvent::Type t = event->type();
10018 if (!dd->tabChangesFocus && (t == QEvent::KeyPress || t == QEvent::KeyRelease)) {
10019 int k = ((QKeyEvent *)event)->key();
10020 if (k == Qt::Key_Tab || k == Qt::Key_Backtab) {
10021 dd->sendControlEvent(event);
10025 bool result = QGraphicsItem::sceneEvent(event);
10027 // Ensure input context is updated.
10028 switch (event->type()) {
10029 case QEvent::ContextMenu:
10030 case QEvent::FocusIn:
10031 case QEvent::FocusOut:
10032 case QEvent::GraphicsSceneDragEnter:
10033 case QEvent::GraphicsSceneDragLeave:
10034 case QEvent::GraphicsSceneDragMove:
10035 case QEvent::GraphicsSceneDrop:
10036 case QEvent::GraphicsSceneHoverEnter:
10037 case QEvent::GraphicsSceneHoverLeave:
10038 case QEvent::GraphicsSceneHoverMove:
10039 case QEvent::GraphicsSceneMouseDoubleClick:
10040 case QEvent::GraphicsSceneMousePress:
10041 case QEvent::GraphicsSceneMouseMove:
10042 case QEvent::GraphicsSceneMouseRelease:
10043 case QEvent::KeyPress:
10044 case QEvent::KeyRelease:
10045 // Reset the focus widget's input context, regardless
10046 // of how this item gained or lost focus.
10047 if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) {
10048 qApp->inputMethod()->reset();
10050 qApp->inputMethod()->update(Qt::ImQueryInput);
10053 case QEvent::ShortcutOverride:
10054 dd->sendControlEvent(event);
10066 void QGraphicsTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
10068 if ((QGraphicsItem::d_ptr->flags & (ItemIsSelectable | ItemIsMovable))
10069 && (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) {
10070 // User left-pressed on edge of selectable/movable item, use
10072 dd->useDefaultImpl = true;
10073 } else if (event->buttons() == event->button()
10074 && dd->control->textInteractionFlags() == Qt::NoTextInteraction) {
10075 // User pressed first button on non-interactive item.
10076 dd->useDefaultImpl = true;
10078 if (dd->useDefaultImpl) {
10079 QGraphicsItem::mousePressEvent(event);
10080 if (!event->isAccepted())
10081 dd->useDefaultImpl = false;
10085 dd->sendControlEvent(event);
10091 void QGraphicsTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
10093 if (dd->useDefaultImpl) {
10094 QGraphicsItem::mouseMoveEvent(event);
10098 dd->sendControlEvent(event);
10104 void QGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
10106 if (dd->useDefaultImpl) {
10107 QGraphicsItem::mouseReleaseEvent(event);
10108 if (dd->control->textInteractionFlags() == Qt::NoTextInteraction
10109 && !event->buttons()) {
10110 // User released last button on non-interactive item.
10111 dd->useDefaultImpl = false;
10112 } else if ((event->buttons() & Qt::LeftButton) == 0) {
10113 // User released the left button on an interactive item.
10114 dd->useDefaultImpl = false;
10119 QWidget *widget = event->widget();
10120 if (widget && (dd->control->textInteractionFlags() & Qt::TextEditable) && boundingRect().contains(event->pos())) {
10121 qt_widget_private(widget)->handleSoftwareInputPanel(event->button(), dd->clickCausedFocus);
10123 dd->clickCausedFocus = 0;
10124 dd->sendControlEvent(event);
10130 void QGraphicsTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
10132 if (dd->useDefaultImpl) {
10133 QGraphicsItem::mouseDoubleClickEvent(event);
10138 QGraphicsItem::mouseDoubleClickEvent(event);
10142 dd->sendControlEvent(event);
10148 void QGraphicsTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
10150 dd->sendControlEvent(event);
10156 void QGraphicsTextItem::keyPressEvent(QKeyEvent *event)
10158 dd->sendControlEvent(event);
10164 void QGraphicsTextItem::keyReleaseEvent(QKeyEvent *event)
10166 dd->sendControlEvent(event);
10172 void QGraphicsTextItem::focusInEvent(QFocusEvent *event)
10174 dd->sendControlEvent(event);
10175 if (event->reason() == Qt::MouseFocusReason) {
10176 dd->clickCausedFocus = 1;
10184 void QGraphicsTextItem::focusOutEvent(QFocusEvent *event)
10186 dd->sendControlEvent(event);
10193 void QGraphicsTextItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
10195 dd->sendControlEvent(event);
10201 void QGraphicsTextItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
10203 dd->sendControlEvent(event);
10209 void QGraphicsTextItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
10211 dd->sendControlEvent(event);
10217 void QGraphicsTextItem::dropEvent(QGraphicsSceneDragDropEvent *event)
10219 dd->sendControlEvent(event);
10225 void QGraphicsTextItem::inputMethodEvent(QInputMethodEvent *event)
10227 dd->sendControlEvent(event);
10233 void QGraphicsTextItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
10235 dd->sendControlEvent(event);
10241 void QGraphicsTextItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
10243 dd->sendControlEvent(event);
10249 void QGraphicsTextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
10251 dd->sendControlEvent(event);
10257 QVariant QGraphicsTextItem::inputMethodQuery(Qt::InputMethodQuery query) const
10261 v = dd->control->inputMethodQuery(query);
10262 if (v.type() == QVariant::RectF)
10263 v = v.toRectF().translated(-dd->controlOffset());
10264 else if (v.type() == QVariant::PointF)
10265 v = v.toPointF() - dd->controlOffset();
10266 else if (v.type() == QVariant::Rect)
10267 v = v.toRect().translated(-dd->controlOffset().toPoint());
10268 else if (v.type() == QVariant::Point)
10269 v = v.toPoint() - dd->controlOffset().toPoint();
10276 bool QGraphicsTextItem::supportsExtension(Extension extension) const
10278 Q_UNUSED(extension);
10285 void QGraphicsTextItem::setExtension(Extension extension, const QVariant &variant)
10287 Q_UNUSED(extension);
10294 QVariant QGraphicsTextItem::extension(const QVariant &variant) const
10303 void QGraphicsTextItemPrivate::_q_update(QRectF rect)
10305 if (rect.isValid()) {
10306 rect.translate(-controlOffset());
10308 rect = boundingRect;
10310 if (rect.intersects(boundingRect))
10317 void QGraphicsTextItemPrivate::_q_updateBoundingRect(const QSizeF &size)
10319 if (!control) return; // can't happen
10320 const QSizeF pageSize = control->document()->pageSize();
10321 // paged items have a constant (page) size
10322 if (size == boundingRect.size() || pageSize.height() != -1)
10324 qq->prepareGeometryChange();
10325 boundingRect.setSize(size);
10332 void QGraphicsTextItemPrivate::_q_ensureVisible(QRectF rect)
10334 if (qq->hasFocus()) {
10335 rect.translate(-controlOffset());
10336 qq->ensureVisible(rect, /*xmargin=*/0, /*ymargin=*/0);
10340 QWidgetTextControl *QGraphicsTextItemPrivate::textControl() const
10343 QGraphicsTextItem *that = const_cast<QGraphicsTextItem *>(qq);
10344 control = new QWidgetTextControl(that);
10345 control->setTextInteractionFlags(Qt::NoTextInteraction);
10347 QObject::connect(control, SIGNAL(updateRequest(QRectF)),
10348 qq, SLOT(_q_update(QRectF)));
10349 QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)),
10350 qq, SLOT(_q_updateBoundingRect(QSizeF)));
10351 QObject::connect(control, SIGNAL(visibilityRequest(QRectF)),
10352 qq, SLOT(_q_ensureVisible(QRectF)));
10353 QObject::connect(control, SIGNAL(linkActivated(QString)),
10354 qq, SIGNAL(linkActivated(QString)));
10355 QObject::connect(control, SIGNAL(linkHovered(QString)),
10356 qq, SIGNAL(linkHovered(QString)));
10358 const QSizeF pgSize = control->document()->pageSize();
10359 if (pgSize.height() != -1) {
10360 qq->prepareGeometryChange();
10361 that->dd->boundingRect.setSize(pgSize);
10364 that->dd->_q_updateBoundingRect(control->size());
10373 bool QGraphicsTextItemPrivate::_q_mouseOnEdge(QGraphicsSceneMouseEvent *event)
10376 path.addRect(qq->boundingRect());
10378 QPainterPath docPath;
10379 const QTextFrameFormat format = control->document()->rootFrame()->frameFormat();
10381 qq->boundingRect().adjusted(
10382 format.leftMargin(),
10383 format.topMargin(),
10384 -format.rightMargin(),
10385 -format.bottomMargin()));
10387 return path.subtracted(docPath).contains(event->pos());
10391 \fn QGraphicsTextItem::linkActivated(const QString &link)
10393 This signal is emitted when the user clicks on a link on a text item
10394 that enables Qt::LinksAccessibleByMouse or Qt::LinksAccessibleByKeyboard.
10395 \a link is the link that was clicked.
10397 \sa setTextInteractionFlags()
10401 \fn QGraphicsTextItem::linkHovered(const QString &link)
10403 This signal is emitted when the user hovers over a link on a text item
10404 that enables Qt::LinksAccessibleByMouse. \a link is
10405 the link that was hovered over.
10407 \sa setTextInteractionFlags()
10411 Sets the flags \a flags to specify how the text item should react to user
10414 The default for a QGraphicsTextItem is Qt::NoTextInteraction. This function
10415 also affects the ItemIsFocusable QGraphicsItem flag by setting it if \a flags
10416 is different from Qt::NoTextInteraction and clearing it otherwise.
10418 By default, the text is read-only. To transform the item into an editor,
10419 set the Qt::TextEditable flag.
10421 void QGraphicsTextItem::setTextInteractionFlags(Qt::TextInteractionFlags flags)
10423 if (flags == Qt::NoTextInteraction)
10424 setFlags(this->flags() & ~(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod));
10426 setFlags(this->flags() | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod);
10428 dd->textControl()->setTextInteractionFlags(flags);
10432 Returns the current text interaction flags.
10434 \sa setTextInteractionFlags()
10436 Qt::TextInteractionFlags QGraphicsTextItem::textInteractionFlags() const
10439 return Qt::NoTextInteraction;
10440 return dd->control->textInteractionFlags();
10446 If \a b is true, the \uicontrol Tab key will cause the widget to change focus;
10447 otherwise, the tab key will insert a tab into the document.
10449 In some occasions text edits should not allow the user to input tabulators
10450 or change indentation using the \uicontrol Tab key, as this breaks the focus
10451 chain. The default is false.
10453 \sa tabChangesFocus(), ItemIsFocusable, textInteractionFlags()
10455 void QGraphicsTextItem::setTabChangesFocus(bool b)
10457 dd->tabChangesFocus = b;
10463 Returns true if the \uicontrol Tab key will cause the widget to change focus;
10464 otherwise, false is returned.
10466 By default, this behavior is disabled, and this function will return false.
10468 \sa setTabChangesFocus()
10470 bool QGraphicsTextItem::tabChangesFocus() const
10472 return dd->tabChangesFocus;
10476 \property QGraphicsTextItem::openExternalLinks
10478 Specifies whether QGraphicsTextItem should automatically open links using
10479 QDesktopServices::openUrl() instead of emitting the
10480 linkActivated signal.
10482 The default value is false.
10484 void QGraphicsTextItem::setOpenExternalLinks(bool open)
10486 dd->textControl()->setOpenExternalLinks(open);
10489 bool QGraphicsTextItem::openExternalLinks() const
10493 return dd->control->openExternalLinks();
10497 \property QGraphicsTextItem::textCursor
10499 This property represents the visible text cursor in an editable
10502 By default, if the item's text has not been set, this property
10503 contains a null text cursor; otherwise it contains a text cursor
10504 placed at the start of the item's document.
10506 void QGraphicsTextItem::setTextCursor(const QTextCursor &cursor)
10508 dd->textControl()->setTextCursor(cursor);
10511 QTextCursor QGraphicsTextItem::textCursor() const
10514 return QTextCursor();
10515 return dd->control->textCursor();
10518 class QGraphicsSimpleTextItemPrivate : public QAbstractGraphicsShapeItemPrivate
10520 Q_DECLARE_PUBLIC(QGraphicsSimpleTextItem)
10522 inline QGraphicsSimpleTextItemPrivate() {
10523 pen.setStyle(Qt::NoPen);
10524 brush.setStyle(Qt::SolidPattern);
10528 QRectF boundingRect;
10530 void updateBoundingRect();
10533 static QRectF setupTextLayout(QTextLayout *layout)
10535 layout->setCacheEnabled(true);
10536 layout->beginLayout();
10537 while (layout->createLine().isValid())
10539 layout->endLayout();
10540 qreal maxWidth = 0;
10542 for (int i = 0; i < layout->lineCount(); ++i) {
10543 QTextLine line = layout->lineAt(i);
10544 maxWidth = qMax(maxWidth, line.naturalTextWidth());
10545 line.setPosition(QPointF(0, y));
10546 y += line.height();
10548 return QRectF(0, 0, maxWidth, y);
10551 void QGraphicsSimpleTextItemPrivate::updateBoundingRect()
10553 Q_Q(QGraphicsSimpleTextItem);
10555 if (text.isEmpty()) {
10558 QString tmp = text;
10559 tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
10560 QStackTextEngine engine(tmp, font);
10561 QTextLayout layout(&engine);
10562 br = setupTextLayout(&layout);
10564 if (br != boundingRect) {
10565 q->prepareGeometryChange();
10572 \class QGraphicsSimpleTextItem
10573 \brief The QGraphicsSimpleTextItem class provides a simple text path item
10574 that you can add to a QGraphicsScene.
10576 \ingroup graphicsview-api
10577 \inmodule QtWidgets
10579 To set the item's text, you can either pass a QString to
10580 QGraphicsSimpleTextItem's constructor, or call setText() to change the
10581 text later. To set the text fill color, call setBrush().
10583 The simple text item can have both a fill and an outline; setBrush() will
10584 set the text fill (i.e., text color), and setPen() sets the pen that will
10585 be used to draw the text outline. (The latter can be slow, especially for
10586 complex pens, and items with long text content.) If all you want is to
10587 draw a simple line of text, you should call setBrush() only, and leave the
10588 pen unset; QGraphicsSimpleTextItem's pen is by default Qt::NoPen.
10590 QGraphicsSimpleTextItem uses the text's formatted size and the associated
10591 font to provide a reasonable implementation of boundingRect(), shape(),
10592 and contains(). You can set the font by calling setFont().
10594 QGraphicsSimpleText does not display rich text; instead, you can use
10595 QGraphicsTextItem, which provides full text control capabilities.
10597 \image graphicsview-simpletextitem.png
10599 \sa QGraphicsTextItem, QGraphicsPathItem, QGraphicsRectItem,
10600 QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
10601 QGraphicsLineItem, {Graphics View Framework}
10605 Constructs a QGraphicsSimpleTextItem.
10607 \a parent is passed to QGraphicsItem's constructor.
10609 \sa QGraphicsScene::addItem()
10611 QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(QGraphicsItem *parent)
10612 : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent)
10617 Constructs a QGraphicsSimpleTextItem, using \a text as the default plain text.
10619 \a parent is passed to QGraphicsItem's constructor.
10621 \sa QGraphicsScene::addItem()
10623 QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent)
10624 : QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent)
10630 Destroys the QGraphicsSimpleTextItem.
10632 QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem()
10637 Sets the item's text to \a text. The text will be displayed as
10638 plain text. Newline characters ('\\n') as well as characters of
10639 type QChar::LineSeparator will cause item to break the text into
10642 void QGraphicsSimpleTextItem::setText(const QString &text)
10644 Q_D(QGraphicsSimpleTextItem);
10645 if (d->text == text)
10648 d->updateBoundingRect();
10653 Returns the item's text.
10655 QString QGraphicsSimpleTextItem::text() const
10657 Q_D(const QGraphicsSimpleTextItem);
10662 Sets the font that is used to draw the item's text to \a font.
10664 void QGraphicsSimpleTextItem::setFont(const QFont &font)
10666 Q_D(QGraphicsSimpleTextItem);
10668 d->updateBoundingRect();
10672 Returns the font that is used to draw the item's text.
10674 QFont QGraphicsSimpleTextItem::font() const
10676 Q_D(const QGraphicsSimpleTextItem);
10683 QRectF QGraphicsSimpleTextItem::boundingRect() const
10685 Q_D(const QGraphicsSimpleTextItem);
10686 return d->boundingRect;
10692 QPainterPath QGraphicsSimpleTextItem::shape() const
10694 Q_D(const QGraphicsSimpleTextItem);
10696 path.addRect(d->boundingRect);
10703 bool QGraphicsSimpleTextItem::contains(const QPointF &point) const
10705 Q_D(const QGraphicsSimpleTextItem);
10706 return d->boundingRect.contains(point);
10712 void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
10715 Q_D(QGraphicsSimpleTextItem);
10717 painter->setFont(d->font);
10719 QString tmp = d->text;
10720 tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
10721 QStackTextEngine engine(tmp, d->font);
10722 QTextLayout layout(&engine);
10723 setupTextLayout(&layout);
10726 p.setBrush(d->brush);
10727 painter->setPen(p);
10728 if (d->pen.style() == Qt::NoPen && d->brush.style() == Qt::SolidPattern) {
10729 painter->setBrush(Qt::NoBrush);
10731 QTextLayout::FormatRange range;
10733 range.length = layout.text().length();
10734 range.format.setTextOutline(d->pen);
10735 QList<QTextLayout::FormatRange> formats;
10736 formats.append(range);
10737 layout.setAdditionalFormats(formats);
10740 layout.draw(painter, QPointF(0, 0));
10742 if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
10743 qt_graphicsItem_highlightSelected(this, painter, option);
10749 bool QGraphicsSimpleTextItem::isObscuredBy(const QGraphicsItem *item) const
10751 return QAbstractGraphicsShapeItem::isObscuredBy(item);
10757 QPainterPath QGraphicsSimpleTextItem::opaqueArea() const
10759 return QAbstractGraphicsShapeItem::opaqueArea();
10765 int QGraphicsSimpleTextItem::type() const
10773 bool QGraphicsSimpleTextItem::supportsExtension(Extension extension) const
10775 Q_UNUSED(extension);
10782 void QGraphicsSimpleTextItem::setExtension(Extension extension, const QVariant &variant)
10784 Q_UNUSED(extension);
10791 QVariant QGraphicsSimpleTextItem::extension(const QVariant &variant) const
10798 \class QGraphicsItemGroup
10799 \brief The QGraphicsItemGroup class provides a container that treats
10800 a group of items as a single item.
10802 \ingroup graphicsview-api
10803 \inmodule QtWidgets
10805 A QGraphicsItemGroup is a special type of compound item that
10806 treats itself and all its children as one item (i.e., all events
10807 and geometries for all children are merged together). It's common
10808 to use item groups in presentation tools, when the user wants to
10809 group several smaller items into one big item in order to simplify
10810 moving and copying of items.
10812 If all you want is to store items inside other items, you can use
10813 any QGraphicsItem directly by passing a suitable parent to
10816 The boundingRect() function of QGraphicsItemGroup returns the
10817 bounding rectangle of all items in the item group.
10818 QGraphicsItemGroup ignores the ItemIgnoresTransformations flag on
10819 its children (i.e., with respect to the geometry of the group
10820 item, the children are treated as if they were transformable).
10822 There are two ways to construct an item group. The easiest and
10823 most common approach is to pass a list of items (e.g., all
10824 selected items) to QGraphicsScene::createItemGroup(), which
10825 returns a new QGraphicsItemGroup item. The other approach is to
10826 manually construct a QGraphicsItemGroup item, add it to the scene
10827 calling QGraphicsScene::addItem(), and then add items to the group
10828 manually, one at a time by calling addToGroup(). To dismantle
10829 ("ungroup") an item group, you can either call
10830 QGraphicsScene::destroyItemGroup(), or you can manually remove all
10831 items from the group by calling removeFromGroup().
10833 \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 17
10835 The operation of adding and removing items preserves the items'
10836 scene-relative position and transformation, as opposed to calling
10837 setParentItem(), where only the child item's parent-relative
10838 position and transformation are kept.
10840 The addtoGroup() function reparents the target item to this item
10841 group, keeping the item's position and transformation intact
10842 relative to the scene. Visually, this means that items added via
10843 addToGroup() will remain completely unchanged as a result of this
10844 operation, regardless of the item or the group's current position
10845 or transformation; although the item's position and matrix are
10848 The removeFromGroup() function has similar semantics to
10849 setParentItem(); it reparents the item to the parent item of the
10850 item group. As with addToGroup(), the item's scene-relative
10851 position and transformation remain intact.
10853 \sa QGraphicsItem, {Graphics View Framework}
10856 class QGraphicsItemGroupPrivate : public QGraphicsItemPrivate
10859 QRectF itemsBoundingRect;
10863 Constructs a QGraphicsItemGroup. \a parent is passed to QGraphicsItem's
10866 \sa QGraphicsScene::addItem()
10868 QGraphicsItemGroup::QGraphicsItemGroup(QGraphicsItem *parent)
10869 : QGraphicsItem(*new QGraphicsItemGroupPrivate, parent)
10871 setHandlesChildEvents(true);
10875 Destroys the QGraphicsItemGroup.
10877 QGraphicsItemGroup::~QGraphicsItemGroup()
10882 Adds the given \a item and item's child items to this item group.
10883 The item and child items will be reparented to this group, but its
10884 position and transformation relative to the scene will stay intact.
10886 \sa removeFromGroup(), QGraphicsScene::createItemGroup()
10888 void QGraphicsItemGroup::addToGroup(QGraphicsItem *item)
10890 Q_D(QGraphicsItemGroup);
10892 qWarning("QGraphicsItemGroup::addToGroup: cannot add null item");
10895 if (item == this) {
10896 qWarning("QGraphicsItemGroup::addToGroup: cannot add a group to itself");
10902 QTransform itemTransform = item->itemTransform(this, &ok);
10905 qWarning("QGraphicsItemGroup::addToGroup: could not find a valid transformation from item to group coordinates");
10909 QTransform newItemTransform(itemTransform);
10910 item->setPos(mapFromItem(item, 0, 0));
10911 item->setParentItem(this);
10913 // removing position from translation component of the new transform
10914 if (!item->pos().isNull())
10915 newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
10917 // removing additional transformations properties applied with itemTransform()
10918 QPointF origin = item->transformOriginPoint();
10920 QList<QGraphicsTransform*> transformList = item->transformations();
10921 for (int i = 0; i < transformList.size(); ++i)
10922 transformList.at(i)->applyTo(&m);
10923 newItemTransform *= m.toTransform().inverted();
10924 newItemTransform.translate(origin.x(), origin.y());
10925 newItemTransform.rotate(-item->rotation());
10926 newItemTransform.scale(1/item->scale(), 1/item->scale());
10927 newItemTransform.translate(-origin.x(), -origin.y());
10929 // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
10931 item->setTransform(newItemTransform);
10932 item->d_func()->setIsMemberOfGroup(true);
10933 prepareGeometryChange();
10934 d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
10939 Removes the specified \a item from this group. The item will be
10940 reparented to this group's parent item, or to 0 if this group has
10941 no parent. Its position and transformation relative to the scene
10944 \sa addToGroup(), QGraphicsScene::destroyItemGroup()
10946 void QGraphicsItemGroup::removeFromGroup(QGraphicsItem *item)
10948 Q_D(QGraphicsItemGroup);
10950 qWarning("QGraphicsItemGroup::removeFromGroup: cannot remove null item");
10954 QGraphicsItem *newParent = d_ptr->parent;
10958 QTransform itemTransform;
10960 itemTransform = item->itemTransform(newParent, &ok);
10962 itemTransform = item->sceneTransform();
10964 QPointF oldPos = item->mapToItem(newParent, 0, 0);
10965 item->setParentItem(newParent);
10966 item->setPos(oldPos);
10968 // removing position from translation component of the new transform
10969 if (!item->pos().isNull())
10970 itemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
10972 // removing additional transformations properties applied
10973 // with itemTransform() or sceneTransform()
10974 QPointF origin = item->transformOriginPoint();
10976 QList<QGraphicsTransform*> transformList = item->transformations();
10977 for (int i = 0; i < transformList.size(); ++i)
10978 transformList.at(i)->applyTo(&m);
10979 itemTransform *= m.toTransform().inverted();
10980 itemTransform.translate(origin.x(), origin.y());
10981 itemTransform.rotate(-item->rotation());
10982 itemTransform.scale(1 / item->scale(), 1 / item->scale());
10983 itemTransform.translate(-origin.x(), -origin.y());
10985 // ### Expensive, we could maybe use dirtySceneTransform bit for optimization
10987 item->setTransform(itemTransform);
10988 item->d_func()->setIsMemberOfGroup(item->group() != 0);
10990 // ### Quite expensive. But removeFromGroup() isn't called very often.
10991 prepareGeometryChange();
10992 d->itemsBoundingRect = childrenBoundingRect();
10998 Returns the bounding rect of this group item, and all its children.
11000 QRectF QGraphicsItemGroup::boundingRect() const
11002 Q_D(const QGraphicsItemGroup);
11003 return d->itemsBoundingRect;
11009 void QGraphicsItemGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
11013 if (option->state & QStyle::State_Selected) {
11014 Q_D(QGraphicsItemGroup);
11015 painter->setBrush(Qt::NoBrush);
11016 painter->drawRect(d->itemsBoundingRect);
11023 bool QGraphicsItemGroup::isObscuredBy(const QGraphicsItem *item) const
11025 return QGraphicsItem::isObscuredBy(item);
11031 QPainterPath QGraphicsItemGroup::opaqueArea() const
11033 return QGraphicsItem::opaqueArea();
11039 int QGraphicsItemGroup::type() const
11044 #ifndef QT_NO_GRAPHICSEFFECT
11045 QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
11047 const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
11048 if (!info && deviceCoordinates) {
11049 // Device coordinates without info not yet supported.
11050 qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
11054 QRectF rect = item->boundingRect();
11055 if (!item->d_ptr->children.isEmpty())
11056 rect |= item->childrenBoundingRect();
11058 if (deviceCoordinates) {
11059 Q_ASSERT(info->painter);
11060 rect = info->painter->worldTransform().mapRect(rect);
11066 void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter)
11069 qWarning("QGraphicsEffectSource::draw: Can only begin as a result of QGraphicsEffect::draw");
11073 Q_ASSERT(item->d_ptr->scene);
11074 QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
11075 if (painter == info->painter) {
11076 scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
11077 info->widget, info->opacity, info->effectTransform, info->wasDirtySceneTransform,
11080 QTransform effectTransform = info->painter->worldTransform().inverted();
11081 effectTransform *= painter->worldTransform();
11082 scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
11083 info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
11088 // sourceRect must be in the given coordinate system
11089 QRect QGraphicsItemEffectSourcePrivate::paddedEffectRect(Qt::CoordinateSystem system, QGraphicsEffect::PixmapPadMode mode, const QRectF &sourceRect, bool *unpadded) const
11091 QRectF effectRectF;
11096 if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
11098 QRectF deviceRect = system == Qt::DeviceCoordinates ? sourceRect : info->painter->worldTransform().mapRect(sourceRect);
11099 effectRectF = item->graphicsEffect()->boundingRectFor(deviceRect);
11101 *unpadded = (effectRectF.size() == sourceRect.size());
11102 if (info && system == Qt::LogicalCoordinates)
11103 effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
11105 // no choice but to send a logical coordinate bounding rect to boundingRectFor
11106 effectRectF = item->graphicsEffect()->boundingRectFor(sourceRect);
11108 } else if (mode == QGraphicsEffect::PadToTransparentBorder) {
11109 // adjust by 1.5 to account for cosmetic pens
11110 effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
11112 effectRectF = sourceRect;
11117 return effectRectF.toAlignedRect();
11120 QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
11121 QGraphicsEffect::PixmapPadMode mode) const
11123 const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
11124 if (!info && deviceCoordinates) {
11125 // Device coordinates without info not yet supported.
11126 qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
11129 if (!item->d_ptr->scene)
11131 QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
11134 const QRectF sourceRect = boundingRect(system);
11135 QRect effectRect = paddedEffectRect(system, mode, sourceRect, &unpadded);
11138 *offset = effectRect.topLeft();
11140 bool untransformed = !deviceCoordinates
11141 || info->painter->worldTransform().type() <= QTransform::TxTranslate;
11142 if (untransformed && unpadded && isPixmap()) {
11144 *offset = boundingRect(system).topLeft().toPoint();
11145 return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
11148 if (effectRect.isEmpty())
11151 QPixmap pixmap(effectRect.size());
11152 pixmap.fill(Qt::transparent);
11153 QPainter pixmapPainter(&pixmap);
11154 pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing);
11156 QTransform effectTransform = QTransform::fromTranslate(-effectRect.x(), -effectRect.y());
11157 if (deviceCoordinates && info->effectTransform)
11158 effectTransform *= *info->effectTransform;
11161 // Logical coordinates without info.
11162 QTransform sceneTransform = item->sceneTransform();
11163 QTransform newEffectTransform = sceneTransform.inverted();
11164 newEffectTransform *= effectTransform;
11165 scened->draw(item, &pixmapPainter, 0, &sceneTransform, 0, 0, qreal(1.0),
11166 &newEffectTransform, false, true);
11167 } else if (deviceCoordinates) {
11168 // Device coordinates with info.
11169 scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
11170 info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
11173 // Item coordinates with info.
11174 QTransform newEffectTransform = info->transformPtr->inverted();
11175 newEffectTransform *= effectTransform;
11176 scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, 0,
11177 info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform,
11181 pixmapPainter.end();
11185 #endif //QT_NO_GRAPHICSEFFECT
11187 #ifndef QT_NO_DEBUG_STREAM
11188 QDebug operator<<(QDebug debug, QGraphicsItem *item)
11191 debug << "QGraphicsItem(0)";
11195 if (QGraphicsObject *o = item->toGraphicsObject())
11196 debug << o->metaObject()->className();
11198 debug << "QGraphicsItem";
11199 debug << "(this =" << (void*)item
11200 << ", parent =" << (void*)item->parentItem()
11201 << ", pos =" << item->pos()
11202 << ", z =" << item->zValue() << ", flags = "
11203 << item->flags() << ")";
11207 QDebug operator<<(QDebug debug, QGraphicsObject *item)
11210 debug << "QGraphicsObject(0)";
11214 debug.nospace() << item->metaObject()->className() << '(' << (void*)item;
11215 if (!item->objectName().isEmpty())
11216 debug << ", name = " << item->objectName();
11217 debug.nospace() << ", parent = " << ((void*)item->parentItem())
11218 << ", pos = " << item->pos()
11219 << ", z = " << item->zValue() << ", flags = "
11220 << item->flags() << ')';
11221 return debug.space();
11224 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change)
11226 const char *str = "UnknownChange";
11228 case QGraphicsItem::ItemChildAddedChange:
11229 str = "ItemChildAddedChange";
11231 case QGraphicsItem::ItemChildRemovedChange:
11232 str = "ItemChildRemovedChange";
11234 case QGraphicsItem::ItemCursorChange:
11235 str = "ItemCursorChange";
11237 case QGraphicsItem::ItemCursorHasChanged:
11238 str = "ItemCursorHasChanged";
11240 case QGraphicsItem::ItemEnabledChange:
11241 str = "ItemEnabledChange";
11243 case QGraphicsItem::ItemEnabledHasChanged:
11244 str = "ItemEnabledHasChanged";
11246 case QGraphicsItem::ItemFlagsChange:
11247 str = "ItemFlagsChange";
11249 case QGraphicsItem::ItemFlagsHaveChanged:
11250 str = "ItemFlagsHaveChanged";
11252 case QGraphicsItem::ItemMatrixChange:
11253 str = "ItemMatrixChange";
11255 case QGraphicsItem::ItemParentChange:
11256 str = "ItemParentChange";
11258 case QGraphicsItem::ItemParentHasChanged:
11259 str = "ItemParentHasChanged";
11261 case QGraphicsItem::ItemPositionChange:
11262 str = "ItemPositionChange";
11264 case QGraphicsItem::ItemPositionHasChanged:
11265 str = "ItemPositionHasChanged";
11267 case QGraphicsItem::ItemSceneChange:
11268 str = "ItemSceneChange";
11270 case QGraphicsItem::ItemSceneHasChanged:
11271 str = "ItemSceneHasChanged";
11273 case QGraphicsItem::ItemSelectedChange:
11274 str = "ItemSelectedChange";
11276 case QGraphicsItem::ItemSelectedHasChanged:
11277 str = "ItemSelectedHasChanged";
11279 case QGraphicsItem::ItemToolTipChange:
11280 str = "ItemToolTipChange";
11282 case QGraphicsItem::ItemToolTipHasChanged:
11283 str = "ItemToolTipHasChanged";
11285 case QGraphicsItem::ItemTransformChange:
11286 str = "ItemTransformChange";
11288 case QGraphicsItem::ItemTransformHasChanged:
11289 str = "ItemTransformHasChanged";
11291 case QGraphicsItem::ItemVisibleChange:
11292 str = "ItemVisibleChange";
11294 case QGraphicsItem::ItemVisibleHasChanged:
11295 str = "ItemVisibleHasChanged";
11297 case QGraphicsItem::ItemZValueChange:
11298 str = "ItemZValueChange";
11300 case QGraphicsItem::ItemZValueHasChanged:
11301 str = "ItemZValueHasChanged";
11303 case QGraphicsItem::ItemOpacityChange:
11304 str = "ItemOpacityChange";
11306 case QGraphicsItem::ItemOpacityHasChanged:
11307 str = "ItemOpacityHasChanged";
11309 case QGraphicsItem::ItemScenePositionHasChanged:
11310 str = "ItemScenePositionHasChanged";
11312 case QGraphicsItem::ItemRotationChange:
11313 str = "ItemRotationChange";
11315 case QGraphicsItem::ItemRotationHasChanged:
11316 str = "ItemRotationHasChanged";
11318 case QGraphicsItem::ItemScaleChange:
11319 str = "ItemScaleChange";
11321 case QGraphicsItem::ItemScaleHasChanged:
11322 str = "ItemScaleHasChanged";
11324 case QGraphicsItem::ItemTransformOriginPointChange:
11325 str = "ItemTransformOriginPointChange";
11327 case QGraphicsItem::ItemTransformOriginPointHasChanged:
11328 str = "ItemTransformOriginPointHasChanged";
11335 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
11337 const char *str = "UnknownFlag";
11339 case QGraphicsItem::ItemIsMovable:
11340 str = "ItemIsMovable";
11342 case QGraphicsItem::ItemIsSelectable:
11343 str = "ItemIsSelectable";
11345 case QGraphicsItem::ItemIsFocusable:
11346 str = "ItemIsFocusable";
11348 case QGraphicsItem::ItemClipsToShape:
11349 str = "ItemClipsToShape";
11351 case QGraphicsItem::ItemClipsChildrenToShape:
11352 str = "ItemClipsChildrenToShape";
11354 case QGraphicsItem::ItemIgnoresTransformations:
11355 str = "ItemIgnoresTransformations";
11357 case QGraphicsItem::ItemIgnoresParentOpacity:
11358 str = "ItemIgnoresParentOpacity";
11360 case QGraphicsItem::ItemDoesntPropagateOpacityToChildren:
11361 str = "ItemDoesntPropagateOpacityToChildren";
11363 case QGraphicsItem::ItemStacksBehindParent:
11364 str = "ItemStacksBehindParent";
11366 case QGraphicsItem::ItemUsesExtendedStyleOption:
11367 str = "ItemUsesExtendedStyleOption";
11369 case QGraphicsItem::ItemHasNoContents:
11370 str = "ItemHasNoContents";
11372 case QGraphicsItem::ItemSendsGeometryChanges:
11373 str = "ItemSendsGeometryChanges";
11375 case QGraphicsItem::ItemAcceptsInputMethod:
11376 str = "ItemAcceptsInputMethod";
11378 case QGraphicsItem::ItemNegativeZStacksBehindParent:
11379 str = "ItemNegativeZStacksBehindParent";
11381 case QGraphicsItem::ItemIsPanel:
11382 str = "ItemIsPanel";
11384 case QGraphicsItem::ItemIsFocusScope:
11385 str = "ItemIsFocusScope";
11387 case QGraphicsItem::ItemSendsScenePositionChanges:
11388 str = "ItemSendsScenePositionChanges";
11390 case QGraphicsItem::ItemStopsClickFocusPropagation:
11391 str = "ItemStopsClickFocusPropagation";
11393 case QGraphicsItem::ItemStopsFocusHandling:
11394 str = "ItemStopsFocusHandling";
11401 QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags)
11405 for (int i = 0; i < 17; ++i) {
11406 if (flags & (1 << i)) {
11410 debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i)));
11421 #include "moc_qgraphicsitem.cpp"
11423 #endif // QT_NO_GRAPHICSVIEW