0
|
1 |
/****************************************************************************
|
|
2 |
**
|
|
3 |
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
4 |
** All rights reserved.
|
|
5 |
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
6 |
**
|
|
7 |
** This file is part of the QtGui module of the Qt Toolkit.
|
|
8 |
**
|
|
9 |
** $QT_BEGIN_LICENSE:LGPL$
|
|
10 |
** No Commercial Usage
|
|
11 |
** This file contains pre-release code and may not be distributed.
|
|
12 |
** You may use this file in accordance with the terms and conditions
|
|
13 |
** contained in the Technology Preview License Agreement accompanying
|
|
14 |
** this package.
|
|
15 |
**
|
|
16 |
** GNU Lesser General Public License Usage
|
|
17 |
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
18 |
** General Public License version 2.1 as published by the Free Software
|
|
19 |
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
20 |
** packaging of this file. Please review the following information to
|
|
21 |
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
22 |
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
23 |
**
|
|
24 |
** In addition, as a special exception, Nokia gives you certain additional
|
|
25 |
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
26 |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
27 |
**
|
|
28 |
** If you have questions regarding the use of this file, please contact
|
|
29 |
** Nokia at qt-info@nokia.com.
|
|
30 |
**
|
|
31 |
**
|
|
32 |
**
|
|
33 |
**
|
|
34 |
**
|
|
35 |
**
|
|
36 |
**
|
|
37 |
**
|
|
38 |
** $QT_END_LICENSE$
|
|
39 |
**
|
|
40 |
****************************************************************************/
|
|
41 |
|
|
42 |
/*!
|
|
43 |
\class QGraphicsItem
|
|
44 |
\brief The QGraphicsItem class is the base class for all graphical
|
|
45 |
items in a QGraphicsScene.
|
|
46 |
\since 4.2
|
|
47 |
|
|
48 |
\ingroup graphicsview-api
|
|
49 |
|
|
50 |
It provides a light-weight foundation for writing your own custom items.
|
|
51 |
This includes defining the item's geometry, collision detection, its
|
|
52 |
painting implementation and item interaction through its event handlers.
|
|
53 |
QGraphicsItem is part of \l{The Graphics View Framework}
|
|
54 |
|
|
55 |
\img graphicsview-items.png
|
|
56 |
|
|
57 |
For convenience, Qt provides a set of standard graphics items for the most
|
|
58 |
common shapes. These are:
|
|
59 |
|
|
60 |
\list
|
|
61 |
\o QGraphicsEllipseItem provides an ellipse item
|
|
62 |
\o QGraphicsLineItem provides a line item
|
|
63 |
\o QGraphicsPathItem provides an arbitrary path item
|
|
64 |
\o QGraphicsPixmapItem provides a pixmap item
|
|
65 |
\o QGraphicsPolygonItem provides a polygon item
|
|
66 |
\o QGraphicsRectItem provides a rectangular item
|
|
67 |
\o QGraphicsSimpleTextItem provides a simple text label item
|
|
68 |
\o QGraphicsTextItem provides an advanced text browser item
|
|
69 |
\endlist
|
|
70 |
|
|
71 |
All of an item's geometric information is based on its local coordinate
|
|
72 |
system. The item's position, pos(), is the only function that does not
|
|
73 |
operate in local coordinates, as it returns a position in parent
|
|
74 |
coordinates. \l {The Graphics View Coordinate System} describes the coordinate
|
|
75 |
system in detail.
|
|
76 |
|
|
77 |
You can set whether an item should be visible (i.e., drawn, and accepting
|
|
78 |
events), by calling setVisible(). Hiding an item will also hide its
|
|
79 |
children. Similarly, you can enable or disable an item by calling
|
|
80 |
setEnabled(). If you disable an item, all its children will also be
|
|
81 |
disabled. By default, items are both visible and enabled. To toggle
|
|
82 |
whether an item is selected or not, first enable selection by setting
|
|
83 |
the ItemIsSelectable flag, and then call setSelected(). Normally,
|
|
84 |
selection is toggled by the scene, as a result of user interaction.
|
|
85 |
|
|
86 |
To write your own graphics item, you first create a subclass of
|
|
87 |
QGraphicsItem, and then start by implementing its two pure virtual public
|
|
88 |
functions: boundingRect(), which returns an estimate of the area painted
|
|
89 |
by the item, and paint(), which implements the actual painting. For
|
|
90 |
example:
|
|
91 |
|
|
92 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 0
|
|
93 |
|
|
94 |
The boundingRect() function has many different purposes.
|
|
95 |
QGraphicsScene bases its item index on boundingRect(), and
|
|
96 |
QGraphicsView uses it both for culling invisible items, and for
|
|
97 |
determining the area that needs to be recomposed when drawing
|
|
98 |
overlapping items. In addition, QGraphicsItem's collision
|
|
99 |
detection mechanisms use boundingRect() to provide an efficient
|
|
100 |
cut-off. The fine grained collision algorithm in
|
|
101 |
collidesWithItem() is based on calling shape(), which returns an
|
|
102 |
accurate outline of the item's shape as a QPainterPath.
|
|
103 |
|
|
104 |
QGraphicsScene expects all items boundingRect() and shape() to
|
|
105 |
remain unchanged unless it is notified. If you want to change an
|
|
106 |
item's geometry in any way, you must first call
|
|
107 |
prepareGeometryChange() to allow QGraphicsScene to update its
|
|
108 |
bookkeeping.
|
|
109 |
|
|
110 |
Collision detection can be done in two ways:
|
|
111 |
|
|
112 |
\list 1
|
|
113 |
|
|
114 |
\o Reimplement shape() to return an accurate shape for your item,
|
|
115 |
and rely on the default implementation of collidesWithItem() to do
|
|
116 |
shape-shape intersection. This can be rather expensive if the
|
|
117 |
shapes are complex.
|
|
118 |
|
|
119 |
\o Reimplement collidesWithItem() to provide your own custom item
|
|
120 |
and shape collision algorithm.
|
|
121 |
|
|
122 |
\endlist
|
|
123 |
|
|
124 |
The contains() function can be called to determine whether the item \e
|
|
125 |
contains a point or not. This function can also be reimplemented by the
|
|
126 |
item. The default behavior of contains() is based on calling shape().
|
|
127 |
|
|
128 |
Items can contain other items, and also be contained by other items. All
|
|
129 |
items can have a parent item and a list of children. Unless the item has
|
|
130 |
no parent, its position is in \e parent coordinates (i.e., the parent's
|
|
131 |
local coordinates). Parent items propagate both their position and their
|
|
132 |
transformation to all children.
|
|
133 |
|
|
134 |
\img graphicsview-parentchild.png
|
|
135 |
|
|
136 |
\section1 Transformation
|
|
137 |
|
|
138 |
QGraphicsItem supports projective transformations in addition to its base
|
|
139 |
position, pos(). There are several ways to change an item's transformation.
|
|
140 |
For simple transformations, you can call either of the convenience
|
|
141 |
functions setRotation() or setScale(), or you can pass any transformation
|
|
142 |
matrix to setTransform(). For advanced transformation control you also have
|
|
143 |
the option of setting several combined transformations by calling
|
|
144 |
setTransformations().
|
|
145 |
|
|
146 |
Item transformations accumulate from parent to child, so if both a parent
|
|
147 |
and child item are rotated 90 degrees, the child's total transformation
|
|
148 |
will be 180 degrees. Similarly, if the item's parent is scaled to 2x its
|
|
149 |
original size, its children will also be twice as large. An item's
|
|
150 |
transformation does not affect its own local geometry; all geometry
|
|
151 |
functions (e.g., contains(), update(), and all the mapping functions) still
|
|
152 |
operate in local coordinates. For convenience, QGraphicsItem provides the
|
|
153 |
functions sceneTransform(), which returns the item's total transformation
|
|
154 |
matrix (including its position and all parents' positions and
|
|
155 |
transformations), and scenePos(), which returns its position in scene
|
|
156 |
coordinates. To reset an item's matrix, call resetTransform().
|
|
157 |
|
|
158 |
Certain transformation operations produce a different outcome depending on
|
|
159 |
the order in which they are applied. For example, if you scale an
|
|
160 |
transform, and then rotate it, you may get a different result than if the
|
|
161 |
transform was rotated first. However, the order you set the transformation
|
|
162 |
properties on QGraphicsItem does not affect the resulting transformation;
|
|
163 |
QGraphicsItem always applies the properties in a fixed, defined order:
|
|
164 |
|
|
165 |
\list
|
|
166 |
\o The item's base transform is applied (transform())
|
|
167 |
\o The item's transformations list is applied in order (transformations())
|
|
168 |
\o The item is rotated relative to its transform origin point (rotation(), transformOriginPoint())
|
|
169 |
\o The item is scaled relative to its transform origin point (scale(), transformOriginPoint())
|
|
170 |
\endlist
|
|
171 |
|
|
172 |
\section1 Painting
|
|
173 |
|
|
174 |
The paint() function is called by QGraphicsView to paint the item's
|
|
175 |
contents. The item has no background or default fill of its own; whatever
|
|
176 |
is behind the item will shine through all areas that are not explicitly
|
|
177 |
painted in this function. You can call update() to schedule a repaint,
|
|
178 |
optionally passing the rectangle that needs a repaint. Depending on
|
|
179 |
whether or not the item is visible in a view, the item may or may not be
|
|
180 |
repainted; there is no equivalent to QWidget::repaint() in QGraphicsItem.
|
|
181 |
|
|
182 |
Items are painted by the view, starting with the parent items and then
|
|
183 |
drawing children, in ascending stacking order. You can set an item's
|
|
184 |
stacking order by calling setZValue(), and test it by calling
|
|
185 |
zValue(), where items with low z-values are painted before items with
|
|
186 |
high z-values. Stacking order applies to sibling items; parents are always
|
|
187 |
drawn before their children.
|
|
188 |
|
|
189 |
\section1 Sorting
|
|
190 |
|
|
191 |
All items are drawn in a defined, stable order, and this same order decides
|
|
192 |
which items will receive mouse input first when you click on the scene.
|
|
193 |
Normally you don't have to worry about sorting, as the items follow a
|
|
194 |
"natural order", following the logical structure of the scene.
|
|
195 |
|
|
196 |
An item's children are stacked on top of the parent, and sibling items are
|
|
197 |
stacked by insertion order (i.e., in the same order that they were either
|
|
198 |
added to the scene, or added to the same parent). If you add item A, and
|
|
199 |
then B, then B will be on top of A. If you then add C, the items' stacking
|
|
200 |
order will be A, then B, then C.
|
|
201 |
|
|
202 |
\image graphicsview-zorder.png
|
|
203 |
|
|
204 |
This example shows the stacking order of all limbs of the robot from the
|
|
205 |
\l{graphicsview/dragdroprobot}{Drag and Drop Robot} example. The torso is
|
|
206 |
the root item (all other items are children or descendants of the torso),
|
|
207 |
so it is drawn first. Next, the head is drawn, as it is the first item in
|
|
208 |
the torso's list of children. Then the upper left arm is drawn. As the
|
|
209 |
lower arm is a child of the upper arm, the lower arm is then drawn,
|
|
210 |
followed by the upper arm's next sibling, which is the upper right arm, and
|
|
211 |
so on.
|
|
212 |
|
|
213 |
For advanced users, there are ways to alter how your items are sorted:
|
|
214 |
|
|
215 |
\list
|
|
216 |
\o You can call setZValue() on an item to explicitly stack it on top of, or
|
|
217 |
under, other sibling items. The default Z value for an item is 0. Items
|
|
218 |
with the same Z value are stacked by insertion order.
|
|
219 |
|
|
220 |
\o You can call stackBefore() to reorder the list of children. This will
|
|
221 |
directly modify the insertion order.
|
|
222 |
|
|
223 |
\o You can set the ItemStacksBehindParent flag to stack a child item behind
|
|
224 |
its parent.
|
|
225 |
\endlist
|
|
226 |
|
|
227 |
The stacking order of two sibling items also counts for each item's
|
|
228 |
children and descendant items. So if one item is on top of another, then
|
|
229 |
all its children will also be on top of all the other item's children as
|
|
230 |
well.
|
|
231 |
|
|
232 |
\section1 Events
|
|
233 |
|
|
234 |
QGraphicsItem receives events from QGraphicsScene through the virtual
|
|
235 |
function sceneEvent(). This function distributes the most common events
|
|
236 |
to a set of convenience event handlers:
|
|
237 |
|
|
238 |
\list
|
|
239 |
\o contextMenuEvent() handles context menu events
|
|
240 |
\o focusInEvent() and focusOutEvent() handle focus in and out events
|
|
241 |
\o hoverEnterEvent(), hoverMoveEvent(), and hoverLeaveEvent() handles
|
|
242 |
hover enter, move and leave events
|
|
243 |
\o inputMethodEvent() handles input events, for accessibility support
|
|
244 |
\o keyPressEvent() and keyReleaseEvent() handle key press and release events
|
|
245 |
\o mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), and
|
|
246 |
mouseDoubleClickEvent() handles mouse press, move, release, click and
|
|
247 |
doubleclick events
|
|
248 |
\endlist
|
|
249 |
|
|
250 |
You can filter events for any other item by installing event filters. This
|
|
251 |
functionality is separate from Qt's regular event filters (see
|
|
252 |
QObject::installEventFilter()), which only work on subclasses of QObject. After
|
|
253 |
installing your item as an event filter for another item by calling
|
|
254 |
installSceneEventFilter(), the filtered events will be received by the virtual
|
|
255 |
function sceneEventFilter(). You can remove item event filters by calling
|
|
256 |
removeSceneEventFilter().
|
|
257 |
|
|
258 |
\section1 Custom Data
|
|
259 |
|
|
260 |
Sometimes it's useful to register custom data with an item, be it a custom
|
|
261 |
item, or a standard item. You can call setData() on any item to store data
|
|
262 |
in it using a key-value pair (the key being an integer, and the value is a
|
|
263 |
QVariant). To get custom data from an item, call data(). This
|
|
264 |
functionality is completely untouched by Qt itself; it is provided for the
|
|
265 |
user's convenience.
|
|
266 |
|
|
267 |
\sa QGraphicsScene, QGraphicsView, {The Graphics View Framework}
|
|
268 |
*/
|
|
269 |
|
|
270 |
/*!
|
|
271 |
\variable QGraphicsItem::UserType
|
|
272 |
|
|
273 |
The lowest permitted type value for custom items (subclasses
|
|
274 |
of QGraphicsItem or any of the standard items). This value is
|
|
275 |
used in conjunction with a reimplementation of QGraphicsItem::type()
|
|
276 |
and declaring a Type enum value. Example:
|
|
277 |
|
|
278 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1
|
|
279 |
*/
|
|
280 |
|
|
281 |
/*!
|
|
282 |
\enum QGraphicsItem::GraphicsItemFlag
|
|
283 |
|
|
284 |
This enum describes different flags that you can set on an item to
|
|
285 |
toggle different features in the item's behavior.
|
|
286 |
|
|
287 |
All flags are disabled by default.
|
|
288 |
|
|
289 |
\value ItemIsMovable The item supports interactive movement using
|
|
290 |
the mouse. By clicking on the item and then dragging, the item
|
|
291 |
will move together with the mouse cursor. If the item has
|
|
292 |
children, all children are also moved. If the item is part of a
|
|
293 |
selection, all selected items are also moved. This feature is
|
|
294 |
provided as a convenience through the base implementation of
|
|
295 |
QGraphicsItem's mouse event handlers.
|
|
296 |
|
|
297 |
\value ItemIsSelectable The item supports selection. Enabling this
|
|
298 |
feature will enable setSelected() to toggle selection for the
|
|
299 |
item. It will also let the item be selected automatically as a
|
|
300 |
result of calling QGraphicsScene::setSelectionArea(), by clicking
|
|
301 |
on an item, or by using rubber band selection in QGraphicsView.
|
|
302 |
|
|
303 |
\value ItemIsFocusable The item supports keyboard input focus (i.e., it is
|
|
304 |
an input item). Enabling this flag will allow the item to accept focus,
|
|
305 |
which again allows the delivery of key events to
|
|
306 |
QGraphicsItem::keyPressEvent() and QGraphicsItem::keyReleaseEvent().
|
|
307 |
|
|
308 |
\value ItemClipsToShape The item clips to its own shape. The item cannot
|
|
309 |
draw or receive mouse, tablet, drag and drop or hover events outside ts
|
|
310 |
shape. It is disabled by default. This behavior is enforced by
|
|
311 |
QGraphicsView::drawItems() or QGraphicsScene::drawItems(). This flag was
|
|
312 |
introduced in Qt 4.3.
|
|
313 |
|
|
314 |
\value ItemClipsChildrenToShape The item clips the painting of all its
|
|
315 |
descendants to its own shape. Items that are either direct or indirect
|
|
316 |
children of this item cannot draw outside this item's shape. By default,
|
|
317 |
this flag is disabled; children can draw anywhere. This behavior is
|
|
318 |
enforced by QGraphicsView::drawItems() or
|
|
319 |
QGraphicsScene::drawItems(). This flag was introduced in Qt 4.3.
|
|
320 |
|
|
321 |
\value ItemIgnoresTransformations The item ignores inherited
|
|
322 |
transformations (i.e., its position is still anchored to its parent, but
|
|
323 |
the parent or view rotation, zoom or shear transformations are ignored).
|
|
324 |
This flag is useful for keeping text label items horizontal and unscaled,
|
|
325 |
so they will still be readable if the view is transformed. When set, the
|
|
326 |
item's view geometry and scene geometry will be maintained separately. You
|
|
327 |
must call deviceTransform() to map coordinates and detect collisions in
|
|
328 |
the view. By default, this flag is disabled. This flag was introduced in
|
|
329 |
Qt 4.3. \note With this flag set you can still scale the item itself, and
|
|
330 |
that scale transformation will influence the item's children.
|
|
331 |
|
|
332 |
\value ItemIgnoresParentOpacity The item ignores its parent's opacity. The
|
|
333 |
item's effective opacity is the same as its own; it does not combine with
|
|
334 |
the parent's opacity. This flags allows your item to keep its absolute
|
|
335 |
opacity even if the parent is semitransparent. This flag was introduced in
|
|
336 |
Qt 4.5.
|
|
337 |
|
|
338 |
\value ItemDoesntPropagateOpacityToChildren The item doesn't propagate its
|
|
339 |
opacity to its children. This flag allows you to create a semitransparent
|
|
340 |
item that does not affect the opacity of its children. This flag was
|
|
341 |
introduced in Qt 4.5.
|
|
342 |
|
|
343 |
\value ItemStacksBehindParent The item is stacked behind its parent. By
|
|
344 |
default, child items are stacked on top of the parent item. But setting
|
|
345 |
this flag, the child will be stacked behind it. This flag is useful for
|
|
346 |
drop shadow effects and for decoration objects that follow the parent
|
|
347 |
item's geometry without drawing on top of it.
|
|
348 |
|
|
349 |
\value ItemUsesExtendedStyleOption The item makes use of either
|
|
350 |
\l{QStyleOptionGraphicsItem::}{exposedRect} or
|
|
351 |
\l{QStyleOptionGraphicsItem::}{matrix} in QStyleOptionGraphicsItem. By default,
|
|
352 |
the \l{QStyleOptionGraphicsItem::}{exposedRect} is initialized to the item's
|
|
353 |
boundingRect() and the \l{QStyleOptionGraphicsItem::}{matrix} is untransformed.
|
|
354 |
You can enable this flag for the style options to be set up with more
|
|
355 |
fine-grained values.
|
|
356 |
Note that QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag
|
|
357 |
and always initialized to 1. Use
|
|
358 |
QStyleOptionGraphicsItem::levelOfDetailFromTransform() if you need a higher
|
|
359 |
value.
|
|
360 |
|
|
361 |
\value ItemHasNoContents The item does not paint anything (i.e., calling
|
|
362 |
paint() on the item has no effect). You should set this flag on items that
|
|
363 |
do not need to be painted to ensure that Graphics View avoids unnecessary
|
|
364 |
painting preparations. This flag was introduced in Qt 4.6.
|
|
365 |
|
|
366 |
\value ItemSendsGeometryChanges The item enables itemChange()
|
|
367 |
notifications for ItemPositionChange, ItemPositionHasChanged,
|
|
368 |
ItemMatrixChange, ItemTransformChange, and ItemTransformHasChanged. For
|
|
369 |
performance reasons, these notifications are disabled by default. You must
|
|
370 |
enable this flag to receive notifications for position and transform
|
|
371 |
changes. This flag was introduced in Qt 4.6.
|
|
372 |
|
|
373 |
\value ItemAcceptsInputMethod The item supports input methods typically
|
|
374 |
used for Asian languages.
|
|
375 |
This flag was introduced in Qt 4.6.
|
|
376 |
|
|
377 |
\value ItemNegativeZStacksBehindParent The item automatically stacks behind
|
|
378 |
it's parent if it's z-value is negative. This flag enables setZValue() to
|
|
379 |
toggle ItemStacksBehindParent.
|
|
380 |
|
|
381 |
\value ItemIsPanel. The item is a panel. A panel provides activation and
|
|
382 |
contained focus handling. Only one panel can be active at a time (see
|
|
383 |
QGraphicsItem::isActive()). When no panel is active, QGraphicsScene
|
|
384 |
activates all non-panel items. Window items (i.e.,
|
|
385 |
QGraphicsItem::isWindow() returns true) are panels. This flag was
|
|
386 |
introduced in Qt 4.6.
|
|
387 |
|
|
388 |
\omitvalue ItemIsFocusScope Internal only (for now).
|
|
389 |
*/
|
|
390 |
|
|
391 |
/*!
|
|
392 |
\enum QGraphicsItem::GraphicsItemChange
|
|
393 |
|
|
394 |
ItemVisibleHasChanged,
|
|
395 |
ItemEnabledHasChanged,
|
|
396 |
ItemSelectedHasChanged,
|
|
397 |
ItemParentHasChanged,
|
|
398 |
ItemSceneHasChanged
|
|
399 |
|
|
400 |
This enum describes the state changes that are notified by
|
|
401 |
QGraphicsItem::itemChange(). The notifications are sent as the state
|
|
402 |
changes, and in some cases, adjustments can be made (see the documentation
|
|
403 |
for each change for details).
|
|
404 |
|
|
405 |
Note: Be careful with calling functions on the QGraphicsItem itself inside
|
|
406 |
itemChange(), as certain function calls can lead to unwanted
|
|
407 |
recursion. For example, you cannot call setPos() in itemChange() on an
|
|
408 |
ItemPositionChange notification, as the setPos() function will again call
|
|
409 |
itemChange(ItemPositionChange). Instead, you can return the new, adjusted
|
|
410 |
position from itemChange().
|
|
411 |
|
|
412 |
\value ItemEnabledChange The item's enabled state changes. If the item is
|
|
413 |
presently enabled, it will become disabled, and vice verca. The value
|
|
414 |
argument is the new enabled state (i.e., true or false). Do not call
|
|
415 |
setEnabled() in itemChange() as this notification is delivered. Instead,
|
|
416 |
you can return the new state from itemChange().
|
|
417 |
|
|
418 |
\value ItemEnabledHasChanged The item's enabled state has changed. The
|
|
419 |
value argument is the new enabled state (i.e., true or false). Do not call
|
|
420 |
setEnabled() in itemChange() as this notification is delivered. The return
|
|
421 |
value is ignored.
|
|
422 |
|
|
423 |
\value ItemMatrixChange The item's affine transformation matrix is
|
|
424 |
changing. This value is obsolete; you can use ItemTransformChange instead.
|
|
425 |
|
|
426 |
\value ItemPositionChange The item's position changes. This notification
|
|
427 |
is sent if the ItemSendsGeometryChanges flag is enabled, and when the
|
|
428 |
item's local position changes, relative to its parent (i.e., as a result
|
|
429 |
of calling setPos() or moveBy()). The value argument is the new position
|
|
430 |
(i.e., a QPointF). You can call pos() to get the original position. Do
|
|
431 |
not call setPos() or moveBy() in itemChange() as this notification is
|
|
432 |
delivered; instead, you can return the new, adjusted position from
|
|
433 |
itemChange(). After this notification, QGraphicsItem immediately sends the
|
|
434 |
ItemPositionHasChanged notification if the position changed.
|
|
435 |
|
|
436 |
\value ItemPositionHasChanged The item's position has changed. This
|
|
437 |
notification is sent if the ItemSendsGeometryChanges flag is enabled, and
|
|
438 |
after the item's local position, relative to its parent, has changed. The
|
|
439 |
value argument is the new position (the same as pos()), and QGraphicsItem
|
|
440 |
ignores the return value for this notification (i.e., a read-only
|
|
441 |
notification).
|
|
442 |
|
|
443 |
\value ItemTransformChange The item's transformation matrix changes. This
|
|
444 |
notification is send if the ItemSendsGeometryChanges flag is enabled, and
|
|
445 |
when the item's local transformation matrix changes (i.e., as a result of
|
|
446 |
calling setTransform(). The value argument is the new matrix (i.e., a
|
|
447 |
QTransform); to get the old matrix, call transform(). Do not call
|
|
448 |
setTransform() or set any of the transformation properties in itemChange()
|
|
449 |
as this notification is delivered; instead, you can return the new matrix
|
|
450 |
from itemChange(). This notification is not sent if you change the
|
|
451 |
transformation properties.
|
|
452 |
|
|
453 |
\value ItemTransformHasChanged The item's transformation matrix has
|
|
454 |
changed either because setTransform is called, or one of the
|
|
455 |
transformation properties is changed. This notification is sent if the
|
|
456 |
ItemSendsGeometryChanges flag is enabled, and after the item's local
|
|
457 |
transformation matrix has changed. The value argument is the new matrix
|
|
458 |
(same as transform()), and QGraphicsItem ignores the return value for this
|
|
459 |
notification (i.e., a read-only notification).
|
|
460 |
|
|
461 |
\value ItemSelectedChange The item's selected state changes. If the item is
|
|
462 |
presently selected, it will become unselected, and vice verca. The value
|
|
463 |
argument is the new selected state (i.e., true or false). Do not call
|
|
464 |
setSelected() in itemChange() as this notification is delivered; instead, you
|
|
465 |
can return the new selected state from itemChange().
|
|
466 |
|
|
467 |
\value ItemSelectedHasChanged The item's selected state has changed. The
|
|
468 |
value argument is the new selected state (i.e., true or false). Do not
|
|
469 |
call setSelected() in itemChange() as this notification is delivered. The
|
|
470 |
return value is ignored.
|
|
471 |
|
|
472 |
\value ItemVisibleChange The item's visible state changes. If the item is
|
|
473 |
presently visible, it will become invisible, and vice verca. The value
|
|
474 |
argument is the new visible state (i.e., true or false). Do not call
|
|
475 |
setVisible() in itemChange() as this notification is delivered; instead,
|
|
476 |
you can return the new visible state from itemChange().
|
|
477 |
|
|
478 |
\value ItemVisibleHasChanged The item's visible state has changed. The
|
|
479 |
value argument is the new visible state (i.e., true or false). Do not call
|
|
480 |
setVisible() in itemChange() as this notification is delivered. The return
|
|
481 |
value is ignored.
|
|
482 |
|
|
483 |
\value ItemParentChange The item's parent changes. The value argument is
|
|
484 |
the new parent item (i.e., a QGraphicsItem pointer). Do not call
|
|
485 |
setParentItem() in itemChange() as this notification is delivered;
|
|
486 |
instead, you can return the new parent from itemChange().
|
|
487 |
|
|
488 |
\value ItemParentHasChanged The item's parent has changed. The value
|
|
489 |
argument is the new parent (i.e., a pointer to a QGraphicsItem). Do not
|
|
490 |
call setParentItem() in itemChange() as this notification is
|
|
491 |
delivered. The return value is ignored.
|
|
492 |
|
|
493 |
\value ItemChildAddedChange A child is added to this item. The value
|
|
494 |
argument is the new child item (i.e., a QGraphicsItem pointer). Do not
|
|
495 |
pass this item to any item's setParentItem() function as this notification
|
|
496 |
is delivered. The return value is unused; you cannot adjust anything in
|
|
497 |
this notification. Note that the new child might not be fully constructed
|
|
498 |
when this notification is sent; calling pure virtual functions on
|
|
499 |
the child can lead to a crash.
|
|
500 |
|
|
501 |
\value ItemChildRemovedChange A child is removed from this item. The value
|
|
502 |
argument is the child item that is about to be removed (i.e., a
|
|
503 |
QGraphicsItem pointer). The return value is unused; you cannot adjust
|
|
504 |
anything in this notification.
|
|
505 |
|
|
506 |
\value ItemSceneChange The item is moved to a new scene. This notification
|
|
507 |
is also sent when the item is added to its initial scene, and when it is
|
|
508 |
removed. The value argument is the new scene (i.e., a QGraphicsScene
|
|
509 |
pointer), or a null pointer if the item is removed from a scene. Do not
|
|
510 |
override this change by passing this item to QGraphicsScene::addItem() as
|
|
511 |
this notification is delivered; instead, you can return the new scene from
|
|
512 |
itemChange(). Use this feature with caution; objecting to a scene change can
|
|
513 |
quickly lead to unwanted recursion.
|
|
514 |
|
|
515 |
\value ItemSceneHasChanged The item's scene has changed. The value
|
|
516 |
argument is the new scene (i.e., a pointer to a QGraphicsScene). Do not
|
|
517 |
call setScene() in itemChange() as this notification is delivered. The
|
|
518 |
return value is ignored.
|
|
519 |
|
|
520 |
\value ItemCursorChange The item's cursor changes. The value argument is
|
|
521 |
the new cursor (i.e., a QCursor). Do not call setCursor() in itemChange()
|
|
522 |
as this notification is delivered. Instead, you can return a new cursor
|
|
523 |
from itemChange().
|
|
524 |
|
|
525 |
\value ItemCursorHasChanged The item's cursor has changed. The value
|
|
526 |
argument is the new cursor (i.e., a QCursor). Do not call setCursor() as
|
|
527 |
this notification is delivered. The return value is ignored.
|
|
528 |
|
|
529 |
\value ItemToolTipChange The item's tooltip changes. The value argument is
|
|
530 |
the new tooltip (i.e., a QToolTip). Do not call setToolTip() in
|
|
531 |
itemChange() as this notification is delivered. Instead, you can return a
|
|
532 |
new tooltip from itemChange().
|
|
533 |
|
|
534 |
\value ItemToolTipHasChanged The item's tooltip has changed. The value
|
|
535 |
argument is the new tooltip (i.e., a QToolTip). Do not call setToolTip()
|
|
536 |
as this notification is delivered. The return value is ignored.
|
|
537 |
|
|
538 |
\value ItemFlagsChange The item's flags change. The value argument is the
|
|
539 |
new flags (i.e., a quint32). Do not call setFlags() in itemChange() as
|
|
540 |
this notification is delivered. Instead, you can return the new flags from
|
|
541 |
itemChange().
|
|
542 |
|
|
543 |
\value ItemFlagsHaveChanged The item's flags have changed. The value
|
|
544 |
argument is the new flags (i.e., a quint32). Do not call setFlags() in
|
|
545 |
itemChange() as this notification is delivered. The return value is
|
|
546 |
ignored.
|
|
547 |
|
|
548 |
\value ItemZValueChange The item's Z-value changes. The value argument is
|
|
549 |
the new Z-value (i.e., a double). Do not call setZValue() in itemChange()
|
|
550 |
as this notification is delivered. Instead, you can return a new Z-value
|
|
551 |
from itemChange().
|
|
552 |
|
|
553 |
\value ItemZValueHasChanged The item's Z-value has changed. The value
|
|
554 |
argument is the new Z-value (i.e., a double). Do not call setZValue() as
|
|
555 |
this notification is delivered. The return value is ignored.
|
|
556 |
|
|
557 |
\value ItemOpacityChange The item's opacity changes. The value argument is
|
|
558 |
the new opacity (i.e., a double). Do not call setOpacity() in itemChange()
|
|
559 |
as this notification is delivered. Instead, you can return a new opacity
|
|
560 |
from itemChange().
|
|
561 |
|
|
562 |
\value ItemOpacityHasChanged The item's opacity has changed. The value
|
|
563 |
argument is the new opacity (i.e., a double). Do not call setOpacity() as
|
|
564 |
this notification is delivered. The return value is ignored.
|
|
565 |
*/
|
|
566 |
|
|
567 |
/*!
|
|
568 |
\enum QGraphicsItem::CacheMode
|
|
569 |
\since 4.4
|
|
570 |
|
|
571 |
This enum describes QGraphicsItem's cache modes. Caching is used to speed
|
|
572 |
up rendering by allocating and rendering to an off-screen pixel buffer,
|
|
573 |
which can be reused when the item requires redrawing. For some paint
|
|
574 |
devices, the cache is stored directly in graphics memory, which makes
|
|
575 |
rendering very quick.
|
|
576 |
|
|
577 |
\value NoCache The default; all item caching is
|
|
578 |
disabled. QGraphicsItem::paint() is called every time the item needs
|
|
579 |
redrawing.
|
|
580 |
|
|
581 |
\value ItemCoordinateCache Caching is enabled for the item's logical
|
|
582 |
(local) coordinate system. QGraphicsItem creates an off-screen pixel
|
|
583 |
buffer with a configurable size / resolution that you can pass to
|
|
584 |
QGraphicsItem::setCacheMode(). Rendering quality will typically degrade,
|
|
585 |
depending on the resolution of the cache and the item transformation. The
|
|
586 |
first time the item is redrawn, it will render itself into the cache, and
|
|
587 |
the cache is then reused for every subsequent expose. The cache is also
|
|
588 |
reused as the item is transformed. To adjust the resolution of the cache,
|
|
589 |
you can call setCacheMode() again.
|
|
590 |
|
|
591 |
\value DeviceCoordinateCache Caching is enabled at the paint device level,
|
|
592 |
in device coordinates. This mode is for items that can move, but are not
|
|
593 |
rotated, scaled or sheared. If the item is transformed directly or
|
|
594 |
indirectly, the cache will be regenerated automatically. Unlike
|
|
595 |
ItemCoordinateCacheMode, DeviceCoordinateCache always renders at maximum
|
|
596 |
quality.
|
|
597 |
|
|
598 |
\sa QGraphicsItem::setCacheMode()
|
|
599 |
*/
|
|
600 |
|
|
601 |
/*!
|
|
602 |
\enum QGraphicsItem::Extension
|
|
603 |
\internal
|
|
604 |
|
|
605 |
Note: This is provided as a hook to avoid future problems related
|
|
606 |
to adding virtual functions. See also extension(),
|
|
607 |
supportsExtension() and setExtension().
|
|
608 |
*/
|
|
609 |
|
|
610 |
/*!
|
|
611 |
\enum QGraphicsItem::PanelModality
|
|
612 |
\since 4.6
|
|
613 |
|
|
614 |
This enum specifies the behavior of a modal panel. A modal panel
|
|
615 |
is one that blocks input to other panels. Note that items that
|
|
616 |
are children of a modal panel are not blocked.
|
|
617 |
|
|
618 |
The values are:
|
|
619 |
\value NonModal The panel is not modal and does not block input to other panels.
|
|
620 |
\value PanelModal The panel is modal to a single item hierarchy and blocks input to its parent pane, all grandparent panels, and all siblings of its parent and grandparent panels.
|
|
621 |
\value SceneModal The window is modal to the entire scene and blocks input to all panels.
|
|
622 |
|
|
623 |
\sa QGraphicsItem::setPanelModality(), QGraphicsItem::panelModality(), QGraphicsItem::ItemIsPanel
|
|
624 |
*/
|
|
625 |
|
|
626 |
#include "qgraphicsitem.h"
|
|
627 |
|
|
628 |
#ifndef QT_NO_GRAPHICSVIEW
|
|
629 |
|
|
630 |
#include "qgraphicsscene.h"
|
|
631 |
#include "qgraphicsscene_p.h"
|
|
632 |
#include "qgraphicssceneevent.h"
|
|
633 |
#include "qgraphicsview.h"
|
|
634 |
#include "qgraphicswidget.h"
|
|
635 |
#include "qgraphicsproxywidget.h"
|
|
636 |
#include "qgraphicsscenebsptreeindex_p.h"
|
|
637 |
#include <QtCore/qbitarray.h>
|
|
638 |
#include <QtCore/qdebug.h>
|
|
639 |
#include <QtCore/qpoint.h>
|
|
640 |
#include <QtCore/qstack.h>
|
|
641 |
#include <QtCore/qtimer.h>
|
|
642 |
#include <QtCore/qvariant.h>
|
|
643 |
#include <QtCore/qvarlengtharray.h>
|
|
644 |
#include <QtGui/qapplication.h>
|
|
645 |
#include <QtGui/qbitmap.h>
|
|
646 |
#include <QtGui/qpainter.h>
|
|
647 |
#include <QtGui/qpainterpath.h>
|
|
648 |
#include <QtGui/qpixmapcache.h>
|
|
649 |
#include <QtGui/qstyleoption.h>
|
|
650 |
#include <QtGui/qevent.h>
|
|
651 |
#include <QtGui/qinputcontext.h>
|
|
652 |
#include <QtGui/qgraphicseffect.h>
|
|
653 |
|
|
654 |
#include <private/qgraphicsitem_p.h>
|
|
655 |
#include <private/qgraphicswidget_p.h>
|
|
656 |
#include <private/qtextcontrol_p.h>
|
|
657 |
#include <private/qtextdocumentlayout_p.h>
|
|
658 |
#include <private/qtextengine_p.h>
|
|
659 |
#include <private/qwidget_p.h>
|
|
660 |
|
|
661 |
#ifdef Q_WS_X11
|
|
662 |
#include <private/qt_x11_p.h>
|
|
663 |
#include <private/qpixmap_x11_p.h>
|
|
664 |
#endif
|
|
665 |
|
|
666 |
#include <private/qgesturemanager_p.h>
|
|
667 |
|
|
668 |
#include <math.h>
|
|
669 |
|
|
670 |
QT_BEGIN_NAMESPACE
|
|
671 |
|
|
672 |
static inline void _q_adjustRect(QRect *rect)
|
|
673 |
{
|
|
674 |
Q_ASSERT(rect);
|
|
675 |
if (!rect->width())
|
|
676 |
rect->adjust(0, 0, 1, 0);
|
|
677 |
if (!rect->height())
|
|
678 |
rect->adjust(0, 0, 0, 1);
|
|
679 |
}
|
|
680 |
|
|
681 |
/*
|
|
682 |
### Move this into QGraphicsItemPrivate
|
|
683 |
*/
|
|
684 |
class QGraphicsItemCustomDataStore
|
|
685 |
{
|
|
686 |
public:
|
|
687 |
QMap<const QGraphicsItem *, QMap<int, QVariant> > data;
|
|
688 |
};
|
|
689 |
Q_GLOBAL_STATIC(QGraphicsItemCustomDataStore, qt_dataStore)
|
|
690 |
|
|
691 |
/*!
|
|
692 |
\internal
|
|
693 |
|
|
694 |
Returns a QPainterPath of \a path when stroked with the \a pen.
|
|
695 |
Ignoring dash pattern.
|
|
696 |
*/
|
|
697 |
static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)
|
|
698 |
{
|
|
699 |
// We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
|
|
700 |
// if we pass a value of 0.0 to QPainterPathStroker::setWidth()
|
|
701 |
const qreal penWidthZero = qreal(0.00000001);
|
|
702 |
|
|
703 |
if (path == QPainterPath())
|
|
704 |
return path;
|
|
705 |
QPainterPathStroker ps;
|
|
706 |
ps.setCapStyle(pen.capStyle());
|
|
707 |
if (pen.widthF() <= 0.0)
|
|
708 |
ps.setWidth(penWidthZero);
|
|
709 |
else
|
|
710 |
ps.setWidth(pen.widthF());
|
|
711 |
ps.setJoinStyle(pen.joinStyle());
|
|
712 |
ps.setMiterLimit(pen.miterLimit());
|
|
713 |
QPainterPath p = ps.createStroke(path);
|
|
714 |
p.addPath(path);
|
|
715 |
return p;
|
|
716 |
}
|
|
717 |
|
|
718 |
/*!
|
|
719 |
\internal
|
|
720 |
|
|
721 |
Propagates the ancestor flag \a flag with value \a enabled to all this
|
|
722 |
item's children. If \a root is false, the flag is also set on this item
|
|
723 |
(default is true).
|
|
724 |
*/
|
|
725 |
void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag,
|
|
726 |
AncestorFlag flag, bool enabled, bool root)
|
|
727 |
{
|
|
728 |
Q_Q(QGraphicsItem);
|
|
729 |
if (root) {
|
|
730 |
// For root items only. This is the item that has either enabled or
|
|
731 |
// disabled \a childFlag, or has been reparented.
|
|
732 |
switch (int(childFlag)) {
|
|
733 |
case -2:
|
|
734 |
flag = AncestorFiltersChildEvents;
|
|
735 |
enabled = q->filtersChildEvents();
|
|
736 |
break;
|
|
737 |
case -1:
|
|
738 |
flag = AncestorHandlesChildEvents;
|
|
739 |
enabled = q->handlesChildEvents();
|
|
740 |
break;
|
|
741 |
case QGraphicsItem::ItemClipsChildrenToShape:
|
|
742 |
flag = AncestorClipsChildren;
|
|
743 |
enabled = flags & QGraphicsItem::ItemClipsChildrenToShape;
|
|
744 |
invalidateCachedClipPathRecursively(/*childrenOnly=*/true);
|
|
745 |
break;
|
|
746 |
case QGraphicsItem::ItemIgnoresTransformations:
|
|
747 |
flag = AncestorIgnoresTransformations;
|
|
748 |
enabled = flags & QGraphicsItem::ItemIgnoresTransformations;
|
|
749 |
break;
|
|
750 |
default:
|
|
751 |
return;
|
|
752 |
}
|
|
753 |
|
|
754 |
if (parent) {
|
|
755 |
// Inherit the enabled-state from our parents.
|
|
756 |
if ((parent->d_ptr->ancestorFlags & flag)
|
|
757 |
|| (int(parent->d_ptr->flags & childFlag) == childFlag)
|
|
758 |
|| (childFlag == -1 && parent->d_ptr->handlesChildEvents)
|
|
759 |
|| (childFlag == -2 && parent->d_ptr->filtersDescendantEvents)) {
|
|
760 |
enabled = true;
|
|
761 |
ancestorFlags |= flag;
|
|
762 |
} else {
|
|
763 |
ancestorFlags &= ~flag;
|
|
764 |
}
|
|
765 |
} else {
|
|
766 |
// Top-level root items don't have any ancestors, so there are no
|
|
767 |
// ancestor flags either.
|
|
768 |
ancestorFlags = 0;
|
|
769 |
}
|
|
770 |
} else {
|
|
771 |
// Don't set or propagate the ancestor flag if it's already correct.
|
|
772 |
if (((ancestorFlags & flag) && enabled) || (!(ancestorFlags & flag) && !enabled))
|
|
773 |
return;
|
|
774 |
|
|
775 |
// Set the flag.
|
|
776 |
if (enabled)
|
|
777 |
ancestorFlags |= flag;
|
|
778 |
else
|
|
779 |
ancestorFlags &= ~flag;
|
|
780 |
|
|
781 |
// Don't process children if the item has the main flag set on itself.
|
|
782 |
if ((childFlag != -1 && int(flags & childFlag) == childFlag)
|
|
783 |
|| (int(childFlag) == -1 && handlesChildEvents)
|
|
784 |
|| (int(childFlag) == -2 && filtersDescendantEvents))
|
|
785 |
return;
|
|
786 |
}
|
|
787 |
|
|
788 |
foreach (QGraphicsItem *child, children)
|
|
789 |
child->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false);
|
|
790 |
}
|
|
791 |
|
|
792 |
/*!
|
|
793 |
\internal
|
|
794 |
|
|
795 |
Propagates item group membership.
|
|
796 |
*/
|
|
797 |
void QGraphicsItemPrivate::setIsMemberOfGroup(bool enabled)
|
|
798 |
{
|
|
799 |
Q_Q(QGraphicsItem);
|
|
800 |
isMemberOfGroup = enabled;
|
|
801 |
if (!qgraphicsitem_cast<QGraphicsItemGroup *>(q)) {
|
|
802 |
foreach (QGraphicsItem *child, children)
|
|
803 |
child->d_func()->setIsMemberOfGroup(enabled);
|
|
804 |
}
|
|
805 |
}
|
|
806 |
|
|
807 |
/*!
|
|
808 |
\internal
|
|
809 |
|
|
810 |
Maps any item pos properties of \a event to \a item's coordinate system.
|
|
811 |
*/
|
|
812 |
void QGraphicsItemPrivate::remapItemPos(QEvent *event, QGraphicsItem *item)
|
|
813 |
{
|
|
814 |
Q_Q(QGraphicsItem);
|
|
815 |
switch (event->type()) {
|
|
816 |
case QEvent::GraphicsSceneMouseMove:
|
|
817 |
case QEvent::GraphicsSceneMousePress:
|
|
818 |
case QEvent::GraphicsSceneMouseRelease:
|
|
819 |
case QEvent::GraphicsSceneMouseDoubleClick: {
|
|
820 |
QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
|
|
821 |
mouseEvent->setPos(item->mapFromItem(q, mouseEvent->pos()));
|
|
822 |
mouseEvent->setLastPos(item->mapFromItem(q, mouseEvent->pos()));
|
|
823 |
for (int i = 0x1; i <= 0x10; i <<= 1) {
|
|
824 |
if (mouseEvent->buttons() & i) {
|
|
825 |
Qt::MouseButton button = Qt::MouseButton(i);
|
|
826 |
mouseEvent->setButtonDownPos(button, item->mapFromItem(q, mouseEvent->buttonDownPos(button)));
|
|
827 |
}
|
|
828 |
}
|
|
829 |
break;
|
|
830 |
}
|
|
831 |
case QEvent::GraphicsSceneWheel: {
|
|
832 |
QGraphicsSceneWheelEvent *wheelEvent = static_cast<QGraphicsSceneWheelEvent *>(event);
|
|
833 |
wheelEvent->setPos(item->mapFromItem(q, wheelEvent->pos()));
|
|
834 |
break;
|
|
835 |
}
|
|
836 |
case QEvent::GraphicsSceneContextMenu: {
|
|
837 |
QGraphicsSceneContextMenuEvent *contextEvent = static_cast<QGraphicsSceneContextMenuEvent *>(event);
|
|
838 |
contextEvent->setPos(item->mapFromItem(q, contextEvent->pos()));
|
|
839 |
break;
|
|
840 |
}
|
|
841 |
case QEvent::GraphicsSceneHoverMove: {
|
|
842 |
QGraphicsSceneHoverEvent *hoverEvent = static_cast<QGraphicsSceneHoverEvent *>(event);
|
|
843 |
hoverEvent->setPos(item->mapFromItem(q, hoverEvent->pos()));
|
|
844 |
break;
|
|
845 |
}
|
|
846 |
default:
|
|
847 |
break;
|
|
848 |
}
|
|
849 |
}
|
|
850 |
|
|
851 |
/*!
|
|
852 |
\internal
|
|
853 |
|
|
854 |
Maps the point \a pos from scene to item coordinates. If \a view is passed and the item
|
|
855 |
is untransformable, this function will correctly map \a pos from the scene using the
|
|
856 |
view's transformation.
|
|
857 |
*/
|
|
858 |
QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos,
|
|
859 |
const QWidget *viewport) const
|
|
860 |
{
|
|
861 |
Q_Q(const QGraphicsItem);
|
|
862 |
if (!itemIsUntransformable())
|
|
863 |
return q->mapFromScene(pos);
|
|
864 |
QGraphicsView *view = 0;
|
|
865 |
if (viewport)
|
|
866 |
view = qobject_cast<QGraphicsView *>(viewport->parentWidget());
|
|
867 |
if (!view)
|
|
868 |
return q->mapFromScene(pos);
|
|
869 |
// ### More ping pong than needed.
|
|
870 |
return q->deviceTransform(view->viewportTransform()).inverted().map(view->mapFromScene(pos));
|
|
871 |
}
|
|
872 |
|
|
873 |
/*!
|
|
874 |
\internal
|
|
875 |
|
|
876 |
Combines this item's position and transform onto \a transform.
|
|
877 |
|
|
878 |
If you need to change this function (e.g., adding more transformation
|
|
879 |
modes / options), make sure to change all places marked with COMBINE.
|
|
880 |
*/
|
|
881 |
void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransform *viewTransform) const
|
|
882 |
{
|
|
883 |
// COMBINE
|
|
884 |
if (viewTransform && itemIsUntransformable()) {
|
|
885 |
*x = q_ptr->deviceTransform(*viewTransform);
|
|
886 |
} else {
|
|
887 |
if (transformData)
|
|
888 |
*x *= transformData->computedFullTransform();
|
|
889 |
if (!pos.isNull())
|
|
890 |
*x *= QTransform::fromTranslate(pos.x(), pos.y());
|
|
891 |
}
|
|
892 |
}
|
|
893 |
|
|
894 |
/*!
|
|
895 |
\internal
|
|
896 |
|
|
897 |
Combines this item's position and transform onto \a transform.
|
|
898 |
|
|
899 |
If you need to change this function (e.g., adding more transformation
|
|
900 |
modes / options), make sure to change QGraphicsItem::deviceTransform() as
|
|
901 |
well.
|
|
902 |
*/
|
|
903 |
void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTransform *viewTransform) const
|
|
904 |
{
|
|
905 |
// COMBINE
|
|
906 |
if (viewTransform && itemIsUntransformable()) {
|
|
907 |
*x = q_ptr->deviceTransform(*viewTransform);
|
|
908 |
} else {
|
|
909 |
x->translate(pos.x(), pos.y());
|
|
910 |
if (transformData)
|
|
911 |
*x = transformData->computedFullTransform(x);
|
|
912 |
}
|
|
913 |
}
|
|
914 |
|
|
915 |
void QGraphicsItemPrivate::updateSceneTransformFromParent()
|
|
916 |
{
|
|
917 |
if (parent) {
|
|
918 |
Q_ASSERT(!parent->d_ptr->dirtySceneTransform);
|
|
919 |
if (parent->d_ptr->sceneTransformTranslateOnly) {
|
|
920 |
sceneTransform = QTransform::fromTranslate(parent->d_ptr->sceneTransform.dx() + pos.x(),
|
|
921 |
parent->d_ptr->sceneTransform.dy() + pos.y());
|
|
922 |
} else {
|
|
923 |
sceneTransform = parent->d_ptr->sceneTransform;
|
|
924 |
sceneTransform.translate(pos.x(), pos.y());
|
|
925 |
}
|
|
926 |
if (transformData) {
|
|
927 |
sceneTransform = transformData->computedFullTransform(&sceneTransform);
|
|
928 |
sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
|
|
929 |
} else {
|
|
930 |
sceneTransformTranslateOnly = parent->d_ptr->sceneTransformTranslateOnly;
|
|
931 |
}
|
|
932 |
} else if (!transformData) {
|
|
933 |
sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
|
|
934 |
sceneTransformTranslateOnly = 1;
|
|
935 |
} else if (transformData->onlyTransform) {
|
|
936 |
sceneTransform = transformData->transform;
|
|
937 |
if (!pos.isNull())
|
|
938 |
sceneTransform *= QTransform::fromTranslate(pos.x(), pos.y());
|
|
939 |
sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
|
|
940 |
} else if (pos.isNull()) {
|
|
941 |
sceneTransform = transformData->computedFullTransform();
|
|
942 |
sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
|
|
943 |
} else {
|
|
944 |
sceneTransform = QTransform::fromTranslate(pos.x(), pos.y());
|
|
945 |
sceneTransform = transformData->computedFullTransform(&sceneTransform);
|
|
946 |
sceneTransformTranslateOnly = (sceneTransform.type() <= QTransform::TxTranslate);
|
|
947 |
}
|
|
948 |
dirtySceneTransform = 0;
|
|
949 |
}
|
|
950 |
|
|
951 |
/*!
|
|
952 |
\internal
|
|
953 |
|
|
954 |
This helper function helped us add input method query support in
|
|
955 |
Qt 4.4.1 without having to reimplement the inputMethodQuery()
|
|
956 |
function in QGraphicsProxyWidget. ### Qt 5: Remove. We cannot
|
|
957 |
remove it in 4.5+ even if we do reimplement the function properly,
|
|
958 |
because apps compiled with 4.4 will not be able to call the
|
|
959 |
reimplementation.
|
|
960 |
*/
|
|
961 |
QVariant QGraphicsItemPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query) const
|
|
962 |
{
|
|
963 |
Q_UNUSED(query);
|
|
964 |
return QVariant();
|
|
965 |
}
|
|
966 |
|
|
967 |
/*!
|
|
968 |
\internal
|
|
969 |
|
|
970 |
Make sure not to trigger any pure virtual function calls (e.g.,
|
|
971 |
prepareGeometryChange) if the item is in its destructor, i.e.
|
|
972 |
inDestructor is 1.
|
|
973 |
*/
|
|
974 |
void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
|
|
975 |
{
|
|
976 |
Q_Q(QGraphicsItem);
|
|
977 |
if (newParent == q) {
|
|
978 |
qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this);
|
|
979 |
return;
|
|
980 |
}
|
|
981 |
if (newParent == parent)
|
|
982 |
return;
|
|
983 |
|
|
984 |
const QVariant newParentVariant(q->itemChange(QGraphicsItem::ItemParentChange,
|
|
985 |
qVariantFromValue<QGraphicsItem *>(newParent)));
|
|
986 |
newParent = qVariantValue<QGraphicsItem *>(newParentVariant);
|
|
987 |
if (newParent == parent)
|
|
988 |
return;
|
|
989 |
|
|
990 |
if (scene) {
|
|
991 |
// Deliver the change to the index
|
|
992 |
scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant);
|
|
993 |
}
|
|
994 |
|
|
995 |
if (subFocusItem && parent) {
|
|
996 |
// Make sure none of the old parents point to this guy.
|
|
997 |
subFocusItem->d_ptr->clearSubFocus(parent);
|
|
998 |
}
|
|
999 |
|
|
1000 |
// We anticipate geometry changes. If the item is deleted, it will be
|
|
1001 |
// removed from the index at a later stage, and the whole scene will be
|
|
1002 |
// updated.
|
|
1003 |
if (!inDestructor)
|
|
1004 |
q_ptr->prepareGeometryChange();
|
|
1005 |
|
|
1006 |
const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q));
|
|
1007 |
if (parent) {
|
|
1008 |
// Remove from current parent
|
|
1009 |
parent->d_ptr->removeChild(q);
|
|
1010 |
parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant);
|
|
1011 |
}
|
|
1012 |
|
|
1013 |
// Update toplevelitem list. If this item is being deleted, its parent
|
|
1014 |
// will be 0 but we don't want to register/unregister it in the TLI list.
|
|
1015 |
if (scene && !inDestructor) {
|
|
1016 |
if (parent && !newParent) {
|
|
1017 |
scene->d_func()->registerTopLevelItem(q);
|
|
1018 |
} else if (!parent && newParent) {
|
|
1019 |
scene->d_func()->unregisterTopLevelItem(q);
|
|
1020 |
}
|
|
1021 |
}
|
|
1022 |
|
|
1023 |
// Ensure any last parent focus scope does not point to this item or any of
|
|
1024 |
// its descendents.
|
|
1025 |
QGraphicsItem *p = parent;
|
|
1026 |
QGraphicsItem *parentFocusScopeItem = 0;
|
|
1027 |
while (p) {
|
|
1028 |
if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
|
|
1029 |
// If this item's focus scope's focus scope item points
|
|
1030 |
// to this item or a descendent, then clear it.
|
|
1031 |
QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
|
|
1032 |
if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
|
|
1033 |
parentFocusScopeItem = fsi;
|
|
1034 |
p->d_ptr->focusScopeItem = 0;
|
|
1035 |
}
|
|
1036 |
break;
|
|
1037 |
}
|
|
1038 |
p = p->d_ptr->parent;
|
|
1039 |
}
|
|
1040 |
|
|
1041 |
// Update focus scope item ptr in new scope.
|
|
1042 |
if (newParent) {
|
|
1043 |
QGraphicsItem *p = newParent;
|
|
1044 |
while (p) {
|
|
1045 |
if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
|
|
1046 |
p->d_ptr->focusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem;
|
|
1047 |
// ### The below line might not make sense...
|
|
1048 |
if (subFocusItem)
|
|
1049 |
subFocusItem->d_ptr->clearSubFocus();
|
|
1050 |
break;
|
|
1051 |
}
|
|
1052 |
p = p->d_ptr->parent;
|
|
1053 |
}
|
|
1054 |
}
|
|
1055 |
|
|
1056 |
if ((parent = newParent)) {
|
|
1057 |
bool implicitUpdate = false;
|
|
1058 |
if (parent->d_func()->scene && parent->d_func()->scene != scene) {
|
|
1059 |
// Move this item to its new parent's scene
|
|
1060 |
parent->d_func()->scene->addItem(q);
|
|
1061 |
implicitUpdate = true;
|
|
1062 |
} else if (!parent->d_func()->scene && scene) {
|
|
1063 |
// Remove this item from its former scene
|
|
1064 |
scene->removeItem(q);
|
|
1065 |
}
|
|
1066 |
|
|
1067 |
parent->d_ptr->addChild(q);
|
|
1068 |
parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant);
|
|
1069 |
if (!implicitUpdate && scene) {
|
|
1070 |
scene->d_func()->markDirty(q_ptr, QRect(),
|
|
1071 |
/*invalidateChildren=*/false,
|
|
1072 |
/*maybeDirtyClipPath=*/true);
|
|
1073 |
}
|
|
1074 |
|
|
1075 |
// Inherit ancestor flags from the new parent.
|
|
1076 |
updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
|
|
1077 |
updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
|
|
1078 |
updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape);
|
|
1079 |
updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations);
|
|
1080 |
|
|
1081 |
// Update item visible / enabled.
|
|
1082 |
if (parent->isVisible() != visible) {
|
|
1083 |
if (!parent->isVisible() || !explicitlyHidden)
|
|
1084 |
setVisibleHelper(parent->isVisible(), /* explicit = */ false, /* update = */ !implicitUpdate);
|
|
1085 |
}
|
|
1086 |
if (parent->isEnabled() != enabled) {
|
|
1087 |
if (!parent->isEnabled() || !explicitlyDisabled)
|
|
1088 |
setEnabledHelper(parent->isEnabled(), /* explicit = */ false, /* update = */ !implicitUpdate);
|
|
1089 |
}
|
|
1090 |
|
|
1091 |
// Auto-activate if visible and the parent is active.
|
|
1092 |
if (q->isVisible() && parent->isActive())
|
|
1093 |
q->setActive(true);
|
|
1094 |
} else {
|
|
1095 |
// Inherit ancestor flags from the new parent.
|
|
1096 |
updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
|
|
1097 |
updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
|
|
1098 |
updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape);
|
|
1099 |
updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations);
|
|
1100 |
|
|
1101 |
if (!inDestructor) {
|
|
1102 |
// Update item visible / enabled.
|
|
1103 |
if (!visible && !explicitlyHidden)
|
|
1104 |
setVisibleHelper(true, /* explicit = */ false);
|
|
1105 |
if (!enabled && !explicitlyDisabled)
|
|
1106 |
setEnabledHelper(true, /* explicit = */ false);
|
|
1107 |
|
|
1108 |
// If the item is being deleted, the whole scene will be updated.
|
|
1109 |
if (scene) {
|
|
1110 |
scene->d_func()->markDirty(q_ptr, QRect(),
|
|
1111 |
/*invalidateChildren=*/false,
|
|
1112 |
/*maybeDirtyClipPath=*/true);
|
|
1113 |
}
|
|
1114 |
}
|
|
1115 |
}
|
|
1116 |
|
|
1117 |
// Resolve depth.
|
|
1118 |
invalidateDepthRecursively();
|
|
1119 |
dirtySceneTransform = 1;
|
|
1120 |
|
|
1121 |
// Restore the sub focus chain.
|
|
1122 |
if (subFocusItem) {
|
|
1123 |
subFocusItem->d_ptr->setSubFocus(newParent);
|
|
1124 |
if (parent && parent->isActive())
|
|
1125 |
subFocusItem->setFocus();
|
|
1126 |
}
|
|
1127 |
|
|
1128 |
// Deliver post-change notification
|
|
1129 |
q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant);
|
|
1130 |
|
|
1131 |
if (isObject)
|
|
1132 |
emit static_cast<QGraphicsObject *>(q)->parentChanged();
|
|
1133 |
}
|
|
1134 |
|
|
1135 |
/*!
|
|
1136 |
\internal
|
|
1137 |
|
|
1138 |
Returns the bounding rect of this item's children (excluding itself).
|
|
1139 |
*/
|
|
1140 |
void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect)
|
|
1141 |
{
|
|
1142 |
for (int i = 0; i < children.size(); ++i) {
|
|
1143 |
QGraphicsItem *child = children.at(i);
|
|
1144 |
QGraphicsItemPrivate *childd = child->d_ptr.data();
|
|
1145 |
bool hasPos = !childd->pos.isNull();
|
|
1146 |
if (hasPos || childd->transformData) {
|
|
1147 |
// COMBINE
|
|
1148 |
QTransform matrix = childd->transformToParent();
|
|
1149 |
if (x)
|
|
1150 |
matrix *= *x;
|
|
1151 |
*rect |= matrix.mapRect(child->boundingRect());
|
|
1152 |
if (!childd->children.isEmpty())
|
|
1153 |
childd->childrenBoundingRectHelper(&matrix, rect);
|
|
1154 |
} else {
|
|
1155 |
if (x)
|
|
1156 |
*rect |= x->mapRect(child->boundingRect());
|
|
1157 |
else
|
|
1158 |
*rect |= child->boundingRect();
|
|
1159 |
if (!childd->children.isEmpty())
|
|
1160 |
childd->childrenBoundingRectHelper(x, rect);
|
|
1161 |
}
|
|
1162 |
}
|
|
1163 |
}
|
|
1164 |
|
|
1165 |
void QGraphicsItemPrivate::initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform,
|
|
1166 |
const QRegion &exposedRegion, bool allItems) const
|
|
1167 |
{
|
|
1168 |
Q_ASSERT(option);
|
|
1169 |
Q_Q(const QGraphicsItem);
|
|
1170 |
|
|
1171 |
// Initialize standard QStyleOption values.
|
|
1172 |
const QRectF brect = q->boundingRect();
|
|
1173 |
option->state = QStyle::State_None;
|
|
1174 |
option->rect = brect.toRect();
|
|
1175 |
option->levelOfDetail = 1;
|
|
1176 |
option->exposedRect = brect;
|
|
1177 |
if (selected)
|
|
1178 |
option->state |= QStyle::State_Selected;
|
|
1179 |
if (enabled)
|
|
1180 |
option->state |= QStyle::State_Enabled;
|
|
1181 |
if (q->hasFocus())
|
|
1182 |
option->state |= QStyle::State_HasFocus;
|
|
1183 |
if (scene) {
|
|
1184 |
if (scene->d_func()->hoverItems.contains(q_ptr))
|
|
1185 |
option->state |= QStyle::State_MouseOver;
|
|
1186 |
if (q == scene->mouseGrabberItem())
|
|
1187 |
option->state |= QStyle::State_Sunken;
|
|
1188 |
}
|
|
1189 |
|
|
1190 |
if (!(flags & QGraphicsItem::ItemUsesExtendedStyleOption))
|
|
1191 |
return;
|
|
1192 |
|
|
1193 |
// Initialize QStyleOptionGraphicsItem specific values (matrix, exposedRect).
|
|
1194 |
option->matrix = worldTransform.toAffine(); //### discards perspective
|
|
1195 |
|
|
1196 |
if (!allItems) {
|
|
1197 |
// Determine the item's exposed area
|
|
1198 |
option->exposedRect = QRectF();
|
|
1199 |
const QTransform reverseMap = worldTransform.inverted();
|
|
1200 |
const QVector<QRect> exposedRects(exposedRegion.rects());
|
|
1201 |
for (int i = 0; i < exposedRects.size(); ++i) {
|
|
1202 |
option->exposedRect |= reverseMap.mapRect(exposedRects.at(i));
|
|
1203 |
if (option->exposedRect.contains(brect))
|
|
1204 |
break;
|
|
1205 |
}
|
|
1206 |
option->exposedRect &= brect;
|
|
1207 |
}
|
|
1208 |
}
|
|
1209 |
|
|
1210 |
/*!
|
|
1211 |
\internal
|
|
1212 |
|
|
1213 |
Empty all cached pixmaps from the pixmap cache.
|
|
1214 |
*/
|
|
1215 |
void QGraphicsItemCache::purge()
|
|
1216 |
{
|
|
1217 |
QPixmapCache::remove(key);
|
|
1218 |
key = QPixmapCache::Key();
|
|
1219 |
QMutableMapIterator<QPaintDevice *, DeviceData> it(deviceData);
|
|
1220 |
while (it.hasNext()) {
|
|
1221 |
DeviceData &data = it.next().value();
|
|
1222 |
QPixmapCache::remove(data.key);
|
|
1223 |
data.cacheIndent = QPoint();
|
|
1224 |
}
|
|
1225 |
deviceData.clear();
|
|
1226 |
allExposed = true;
|
|
1227 |
exposed.clear();
|
|
1228 |
}
|
|
1229 |
|
|
1230 |
/*!
|
|
1231 |
Constructs a QGraphicsItem, passing \a item to QGraphicsItem's constructor. It does not modify \fn QObject::parent().
|
|
1232 |
|
|
1233 |
If \a parent is 0, you can add the item to a scene by calling
|
|
1234 |
QGraphicsScene::addItem(). The item will then become a top-level item.
|
|
1235 |
|
|
1236 |
\sa QGraphicsScene::addItem(), setParentItem()
|
|
1237 |
*/
|
|
1238 |
QGraphicsItem::QGraphicsItem(QGraphicsItem *parent
|
|
1239 |
#ifndef Q_QDOC
|
|
1240 |
// obsolete argument
|
|
1241 |
, QGraphicsScene *scene
|
|
1242 |
#endif
|
|
1243 |
)
|
|
1244 |
: d_ptr(new QGraphicsItemPrivate)
|
|
1245 |
{
|
|
1246 |
d_ptr->q_ptr = this;
|
|
1247 |
setParentItem(parent);
|
|
1248 |
|
|
1249 |
if (scene && parent && parent->scene() != scene) {
|
|
1250 |
qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
|
|
1251 |
" different from parent's scene (%p)",
|
|
1252 |
scene, parent->scene());
|
|
1253 |
return;
|
|
1254 |
}
|
|
1255 |
if (scene && !parent)
|
|
1256 |
scene->addItem(this);
|
|
1257 |
}
|
|
1258 |
|
|
1259 |
/*!
|
|
1260 |
\internal
|
|
1261 |
*/
|
|
1262 |
QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent,
|
|
1263 |
QGraphicsScene *scene)
|
|
1264 |
: d_ptr(&dd)
|
|
1265 |
{
|
|
1266 |
d_ptr->q_ptr = this;
|
|
1267 |
setParentItem(parent);
|
|
1268 |
|
|
1269 |
if (scene && parent && parent->scene() != scene) {
|
|
1270 |
qWarning("QGraphicsItem::QGraphicsItem: ignoring scene (%p), which is"
|
|
1271 |
" different from parent's scene (%p)",
|
|
1272 |
scene, parent->scene());
|
|
1273 |
return;
|
|
1274 |
}
|
|
1275 |
if (scene && !parent)
|
|
1276 |
scene->addItem(this);
|
|
1277 |
}
|
|
1278 |
|
|
1279 |
/*!
|
|
1280 |
Destroys the QGraphicsItem and all its children. If this item is currently
|
|
1281 |
associated with a scene, the item will be removed from the scene before it
|
|
1282 |
is deleted.
|
|
1283 |
|
|
1284 |
\note It is more efficient to remove the item from the QGraphicsScene before
|
|
1285 |
destroying the item.
|
|
1286 |
*/
|
|
1287 |
QGraphicsItem::~QGraphicsItem()
|
|
1288 |
{
|
|
1289 |
d_ptr->inDestructor = 1;
|
|
1290 |
d_ptr->removeExtraItemCache();
|
|
1291 |
|
|
1292 |
clearFocus();
|
|
1293 |
|
|
1294 |
// Update focus scope item ptr.
|
|
1295 |
QGraphicsItem *p = d_ptr->parent;
|
|
1296 |
while (p) {
|
|
1297 |
if (p->flags() & ItemIsFocusScope) {
|
|
1298 |
if (p->d_ptr->focusScopeItem == this)
|
|
1299 |
p->d_ptr->focusScopeItem = 0;
|
|
1300 |
break;
|
|
1301 |
}
|
|
1302 |
p = p->d_ptr->parent;
|
|
1303 |
}
|
|
1304 |
|
|
1305 |
if (!d_ptr->children.isEmpty()) {
|
|
1306 |
QList<QGraphicsItem *> oldChildren = d_ptr->children;
|
|
1307 |
qDeleteAll(oldChildren);
|
|
1308 |
Q_ASSERT(d_ptr->children.isEmpty());
|
|
1309 |
}
|
|
1310 |
|
|
1311 |
if (d_ptr->scene) {
|
|
1312 |
d_ptr->scene->d_func()->removeItemHelper(this);
|
|
1313 |
} else {
|
|
1314 |
d_ptr->resetFocusProxy();
|
|
1315 |
d_ptr->setParentItemHelper(0);
|
|
1316 |
}
|
|
1317 |
|
|
1318 |
delete d_ptr->graphicsEffect;
|
|
1319 |
if (d_ptr->transformData) {
|
|
1320 |
for(int i = 0; i < d_ptr->transformData->graphicsTransforms.size(); ++i) {
|
|
1321 |
QGraphicsTransform *t = d_ptr->transformData->graphicsTransforms.at(i);
|
|
1322 |
static_cast<QGraphicsTransformPrivate *>(t->d_ptr.data())->item = 0;
|
|
1323 |
delete t;
|
|
1324 |
}
|
|
1325 |
}
|
|
1326 |
delete d_ptr->transformData;
|
|
1327 |
|
|
1328 |
qt_dataStore()->data.remove(this);
|
|
1329 |
}
|
|
1330 |
|
|
1331 |
/*!
|
|
1332 |
Returns the current scene for the item, or 0 if the item is not stored in
|
|
1333 |
a scene.
|
|
1334 |
|
|
1335 |
To add or move an item to a scene, call QGraphicsScene::addItem().
|
|
1336 |
*/
|
|
1337 |
QGraphicsScene *QGraphicsItem::scene() const
|
|
1338 |
{
|
|
1339 |
return d_ptr->scene;
|
|
1340 |
}
|
|
1341 |
|
|
1342 |
/*!
|
|
1343 |
Returns a pointer to this item's item group, or 0 if this item is not
|
|
1344 |
member of a group.
|
|
1345 |
|
|
1346 |
\sa QGraphicsItemGroup, QGraphicsScene::createItemGroup()
|
|
1347 |
*/
|
|
1348 |
QGraphicsItemGroup *QGraphicsItem::group() const
|
|
1349 |
{
|
|
1350 |
if (!d_ptr->isMemberOfGroup)
|
|
1351 |
return 0;
|
|
1352 |
QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
|
|
1353 |
while ((parent = parent->d_ptr->parent)) {
|
|
1354 |
if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(parent))
|
|
1355 |
return group;
|
|
1356 |
}
|
|
1357 |
// Unreachable; if d_ptr->isMemberOfGroup is != 0, then one parent of this
|
|
1358 |
// item is a group item.
|
|
1359 |
return 0;
|
|
1360 |
}
|
|
1361 |
|
|
1362 |
/*!
|
|
1363 |
Adds this item to the item group \a group. If \a group is 0, this item is
|
|
1364 |
removed from any current group and added as a child of the previous
|
|
1365 |
group's parent.
|
|
1366 |
|
|
1367 |
\sa group(), QGraphicsScene::createItemGroup()
|
|
1368 |
*/
|
|
1369 |
void QGraphicsItem::setGroup(QGraphicsItemGroup *group)
|
|
1370 |
{
|
|
1371 |
if (!group) {
|
|
1372 |
if (QGraphicsItemGroup *group = this->group())
|
|
1373 |
group->removeFromGroup(this);
|
|
1374 |
} else {
|
|
1375 |
group->addToGroup(this);
|
|
1376 |
}
|
|
1377 |
}
|
|
1378 |
|
|
1379 |
/*!
|
|
1380 |
Returns a pointer to this item's parent item. If this item does not have a
|
|
1381 |
parent, 0 is returned.
|
|
1382 |
|
|
1383 |
\sa setParentItem(), childItems()
|
|
1384 |
*/
|
|
1385 |
QGraphicsItem *QGraphicsItem::parentItem() const
|
|
1386 |
{
|
|
1387 |
return d_ptr->parent;
|
|
1388 |
}
|
|
1389 |
|
|
1390 |
/*!
|
|
1391 |
Returns this item's top-level item. The top-level item is the item's
|
|
1392 |
topmost ancestor item whose parent is 0. If an item has no parent, its own
|
|
1393 |
pointer is returned (i.e., a top-level item is its own top-level item).
|
|
1394 |
|
|
1395 |
\sa parentItem()
|
|
1396 |
*/
|
|
1397 |
QGraphicsItem *QGraphicsItem::topLevelItem() const
|
|
1398 |
{
|
|
1399 |
QGraphicsItem *parent = const_cast<QGraphicsItem *>(this);
|
|
1400 |
while (QGraphicsItem *grandPa = parent->parentItem())
|
|
1401 |
parent = grandPa;
|
|
1402 |
return parent;
|
|
1403 |
}
|
|
1404 |
|
|
1405 |
/*!
|
|
1406 |
\since 4.6
|
|
1407 |
|
|
1408 |
Returns a pointer to the item's parent, cast to a QGraphicsObject. returns 0 if the parent item
|
|
1409 |
is not a QGraphicsObject.
|
|
1410 |
|
|
1411 |
\sa parentItem(), childItems()
|
|
1412 |
*/
|
|
1413 |
QGraphicsObject *QGraphicsItem::parentObject() const
|
|
1414 |
{
|
|
1415 |
QGraphicsItem *p = d_ptr->parent;
|
|
1416 |
return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : 0;
|
|
1417 |
}
|
|
1418 |
|
|
1419 |
/*!
|
|
1420 |
\since 4.4
|
|
1421 |
|
|
1422 |
Returns a pointer to the item's parent widget. The item's parent widget is
|
|
1423 |
the closest parent item that is a widget.
|
|
1424 |
|
|
1425 |
\sa parentItem(), childItems()
|
|
1426 |
*/
|
|
1427 |
QGraphicsWidget *QGraphicsItem::parentWidget() const
|
|
1428 |
{
|
|
1429 |
QGraphicsItem *p = parentItem();
|
|
1430 |
while (p && !p->isWidget())
|
|
1431 |
p = p->parentItem();
|
|
1432 |
return (p && p->isWidget()) ? static_cast<QGraphicsWidget *>(p) : 0;
|
|
1433 |
}
|
|
1434 |
|
|
1435 |
/*!
|
|
1436 |
\since 4.4
|
|
1437 |
|
|
1438 |
Returns a pointer to the item's top level widget (i.e., the item's
|
|
1439 |
ancestor whose parent is 0, or whose parent is not a widget), or 0 if this
|
|
1440 |
item does not have a top level widget. If the item is its own top level
|
|
1441 |
widget, this function returns a pointer to the item itself.
|
|
1442 |
*/
|
|
1443 |
QGraphicsWidget *QGraphicsItem::topLevelWidget() const
|
|
1444 |
{
|
|
1445 |
if (const QGraphicsWidget *p = parentWidget())
|
|
1446 |
return p->topLevelWidget();
|
|
1447 |
return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : 0;
|
|
1448 |
}
|
|
1449 |
|
|
1450 |
/*!
|
|
1451 |
\since 4.4
|
|
1452 |
|
|
1453 |
Returns the item's window, or 0 if this item does not have a window. If
|
|
1454 |
the item is a window, it will return itself. Otherwise it will return the
|
|
1455 |
closest ancestor that is a window.
|
|
1456 |
|
|
1457 |
\sa QGraphicsWidget::isWindow()
|
|
1458 |
*/
|
|
1459 |
QGraphicsWidget *QGraphicsItem::window() const
|
|
1460 |
{
|
|
1461 |
QGraphicsItem *p = panel();
|
|
1462 |
if (p && p->isWindow())
|
|
1463 |
return static_cast<QGraphicsWidget *>(p);
|
|
1464 |
return 0;
|
|
1465 |
}
|
|
1466 |
|
|
1467 |
/*!
|
|
1468 |
\since 4.6
|
|
1469 |
|
|
1470 |
Returns the item's panel, or 0 if this item does not have a panel. If the
|
|
1471 |
item is a panel, it will return itself. Otherwise it will return the
|
|
1472 |
closest ancestor that is a panel.
|
|
1473 |
|
|
1474 |
\sa isPanel(), ItemIsPanel
|
|
1475 |
*/
|
|
1476 |
QGraphicsItem *QGraphicsItem::panel() const
|
|
1477 |
{
|
|
1478 |
if (d_ptr->flags & ItemIsPanel)
|
|
1479 |
return const_cast<QGraphicsItem *>(this);
|
|
1480 |
return d_ptr->parent ? d_ptr->parent->panel() : 0;
|
|
1481 |
}
|
|
1482 |
|
|
1483 |
/*!
|
|
1484 |
\since 4.6
|
|
1485 |
|
|
1486 |
Return the graphics item cast to a QGraphicsObject, if the class is actually a
|
|
1487 |
graphics object, 0 otherwise.
|
|
1488 |
*/
|
|
1489 |
QGraphicsObject *QGraphicsItem::toGraphicsObject()
|
|
1490 |
{
|
|
1491 |
return d_ptr->isObject ? static_cast<QGraphicsObject *>(this) : 0;
|
|
1492 |
}
|
|
1493 |
|
|
1494 |
/*!
|
|
1495 |
\since 4.6
|
|
1496 |
|
|
1497 |
Return the graphics item cast to a QGraphicsObject, if the class is actually a
|
|
1498 |
graphics object, 0 otherwise.
|
|
1499 |
*/
|
|
1500 |
const QGraphicsObject *QGraphicsItem::toGraphicsObject() const
|
|
1501 |
{
|
|
1502 |
return d_ptr->isObject ? static_cast<const QGraphicsObject *>(this) : 0;
|
|
1503 |
}
|
|
1504 |
|
|
1505 |
/*!
|
|
1506 |
Sets this item's parent item to \a parent. If this item already has a
|
|
1507 |
parent, it is first removed from the previous parent. If \a parent is 0,
|
|
1508 |
this item will become a top-level item.
|
|
1509 |
|
|
1510 |
Note that this implicitly adds this graphics item to the scene of
|
|
1511 |
the parent. You should not \l{QGraphicsScene::addItem()}{add} the
|
|
1512 |
item to the scene yourself.
|
|
1513 |
|
|
1514 |
Calling this function on an item that is an ancestor of \a parent have undefined behaviour.
|
|
1515 |
|
|
1516 |
\sa parentItem(), childItems()
|
|
1517 |
*/
|
|
1518 |
void QGraphicsItem::setParentItem(QGraphicsItem *parent)
|
|
1519 |
{
|
|
1520 |
d_ptr->setParentItemHelper(parent);
|
|
1521 |
}
|
|
1522 |
|
|
1523 |
/*!
|
|
1524 |
\obsolete
|
|
1525 |
|
|
1526 |
Use childItems() instead.
|
|
1527 |
|
|
1528 |
\sa setParentItem()
|
|
1529 |
*/
|
|
1530 |
QList<QGraphicsItem *> QGraphicsItem::children() const
|
|
1531 |
{
|
|
1532 |
return childItems();
|
|
1533 |
}
|
|
1534 |
|
|
1535 |
/*!
|
|
1536 |
\since 4.4
|
|
1537 |
|
|
1538 |
Returns a list of this item's children.
|
|
1539 |
|
|
1540 |
The items are sorted by stacking order. This takes into account both the
|
|
1541 |
items' insertion order and their Z-values.
|
|
1542 |
|
|
1543 |
\sa setParentItem(), zValue(), {QGraphicsItem#Sorting}{Sorting}
|
|
1544 |
*/
|
|
1545 |
QList<QGraphicsItem *> QGraphicsItem::childItems() const
|
|
1546 |
{
|
|
1547 |
const_cast<QGraphicsItem *>(this)->d_ptr->ensureSortedChildren();
|
|
1548 |
return d_ptr->children;
|
|
1549 |
}
|
|
1550 |
|
|
1551 |
/*!
|
|
1552 |
\since 4.4
|
|
1553 |
Returns true if this item is a widget (i.e., QGraphicsWidget); otherwise,
|
|
1554 |
returns false.
|
|
1555 |
*/
|
|
1556 |
bool QGraphicsItem::isWidget() const
|
|
1557 |
{
|
|
1558 |
return d_ptr->isWidget;
|
|
1559 |
}
|
|
1560 |
|
|
1561 |
/*!
|
|
1562 |
\since 4.4
|
|
1563 |
Returns true if the item is a QGraphicsWidget window, otherwise returns
|
|
1564 |
false.
|
|
1565 |
|
|
1566 |
\sa QGraphicsWidget::windowFlags()
|
|
1567 |
*/
|
|
1568 |
bool QGraphicsItem::isWindow() const
|
|
1569 |
{
|
|
1570 |
return isWidget() && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window);
|
|
1571 |
}
|
|
1572 |
|
|
1573 |
/*!
|
|
1574 |
\since 4.6
|
|
1575 |
Returns true if the item is a panel; otherwise returns false.
|
|
1576 |
|
|
1577 |
\sa QGraphicsItem::panel(), ItemIsPanel
|
|
1578 |
*/
|
|
1579 |
bool QGraphicsItem::isPanel() const
|
|
1580 |
{
|
|
1581 |
return d_ptr->flags & ItemIsPanel;
|
|
1582 |
}
|
|
1583 |
|
|
1584 |
/*!
|
|
1585 |
Returns this item's flags. The flags describe what configurable features
|
|
1586 |
of the item are enabled and not. For example, if the flags include
|
|
1587 |
ItemIsFocusable, the item can accept input focus.
|
|
1588 |
|
|
1589 |
By default, no flags are enabled.
|
|
1590 |
|
|
1591 |
\sa setFlags(), setFlag()
|
|
1592 |
*/
|
|
1593 |
QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const
|
|
1594 |
{
|
|
1595 |
return GraphicsItemFlags(d_ptr->flags);
|
|
1596 |
}
|
|
1597 |
|
|
1598 |
/*!
|
|
1599 |
If \a enabled is true, the item flag \a flag is enabled; otherwise, it is
|
|
1600 |
disabled.
|
|
1601 |
|
|
1602 |
\sa flags(), setFlags()
|
|
1603 |
*/
|
|
1604 |
void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled)
|
|
1605 |
{
|
|
1606 |
if (enabled)
|
|
1607 |
setFlags(flags() | flag);
|
|
1608 |
else
|
|
1609 |
setFlags(flags() & ~flag);
|
|
1610 |
}
|
|
1611 |
|
|
1612 |
/*!
|
|
1613 |
\internal
|
|
1614 |
|
|
1615 |
Sets the flag \a flag on \a item and all its children, to \a enabled.
|
|
1616 |
*/
|
|
1617 |
static void _q_qgraphicsItemSetFlag(QGraphicsItem *item, QGraphicsItem::GraphicsItemFlag flag,
|
|
1618 |
bool enabled)
|
|
1619 |
{
|
|
1620 |
if (item->flags() & flag) {
|
|
1621 |
// If this item already has the correct flag set, we don't have to
|
|
1622 |
// propagate it.
|
|
1623 |
return;
|
|
1624 |
}
|
|
1625 |
item->setFlag(flag, enabled);
|
|
1626 |
foreach (QGraphicsItem *child, item->children())
|
|
1627 |
_q_qgraphicsItemSetFlag(child, flag, enabled);
|
|
1628 |
}
|
|
1629 |
|
|
1630 |
/*!
|
|
1631 |
Sets the item flags to \a flags. All flags in \a flags are enabled; all
|
|
1632 |
flags not in \a flags are disabled.
|
|
1633 |
|
|
1634 |
If the item had focus and \a flags does not enable ItemIsFocusable, the
|
|
1635 |
item loses focus as a result of calling this function. Similarly, if the
|
|
1636 |
item was selected, and \a flags does not enabled ItemIsSelectable, the
|
|
1637 |
item is automatically unselected.
|
|
1638 |
|
|
1639 |
By default, no flags are enabled. (QGraphicsWidget enables the
|
|
1640 |
ItemSendsGeometryChanges flag by default in order to track position
|
|
1641 |
changes.)
|
|
1642 |
|
|
1643 |
\sa flags(), setFlag()
|
|
1644 |
*/
|
|
1645 |
void QGraphicsItem::setFlags(GraphicsItemFlags flags)
|
|
1646 |
{
|
|
1647 |
if (isWindow())
|
|
1648 |
flags |= ItemIsPanel;
|
|
1649 |
|
|
1650 |
// Notify change and check for adjustment.
|
|
1651 |
if (quint32(d_ptr->flags) == quint32(flags))
|
|
1652 |
return;
|
|
1653 |
flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt());
|
|
1654 |
if (quint32(d_ptr->flags) == quint32(flags))
|
|
1655 |
return;
|
|
1656 |
if (d_ptr->scene)
|
|
1657 |
d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags));
|
|
1658 |
|
|
1659 |
// Flags that alter the geometry of the item (or its children).
|
|
1660 |
const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations);
|
|
1661 |
bool fullUpdate = (quint32(flags) & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask);
|
|
1662 |
if (fullUpdate)
|
|
1663 |
d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
|
|
1664 |
|
|
1665 |
// Keep the old flags to compare the diff.
|
|
1666 |
GraphicsItemFlags oldFlags = this->flags();
|
|
1667 |
|
|
1668 |
// Update flags.
|
|
1669 |
d_ptr->flags = flags;
|
|
1670 |
|
|
1671 |
if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) {
|
|
1672 |
// Clear focus on the item if it has focus when the focusable flag
|
|
1673 |
// is unset.
|
|
1674 |
clearFocus();
|
|
1675 |
}
|
|
1676 |
|
|
1677 |
if (!(d_ptr->flags & ItemIsSelectable) && isSelected()) {
|
|
1678 |
// Unselect the item if it is selected when the selectable flag is
|
|
1679 |
// unset.
|
|
1680 |
setSelected(false);
|
|
1681 |
}
|
|
1682 |
|
|
1683 |
if ((flags & ItemClipsChildrenToShape) != (oldFlags & ItemClipsChildrenToShape)) {
|
|
1684 |
// Item children clipping changes. Propagate the ancestor flag to
|
|
1685 |
// all children.
|
|
1686 |
d_ptr->updateAncestorFlag(ItemClipsChildrenToShape);
|
|
1687 |
}
|
|
1688 |
|
|
1689 |
if ((flags & ItemClipsToShape) != (oldFlags & ItemClipsToShape))
|
|
1690 |
d_ptr->invalidateCachedClipPath();
|
|
1691 |
|
|
1692 |
if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) {
|
|
1693 |
// Item children clipping changes. Propagate the ancestor flag to
|
|
1694 |
// all children.
|
|
1695 |
d_ptr->updateAncestorFlag(ItemIgnoresTransformations);
|
|
1696 |
}
|
|
1697 |
|
|
1698 |
if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) {
|
|
1699 |
// Ensure child item sorting is up to date when toggling this flag.
|
|
1700 |
if (d_ptr->parent)
|
|
1701 |
d_ptr->parent->d_ptr->needSortChildren = 1;
|
|
1702 |
else if (d_ptr->scene)
|
|
1703 |
d_ptr->scene->d_func()->needSortTopLevelItems = 1;
|
|
1704 |
}
|
|
1705 |
|
|
1706 |
if ((flags & ItemAcceptsInputMethod) != (oldFlags & ItemAcceptsInputMethod)) {
|
|
1707 |
// Update input method sensitivity in any views.
|
|
1708 |
if (d_ptr->scene)
|
|
1709 |
d_ptr->scene->d_func()->updateInputMethodSensitivityInViews();
|
|
1710 |
}
|
|
1711 |
|
|
1712 |
if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) {
|
|
1713 |
// Update stack-behind.
|
|
1714 |
setFlag(ItemStacksBehindParent, d_ptr->z < qreal(0.0));
|
|
1715 |
}
|
|
1716 |
|
|
1717 |
if ((d_ptr->panelModality != NonModal)
|
|
1718 |
&& d_ptr->scene
|
|
1719 |
&& (flags & ItemIsPanel) != (oldFlags & ItemIsPanel)) {
|
|
1720 |
// update the panel's modal state
|
|
1721 |
if (flags & ItemIsPanel)
|
|
1722 |
d_ptr->scene->d_func()->enterModal(this);
|
|
1723 |
else
|
|
1724 |
d_ptr->scene->d_func()->leaveModal(this);
|
|
1725 |
}
|
|
1726 |
|
|
1727 |
if (d_ptr->scene) {
|
|
1728 |
d_ptr->scene->d_func()->markDirty(this, QRectF(),
|
|
1729 |
/*invalidateChildren=*/true,
|
|
1730 |
/*maybeDirtyClipPath*/true);
|
|
1731 |
}
|
|
1732 |
|
|
1733 |
// Notify change.
|
|
1734 |
itemChange(ItemFlagsHaveChanged, quint32(flags));
|
|
1735 |
}
|
|
1736 |
|
|
1737 |
/*!
|
|
1738 |
\since 4.4
|
|
1739 |
Returns the cache mode for this item. The default mode is NoCache (i.e.,
|
|
1740 |
cache is disabled and all painting is immediate).
|
|
1741 |
|
|
1742 |
\sa setCacheMode()
|
|
1743 |
*/
|
|
1744 |
QGraphicsItem::CacheMode QGraphicsItem::cacheMode() const
|
|
1745 |
{
|
|
1746 |
return QGraphicsItem::CacheMode(d_ptr->cacheMode);
|
|
1747 |
}
|
|
1748 |
|
|
1749 |
/*!
|
|
1750 |
\since 4.4
|
|
1751 |
Sets the item's cache mode to \a mode.
|
|
1752 |
|
|
1753 |
The optional \a logicalCacheSize argument is used only by
|
|
1754 |
ItemCoordinateCache mode, and describes the resolution of the cache
|
|
1755 |
buffer; if \a logicalCacheSize is (100, 100), QGraphicsItem will fit the
|
|
1756 |
item into 100x100 pixels in graphics memory, regardless of the logical
|
|
1757 |
size of the item itself. By default QGraphicsItem uses the size of
|
|
1758 |
boundingRect(). For all other cache modes than ItemCoordinateCache, \a
|
|
1759 |
logicalCacheSize is ignored.
|
|
1760 |
|
|
1761 |
Caching can speed up rendering if your item spends a significant time
|
|
1762 |
redrawing itself. In some cases the cache can also slow down rendering, in
|
|
1763 |
particular when the item spends less time redrawing than QGraphicsItem
|
|
1764 |
spends redrawing from the cache. When enabled, the item's paint() function
|
|
1765 |
will be called only once for each call to update(); for any subsequent
|
|
1766 |
repaint requests, the Graphics View framework will redraw from the
|
|
1767 |
cache. This approach works particularly well with QGLWidget, which stores
|
|
1768 |
all the cache as OpenGL textures.
|
|
1769 |
|
|
1770 |
Be aware that QPixmapCache's cache limit may need to be changed to obtain
|
|
1771 |
optimal performance.
|
|
1772 |
|
|
1773 |
You can read more about the different cache modes in the CacheMode
|
|
1774 |
documentation.
|
|
1775 |
|
|
1776 |
\sa CacheMode, QPixmapCache::setCacheLimit()
|
|
1777 |
*/
|
|
1778 |
void QGraphicsItem::setCacheMode(CacheMode mode, const QSize &logicalCacheSize)
|
|
1779 |
{
|
|
1780 |
CacheMode lastMode = CacheMode(d_ptr->cacheMode);
|
|
1781 |
d_ptr->cacheMode = mode;
|
|
1782 |
bool noVisualChange = (mode == NoCache && lastMode == NoCache)
|
|
1783 |
|| (mode == NoCache && lastMode == DeviceCoordinateCache)
|
|
1784 |
|| (mode == DeviceCoordinateCache && lastMode == NoCache);
|
|
1785 |
if (mode == NoCache) {
|
|
1786 |
d_ptr->removeExtraItemCache();
|
|
1787 |
} else {
|
|
1788 |
QGraphicsItemCache *cache = d_ptr->extraItemCache();
|
|
1789 |
|
|
1790 |
// Reset old cache
|
|
1791 |
cache->purge();
|
|
1792 |
|
|
1793 |
if (mode == ItemCoordinateCache) {
|
|
1794 |
if (lastMode == mode && cache->fixedSize == logicalCacheSize)
|
|
1795 |
noVisualChange = true;
|
|
1796 |
cache->fixedSize = logicalCacheSize;
|
|
1797 |
}
|
|
1798 |
}
|
|
1799 |
if (!noVisualChange)
|
|
1800 |
update();
|
|
1801 |
}
|
|
1802 |
|
|
1803 |
/*!
|
|
1804 |
\since 4.6
|
|
1805 |
|
|
1806 |
Returns the modality for this item.
|
|
1807 |
*/
|
|
1808 |
QGraphicsItem::PanelModality QGraphicsItem::panelModality() const
|
|
1809 |
{
|
|
1810 |
return d_ptr->panelModality;
|
|
1811 |
}
|
|
1812 |
|
|
1813 |
/*!
|
|
1814 |
\since 4.6
|
|
1815 |
|
|
1816 |
Sets the modality for this item to \a panelModality.
|
|
1817 |
|
|
1818 |
Changing the modality of a visible item takes effect immediately.
|
|
1819 |
*/
|
|
1820 |
void QGraphicsItem::setPanelModality(PanelModality panelModality)
|
|
1821 |
{
|
|
1822 |
if (d_ptr->panelModality == panelModality)
|
|
1823 |
return;
|
|
1824 |
|
|
1825 |
PanelModality previousModality = d_ptr->panelModality;
|
|
1826 |
bool enterLeaveModal = (isPanel() && d_ptr->scene && isVisible());
|
|
1827 |
if (enterLeaveModal && panelModality == NonModal)
|
|
1828 |
d_ptr->scene->d_func()->leaveModal(this);
|
|
1829 |
d_ptr->panelModality = panelModality;
|
|
1830 |
if (enterLeaveModal && d_ptr->panelModality != NonModal)
|
|
1831 |
d_ptr->scene->d_func()->enterModal(this, previousModality);
|
|
1832 |
}
|
|
1833 |
|
|
1834 |
/*!
|
|
1835 |
\since 4.6
|
|
1836 |
|
|
1837 |
Returns true if this item is blocked by a modal panel, false otherwise. If \a blockingPanel is
|
|
1838 |
non-zero, \a blockingPanel will be set to the modal panel that is blocking this item. If this
|
|
1839 |
item is not blocked, \a blockingPanel will not be set by this function.
|
|
1840 |
|
|
1841 |
This function always returns false for items not in a scene.
|
|
1842 |
|
|
1843 |
\sa panelModality() setPanelModality() PanelModality
|
|
1844 |
*/
|
|
1845 |
bool QGraphicsItem::isBlockedByModalPanel(QGraphicsItem **blockingPanel) const
|
|
1846 |
{
|
|
1847 |
if (!d_ptr->scene)
|
|
1848 |
return false;
|
|
1849 |
|
|
1850 |
|
|
1851 |
QGraphicsItem *dummy = 0;
|
|
1852 |
if (!blockingPanel)
|
|
1853 |
blockingPanel = &dummy;
|
|
1854 |
|
|
1855 |
QGraphicsScenePrivate *scene_d = d_ptr->scene->d_func();
|
|
1856 |
if (scene_d->modalPanels.isEmpty())
|
|
1857 |
return false;
|
|
1858 |
|
|
1859 |
// ###
|
|
1860 |
if (!scene_d->popupWidgets.isEmpty() && scene_d->popupWidgets.first() == this)
|
|
1861 |
return false;
|
|
1862 |
|
|
1863 |
for (int i = 0; i < scene_d->modalPanels.count(); ++i) {
|
|
1864 |
QGraphicsItem *modalPanel = scene_d->modalPanels.at(i);
|
|
1865 |
if (modalPanel->panelModality() == QGraphicsItem::SceneModal) {
|
|
1866 |
// Scene modal panels block all non-descendents.
|
|
1867 |
if (modalPanel != this && !modalPanel->isAncestorOf(this)) {
|
|
1868 |
*blockingPanel = modalPanel;
|
|
1869 |
return true;
|
|
1870 |
}
|
|
1871 |
} else {
|
|
1872 |
// Window modal panels block ancestors and siblings/cousins.
|
|
1873 |
if (modalPanel != this
|
|
1874 |
&& !modalPanel->isAncestorOf(this)
|
|
1875 |
&& commonAncestorItem(modalPanel)) {
|
|
1876 |
*blockingPanel = modalPanel;
|
|
1877 |
return true;
|
|
1878 |
}
|
|
1879 |
}
|
|
1880 |
}
|
|
1881 |
return false;
|
|
1882 |
}
|
|
1883 |
|
|
1884 |
#ifndef QT_NO_TOOLTIP
|
|
1885 |
/*!
|
|
1886 |
Returns the item's tool tip, or an empty QString if no tool tip has been
|
|
1887 |
set.
|
|
1888 |
|
|
1889 |
\sa setToolTip(), QToolTip
|
|
1890 |
*/
|
|
1891 |
QString QGraphicsItem::toolTip() const
|
|
1892 |
{
|
|
1893 |
return d_ptr->extra(QGraphicsItemPrivate::ExtraToolTip).toString();
|
|
1894 |
}
|
|
1895 |
|
|
1896 |
/*!
|
|
1897 |
Sets the item's tool tip to \a toolTip. If \a toolTip is empty, the item's
|
|
1898 |
tool tip is cleared.
|
|
1899 |
|
|
1900 |
\sa toolTip(), QToolTip
|
|
1901 |
*/
|
|
1902 |
void QGraphicsItem::setToolTip(const QString &toolTip)
|
|
1903 |
{
|
|
1904 |
const QVariant toolTipVariant(itemChange(ItemToolTipChange, toolTip));
|
|
1905 |
d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTipVariant.toString());
|
|
1906 |
itemChange(ItemToolTipHasChanged, toolTipVariant);
|
|
1907 |
}
|
|
1908 |
#endif // QT_NO_TOOLTIP
|
|
1909 |
|
|
1910 |
#ifndef QT_NO_CURSOR
|
|
1911 |
/*!
|
|
1912 |
Returns the current cursor shape for the item. The mouse cursor
|
|
1913 |
will assume this shape when it's over this item. See the \link
|
|
1914 |
Qt::CursorShape list of predefined cursor objects\endlink for a
|
|
1915 |
range of useful shapes.
|
|
1916 |
|
|
1917 |
An editor item might want to use an I-beam cursor:
|
|
1918 |
|
|
1919 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 2
|
|
1920 |
|
|
1921 |
If no cursor has been set, the parent's cursor is used.
|
|
1922 |
|
|
1923 |
\sa setCursor(), hasCursor(), unsetCursor(), QWidget::cursor,
|
|
1924 |
QApplication::overrideCursor()
|
|
1925 |
*/
|
|
1926 |
QCursor QGraphicsItem::cursor() const
|
|
1927 |
{
|
|
1928 |
return qVariantValue<QCursor>(d_ptr->extra(QGraphicsItemPrivate::ExtraCursor));
|
|
1929 |
}
|
|
1930 |
|
|
1931 |
/*!
|
|
1932 |
Sets the current cursor shape for the item to \a cursor. The mouse cursor
|
|
1933 |
will assume this shape when it's over this item. See the \link
|
|
1934 |
Qt::CursorShape list of predefined cursor objects\endlink for a range of
|
|
1935 |
useful shapes.
|
|
1936 |
|
|
1937 |
An editor item might want to use an I-beam cursor:
|
|
1938 |
|
|
1939 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 3
|
|
1940 |
|
|
1941 |
If no cursor has been set, the cursor of the item beneath is used.
|
|
1942 |
|
|
1943 |
\sa cursor(), hasCursor(), unsetCursor(), QWidget::cursor,
|
|
1944 |
QApplication::overrideCursor()
|
|
1945 |
*/
|
|
1946 |
void QGraphicsItem::setCursor(const QCursor &cursor)
|
|
1947 |
{
|
|
1948 |
const QVariant cursorVariant(itemChange(ItemCursorChange, qVariantFromValue<QCursor>(cursor)));
|
|
1949 |
d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qVariantValue<QCursor>(cursorVariant));
|
|
1950 |
d_ptr->hasCursor = 1;
|
|
1951 |
if (d_ptr->scene) {
|
|
1952 |
d_ptr->scene->d_func()->allItemsUseDefaultCursor = false;
|
|
1953 |
foreach (QGraphicsView *view, d_ptr->scene->views()) {
|
|
1954 |
view->viewport()->setMouseTracking(true);
|
|
1955 |
// Note: Some of this logic is duplicated in QGraphicsView's mouse events.
|
|
1956 |
if (view->underMouse()) {
|
|
1957 |
foreach (QGraphicsItem *itemUnderCursor, view->items(view->mapFromGlobal(QCursor::pos()))) {
|
|
1958 |
if (itemUnderCursor->hasCursor()) {
|
|
1959 |
QMetaObject::invokeMethod(view, "_q_setViewportCursor",
|
|
1960 |
Q_ARG(QCursor, itemUnderCursor->cursor()));
|
|
1961 |
break;
|
|
1962 |
}
|
|
1963 |
}
|
|
1964 |
break;
|
|
1965 |
}
|
|
1966 |
}
|
|
1967 |
}
|
|
1968 |
itemChange(ItemCursorHasChanged, cursorVariant);
|
|
1969 |
}
|
|
1970 |
|
|
1971 |
/*!
|
|
1972 |
Returns true if this item has a cursor set; otherwise, false is returned.
|
|
1973 |
|
|
1974 |
By default, items don't have any cursor set. cursor() will return a
|
|
1975 |
standard pointing arrow cursor.
|
|
1976 |
|
|
1977 |
\sa unsetCursor()
|
|
1978 |
*/
|
|
1979 |
bool QGraphicsItem::hasCursor() const
|
|
1980 |
{
|
|
1981 |
return d_ptr->hasCursor;
|
|
1982 |
}
|
|
1983 |
|
|
1984 |
/*!
|
|
1985 |
Clears the cursor from this item.
|
|
1986 |
|
|
1987 |
\sa hasCursor(), setCursor()
|
|
1988 |
*/
|
|
1989 |
void QGraphicsItem::unsetCursor()
|
|
1990 |
{
|
|
1991 |
d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraCursor);
|
|
1992 |
d_ptr->hasCursor = 0;
|
|
1993 |
if (d_ptr->scene) {
|
|
1994 |
foreach (QGraphicsView *view, d_ptr->scene->views()) {
|
|
1995 |
if (view->underMouse() && view->itemAt(view->mapFromGlobal(QCursor::pos())) == this) {
|
|
1996 |
QMetaObject::invokeMethod(view, "_q_unsetViewportCursor");
|
|
1997 |
break;
|
|
1998 |
}
|
|
1999 |
}
|
|
2000 |
}
|
|
2001 |
}
|
|
2002 |
|
|
2003 |
#endif // QT_NO_CURSOR
|
|
2004 |
|
|
2005 |
/*!
|
|
2006 |
Returns true if the item is visible; otherwise, false is returned.
|
|
2007 |
|
|
2008 |
Note that the item's general visibility is unrelated to whether or not it
|
|
2009 |
is actually being visualized by a QGraphicsView.
|
|
2010 |
|
|
2011 |
\sa setVisible()
|
|
2012 |
*/
|
|
2013 |
bool QGraphicsItem::isVisible() const
|
|
2014 |
{
|
|
2015 |
return d_ptr->visible;
|
|
2016 |
}
|
|
2017 |
|
|
2018 |
/*!
|
|
2019 |
\since 4.4
|
|
2020 |
Returns true if the item is visible to \a parent; otherwise, false is
|
|
2021 |
returned. \a parent can be 0, in which case this function will return
|
|
2022 |
whether the item is visible to the scene or not.
|
|
2023 |
|
|
2024 |
An item may not be visible to its ancestors even if isVisible() is true. If
|
|
2025 |
any ancestor is hidden, the item itself will be implicitly hidden, in which
|
|
2026 |
case this function will return false.
|
|
2027 |
|
|
2028 |
\sa isVisible(), setVisible()
|
|
2029 |
*/
|
|
2030 |
bool QGraphicsItem::isVisibleTo(const QGraphicsItem *parent) const
|
|
2031 |
{
|
|
2032 |
if (!d_ptr->visible)
|
|
2033 |
return false;
|
|
2034 |
if (parent == this)
|
|
2035 |
return true;
|
|
2036 |
if (parentItem() && parentItem()->isVisibleTo(parent))
|
|
2037 |
return true;
|
|
2038 |
if (!parent && !parentItem())
|
|
2039 |
return true;
|
|
2040 |
return false;
|
|
2041 |
}
|
|
2042 |
|
|
2043 |
/*!
|
|
2044 |
\internal
|
|
2045 |
|
|
2046 |
Sets this item's visibility to \a newVisible. If \a explicitly is true,
|
|
2047 |
this item will be "explicitly" \a newVisible; otherwise, it.. will not be.
|
|
2048 |
*/
|
|
2049 |
void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bool update)
|
|
2050 |
{
|
|
2051 |
Q_Q(QGraphicsItem);
|
|
2052 |
|
|
2053 |
// Update explicit bit.
|
|
2054 |
if (explicitly)
|
|
2055 |
explicitlyHidden = newVisible ? 0 : 1;
|
|
2056 |
|
|
2057 |
// Check if there's nothing to do.
|
|
2058 |
if (visible == quint32(newVisible))
|
|
2059 |
return;
|
|
2060 |
|
|
2061 |
// Don't show child if parent is not visible
|
|
2062 |
if (parent && newVisible && !parent->d_ptr->visible)
|
|
2063 |
return;
|
|
2064 |
|
|
2065 |
// Modify the property.
|
|
2066 |
const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange,
|
|
2067 |
quint32(newVisible)));
|
|
2068 |
newVisible = newVisibleVariant.toBool();
|
|
2069 |
if (visible == quint32(newVisible))
|
|
2070 |
return;
|
|
2071 |
visible = newVisible;
|
|
2072 |
|
|
2073 |
// Schedule redrawing
|
|
2074 |
if (update) {
|
|
2075 |
QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
|
|
2076 |
if (c)
|
|
2077 |
c->purge();
|
|
2078 |
if (scene) {
|
|
2079 |
scene->d_func()->markDirty(q_ptr, QRectF(),
|
|
2080 |
/*invalidateChildren=*/false,
|
|
2081 |
/*maybeDirtyClipPath=*/false,
|
|
2082 |
/*force=*/true);
|
|
2083 |
}
|
|
2084 |
}
|
|
2085 |
|
|
2086 |
// Certain properties are dropped as an item becomes invisible.
|
|
2087 |
if (!newVisible) {
|
|
2088 |
if (scene) {
|
|
2089 |
if (scene->d_func()->mouseGrabberItems.contains(q))
|
|
2090 |
q->ungrabMouse();
|
|
2091 |
if (scene->d_func()->keyboardGrabberItems.contains(q))
|
|
2092 |
q->ungrabKeyboard();
|
|
2093 |
if (q->isPanel() && panelModality != QGraphicsItem::NonModal)
|
|
2094 |
scene->d_func()->leaveModal(q_ptr);
|
|
2095 |
}
|
|
2096 |
if (q_ptr->hasFocus() && scene) {
|
|
2097 |
// Hiding the closest non-panel ancestor of the focus item
|
|
2098 |
QGraphicsItem *focusItem = scene->focusItem();
|
|
2099 |
bool clear = true;
|
|
2100 |
if (isWidget && !focusItem->isPanel()) {
|
|
2101 |
do {
|
|
2102 |
if (focusItem == q_ptr) {
|
|
2103 |
clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
|
|
2104 |
break;
|
|
2105 |
}
|
|
2106 |
} while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
|
|
2107 |
}
|
|
2108 |
if (clear)
|
|
2109 |
q_ptr->clearFocus();
|
|
2110 |
}
|
|
2111 |
if (q_ptr->isSelected())
|
|
2112 |
q_ptr->setSelected(false);
|
|
2113 |
} else {
|
|
2114 |
geometryChanged = 1;
|
|
2115 |
paintedViewBoundingRectsNeedRepaint = 1;
|
|
2116 |
if (scene) {
|
|
2117 |
if (isWidget) {
|
|
2118 |
QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(q_ptr);
|
|
2119 |
if (widget->windowType() == Qt::Popup)
|
|
2120 |
scene->d_func()->addPopup(widget);
|
|
2121 |
}
|
|
2122 |
if (q->isPanel() && panelModality != QGraphicsItem::NonModal) {
|
|
2123 |
scene->d_func()->enterModal(q_ptr);
|
|
2124 |
}
|
|
2125 |
}
|
|
2126 |
}
|
|
2127 |
|
|
2128 |
// Update children with explicitly = false.
|
|
2129 |
const bool updateChildren = update && !(flags & QGraphicsItem::ItemClipsChildrenToShape);
|
|
2130 |
foreach (QGraphicsItem *child, children) {
|
|
2131 |
if (!newVisible || !child->d_ptr->explicitlyHidden)
|
|
2132 |
child->d_ptr->setVisibleHelper(newVisible, false, updateChildren);
|
|
2133 |
}
|
|
2134 |
|
|
2135 |
// Update activation
|
|
2136 |
if (scene && q->isPanel()) {
|
|
2137 |
if (newVisible) {
|
|
2138 |
if (parent && parent->isActive())
|
|
2139 |
q->setActive(true);
|
|
2140 |
} else {
|
|
2141 |
if (q->isActive())
|
|
2142 |
scene->setActivePanel(parent);
|
|
2143 |
}
|
|
2144 |
}
|
|
2145 |
|
|
2146 |
// Enable subfocus
|
|
2147 |
if (newVisible) {
|
|
2148 |
QGraphicsItem *p = parent;
|
|
2149 |
bool done = false;
|
|
2150 |
while (p) {
|
|
2151 |
if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
|
|
2152 |
QGraphicsItem *fsi = p->d_ptr->focusScopeItem;
|
|
2153 |
if (q_ptr == fsi || q_ptr->isAncestorOf(fsi)) {
|
|
2154 |
done = true;
|
|
2155 |
while (fsi->d_ptr->focusScopeItem && fsi->d_ptr->focusScopeItem->isVisible())
|
|
2156 |
fsi = fsi->d_ptr->focusScopeItem;
|
|
2157 |
scene->setFocusItem(fsi);
|
|
2158 |
}
|
|
2159 |
break;
|
|
2160 |
}
|
|
2161 |
p = p->d_ptr->parent;
|
|
2162 |
}
|
|
2163 |
if (!done) {
|
|
2164 |
QGraphicsItem *fi = subFocusItem;
|
|
2165 |
if (fi && fi != scene->focusItem()) {
|
|
2166 |
scene->setFocusItem(fi);
|
|
2167 |
}
|
|
2168 |
}
|
|
2169 |
}
|
|
2170 |
|
|
2171 |
// Deliver post-change notification.
|
|
2172 |
q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, newVisibleVariant);
|
|
2173 |
|
|
2174 |
if (isObject)
|
|
2175 |
emit static_cast<QGraphicsObject *>(q_ptr)->visibleChanged();
|
|
2176 |
}
|
|
2177 |
|
|
2178 |
/*!
|
|
2179 |
If \a visible is true, the item is made visible. Otherwise, the item is
|
|
2180 |
made invisible. Invisible items are not painted, nor do they receive any
|
|
2181 |
events. In particular, mouse events pass right through invisible items,
|
|
2182 |
and are delivered to any item that may be behind. Invisible items are also
|
|
2183 |
unselectable, they cannot take input focus, and are not detected by
|
|
2184 |
QGraphicsScene's item location functions.
|
|
2185 |
|
|
2186 |
If an item becomes invisible while grabbing the mouse, (i.e., while it is
|
|
2187 |
receiving mouse events,) it will automatically lose the mouse grab, and
|
|
2188 |
the grab is not regained by making the item visible again; it must receive
|
|
2189 |
a new mouse press to regain the mouse grab.
|
|
2190 |
|
|
2191 |
Similarly, an invisible item cannot have focus, so if the item has focus
|
|
2192 |
when it becomes invisible, it will lose focus, and the focus is not
|
|
2193 |
regained by simply making the item visible again.
|
|
2194 |
|
|
2195 |
If you hide a parent item, all its children will also be hidden. If you
|
|
2196 |
show a parent item, all children will be shown, unless they have been
|
|
2197 |
explicitly hidden (i.e., if you call setVisible(false) on a child, it will
|
|
2198 |
not be reshown even if its parent is hidden, and then shown again).
|
|
2199 |
|
|
2200 |
Items are visible by default; it is unnecessary to call
|
|
2201 |
setVisible() on a new item.
|
|
2202 |
|
|
2203 |
\sa isVisible(), show(), hide()
|
|
2204 |
*/
|
|
2205 |
void QGraphicsItem::setVisible(bool visible)
|
|
2206 |
{
|
|
2207 |
d_ptr->setVisibleHelper(visible, /* explicit = */ true);
|
|
2208 |
}
|
|
2209 |
|
|
2210 |
/*!
|
|
2211 |
\fn void QGraphicsItem::hide()
|
|
2212 |
|
|
2213 |
Hides the item. (Items are visible by default.)
|
|
2214 |
|
|
2215 |
This convenience function is equivalent to calling \c setVisible(false).
|
|
2216 |
|
|
2217 |
\sa show(), setVisible()
|
|
2218 |
*/
|
|
2219 |
|
|
2220 |
/*!
|
|
2221 |
\fn void QGraphicsItem::show()
|
|
2222 |
|
|
2223 |
Shows the item. (Items are visible by default.)
|
|
2224 |
|
|
2225 |
This convenience function is equivalent to calling \c setVisible(true).
|
|
2226 |
|
|
2227 |
\sa hide(), setVisible()
|
|
2228 |
*/
|
|
2229 |
|
|
2230 |
/*!
|
|
2231 |
Returns true if the item is enabled; otherwise, false is returned.
|
|
2232 |
|
|
2233 |
\sa setEnabled()
|
|
2234 |
*/
|
|
2235 |
bool QGraphicsItem::isEnabled() const
|
|
2236 |
{
|
|
2237 |
return d_ptr->enabled;
|
|
2238 |
}
|
|
2239 |
|
|
2240 |
/*!
|
|
2241 |
\internal
|
|
2242 |
|
|
2243 |
Sets this item's visibility to \a newEnabled. If \a explicitly is true,
|
|
2244 |
this item will be "explicitly" \a newEnabled; otherwise, it.. will not be.
|
|
2245 |
*/
|
|
2246 |
void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bool update)
|
|
2247 |
{
|
|
2248 |
// Update explicit bit.
|
|
2249 |
if (explicitly)
|
|
2250 |
explicitlyDisabled = newEnabled ? 0 : 1;
|
|
2251 |
|
|
2252 |
// Check if there's nothing to do.
|
|
2253 |
if (enabled == quint32(newEnabled))
|
|
2254 |
return;
|
|
2255 |
|
|
2256 |
// Certain properties are dropped when an item is disabled.
|
|
2257 |
if (!newEnabled) {
|
|
2258 |
if (scene && scene->mouseGrabberItem() == q_ptr)
|
|
2259 |
q_ptr->ungrabMouse();
|
|
2260 |
if (q_ptr->hasFocus()) {
|
|
2261 |
// Disabling the closest non-panel ancestor of the focus item
|
|
2262 |
// causes focus to pop to the next item, otherwise it's cleared.
|
|
2263 |
QGraphicsItem *focusItem = scene->focusItem();
|
|
2264 |
bool clear = true;
|
|
2265 |
if (isWidget && !focusItem->isPanel() && q_ptr->isAncestorOf(focusItem)) {
|
|
2266 |
do {
|
|
2267 |
if (focusItem == q_ptr) {
|
|
2268 |
clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
|
|
2269 |
break;
|
|
2270 |
}
|
|
2271 |
} while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
|
|
2272 |
}
|
|
2273 |
if (clear)
|
|
2274 |
q_ptr->clearFocus();
|
|
2275 |
}
|
|
2276 |
if (q_ptr->isSelected())
|
|
2277 |
q_ptr->setSelected(false);
|
|
2278 |
}
|
|
2279 |
|
|
2280 |
// Modify the property.
|
|
2281 |
const QVariant newEnabledVariant(q_ptr->itemChange(QGraphicsItem::ItemEnabledChange,
|
|
2282 |
quint32(newEnabled)));
|
|
2283 |
enabled = newEnabledVariant.toBool();
|
|
2284 |
|
|
2285 |
// Schedule redraw.
|
|
2286 |
if (update)
|
|
2287 |
q_ptr->update();
|
|
2288 |
|
|
2289 |
foreach (QGraphicsItem *child, children) {
|
|
2290 |
if (!newEnabled || !child->d_ptr->explicitlyDisabled)
|
|
2291 |
child->d_ptr->setEnabledHelper(newEnabled, /* explicitly = */ false);
|
|
2292 |
}
|
|
2293 |
|
|
2294 |
// Deliver post-change notification.
|
|
2295 |
q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, newEnabledVariant);
|
|
2296 |
|
|
2297 |
if (isObject)
|
|
2298 |
emit static_cast<QGraphicsObject *>(q_ptr)->enabledChanged();
|
|
2299 |
}
|
|
2300 |
|
|
2301 |
/*!
|
|
2302 |
If \a enabled is true, the item is enabled; otherwise, it is disabled.
|
|
2303 |
|
|
2304 |
Disabled items are visible, but they do not receive any events, and cannot
|
|
2305 |
take focus nor be selected. Mouse events are discarded; they are not
|
|
2306 |
propagated unless the item is also invisible, or if it does not accept
|
|
2307 |
mouse events (see acceptedMouseButtons()). A disabled item cannot become the
|
|
2308 |
mouse grabber, and as a result of this, an item loses the grab if it
|
|
2309 |
becomes disabled when grabbing the mouse, just like it loses focus if it
|
|
2310 |
had focus when it was disabled.
|
|
2311 |
|
|
2312 |
Disabled items are traditionally drawn using grayed-out colors (see \l
|
|
2313 |
QPalette::Disabled).
|
|
2314 |
|
|
2315 |
If you disable a parent item, all its children will also be disabled. If
|
|
2316 |
you enable a parent item, all children will be enabled, unless they have
|
|
2317 |
been explicitly disabled (i.e., if you call setEnabled(false) on a child,
|
|
2318 |
it will not be reenabled if its parent is disabled, and then enabled
|
|
2319 |
again).
|
|
2320 |
|
|
2321 |
Items are enabled by default.
|
|
2322 |
|
|
2323 |
\note If you install an event filter, you can still intercept events
|
|
2324 |
before they are delivered to items; this mechanism disregards the item's
|
|
2325 |
enabled state.
|
|
2326 |
|
|
2327 |
\sa isEnabled()
|
|
2328 |
*/
|
|
2329 |
void QGraphicsItem::setEnabled(bool enabled)
|
|
2330 |
{
|
|
2331 |
d_ptr->setEnabledHelper(enabled, /* explicitly = */ true);
|
|
2332 |
}
|
|
2333 |
|
|
2334 |
/*!
|
|
2335 |
Returns true if this item is selected; otherwise, false is returned.
|
|
2336 |
|
|
2337 |
Items that are in a group inherit the group's selected state.
|
|
2338 |
|
|
2339 |
Items are not selected by default.
|
|
2340 |
|
|
2341 |
\sa setSelected(), QGraphicsScene::setSelectionArea()
|
|
2342 |
*/
|
|
2343 |
bool QGraphicsItem::isSelected() const
|
|
2344 |
{
|
|
2345 |
if (QGraphicsItemGroup *group = this->group())
|
|
2346 |
return group->isSelected();
|
|
2347 |
return d_ptr->selected;
|
|
2348 |
}
|
|
2349 |
|
|
2350 |
/*!
|
|
2351 |
If \a selected is true and this item is selectable, this item is selected;
|
|
2352 |
otherwise, it is unselected.
|
|
2353 |
|
|
2354 |
If the item is in a group, the whole group's selected state is toggled by
|
|
2355 |
this function. If the group is selected, all items in the group are also
|
|
2356 |
selected, and if the group is not selected, no item in the group is
|
|
2357 |
selected.
|
|
2358 |
|
|
2359 |
Only visible, enabled, selectable items can be selected. If \a selected
|
|
2360 |
is true and this item is either invisible or disabled or unselectable,
|
|
2361 |
this function does nothing.
|
|
2362 |
|
|
2363 |
By default, items cannot be selected. To enable selection, set the
|
|
2364 |
ItemIsSelectable flag.
|
|
2365 |
|
|
2366 |
This function is provided for convenience, allowing individual toggling of
|
|
2367 |
the selected state of an item. However, a more common way of selecting
|
|
2368 |
items is to call QGraphicsScene::setSelectionArea(), which will call this
|
|
2369 |
function for all visible, enabled, and selectable items within a specified
|
|
2370 |
area on the scene.
|
|
2371 |
|
|
2372 |
\sa isSelected(), QGraphicsScene::selectedItems()
|
|
2373 |
*/
|
|
2374 |
void QGraphicsItem::setSelected(bool selected)
|
|
2375 |
{
|
|
2376 |
if (QGraphicsItemGroup *group = this->group()) {
|
|
2377 |
group->setSelected(selected);
|
|
2378 |
return;
|
|
2379 |
}
|
|
2380 |
|
|
2381 |
if (!(d_ptr->flags & ItemIsSelectable) || !d_ptr->enabled || !d_ptr->visible)
|
|
2382 |
selected = false;
|
|
2383 |
if (d_ptr->selected == selected)
|
|
2384 |
return;
|
|
2385 |
const QVariant newSelectedVariant(itemChange(ItemSelectedChange, quint32(selected)));
|
|
2386 |
bool newSelected = newSelectedVariant.toBool();
|
|
2387 |
if (d_ptr->selected == newSelected)
|
|
2388 |
return;
|
|
2389 |
d_ptr->selected = newSelected;
|
|
2390 |
|
|
2391 |
update();
|
|
2392 |
if (d_ptr->scene) {
|
|
2393 |
QGraphicsScenePrivate *sceneD = d_ptr->scene->d_func();
|
|
2394 |
if (selected) {
|
|
2395 |
sceneD->selectedItems << this;
|
|
2396 |
} else {
|
|
2397 |
// QGraphicsScene::selectedItems() lazily pulls out all items that are
|
|
2398 |
// no longer selected.
|
|
2399 |
}
|
|
2400 |
if (!sceneD->selectionChanging)
|
|
2401 |
emit d_ptr->scene->selectionChanged();
|
|
2402 |
}
|
|
2403 |
|
|
2404 |
// Deliver post-change notification.
|
|
2405 |
itemChange(QGraphicsItem::ItemSelectedHasChanged, newSelectedVariant);
|
|
2406 |
}
|
|
2407 |
|
|
2408 |
/*!
|
|
2409 |
\since 4.5
|
|
2410 |
|
|
2411 |
Returns this item's local opacity, which is between 0.0 (transparent) and
|
|
2412 |
1.0 (opaque). This value is combined with parent and ancestor values into
|
|
2413 |
the effectiveOpacity(). The effective opacity decides how the item is
|
|
2414 |
rendered.
|
|
2415 |
|
|
2416 |
The opacity property decides the state of the painter passed to the
|
|
2417 |
paint() function. If the item is cached, i.e., ItemCoordinateCache or
|
|
2418 |
DeviceCoordinateCache, the effective property will be applied to the item's
|
|
2419 |
cache as it is rendered.
|
|
2420 |
|
|
2421 |
The default opacity is 1.0; fully opaque.
|
|
2422 |
|
|
2423 |
\sa setOpacity(), paint(), ItemIgnoresParentOpacity,
|
|
2424 |
ItemDoesntPropagateOpacityToChildren
|
|
2425 |
*/
|
|
2426 |
qreal QGraphicsItem::opacity() const
|
|
2427 |
{
|
|
2428 |
return d_ptr->opacity;
|
|
2429 |
}
|
|
2430 |
|
|
2431 |
/*!
|
|
2432 |
\since 4.5
|
|
2433 |
|
|
2434 |
Returns this item's \e effective opacity, which is between 0.0
|
|
2435 |
(transparent) and 1.0 (opaque). This value is a combination of this item's
|
|
2436 |
local opacity, and its parent and ancestors' opacities. The effective
|
|
2437 |
opacity decides how the item is rendered.
|
|
2438 |
|
|
2439 |
\sa opacity(), setOpacity(), paint(), ItemIgnoresParentOpacity,
|
|
2440 |
ItemDoesntPropagateOpacityToChildren
|
|
2441 |
*/
|
|
2442 |
qreal QGraphicsItem::effectiveOpacity() const
|
|
2443 |
{
|
|
2444 |
return d_ptr->effectiveOpacity();
|
|
2445 |
}
|
|
2446 |
|
|
2447 |
/*!
|
|
2448 |
\since 4.5
|
|
2449 |
|
|
2450 |
Sets this item's local \a opacity, between 0.0 (transparent) and 1.0
|
|
2451 |
(opaque). The item's local opacity is combined with parent and ancestor
|
|
2452 |
opacities into the effectiveOpacity().
|
|
2453 |
|
|
2454 |
By default, opacity propagates from parent to child, so if a parent's
|
|
2455 |
opacity is 0.5 and the child is also 0.5, the child's effective opacity
|
|
2456 |
will be 0.25.
|
|
2457 |
|
|
2458 |
The opacity property decides the state of the painter passed to the
|
|
2459 |
paint() function. If the item is cached, i.e., ItemCoordinateCache or
|
|
2460 |
DeviceCoordinateCache, the effective property will be applied to the
|
|
2461 |
item's cache as it is rendered.
|
|
2462 |
|
|
2463 |
There are two item flags that affect how the item's opacity is combined
|
|
2464 |
with the parent: ItemIgnoresParentOpacity and
|
|
2465 |
ItemDoesntPropagateOpacityToChildren.
|
|
2466 |
|
|
2467 |
\sa opacity(), effectiveOpacity()
|
|
2468 |
*/
|
|
2469 |
void QGraphicsItem::setOpacity(qreal opacity)
|
|
2470 |
{
|
|
2471 |
// Notify change.
|
|
2472 |
const QVariant newOpacityVariant(itemChange(ItemOpacityChange, opacity));
|
|
2473 |
|
|
2474 |
// Normalized opacity
|
|
2475 |
qreal newOpacity = qBound(qreal(0), newOpacityVariant.toReal(), qreal(1));
|
|
2476 |
|
|
2477 |
// No change? Done.
|
|
2478 |
if (newOpacity == d_ptr->opacity)
|
|
2479 |
return;
|
|
2480 |
|
|
2481 |
d_ptr->opacity = newOpacity;
|
|
2482 |
|
|
2483 |
// Notify change.
|
|
2484 |
itemChange(ItemOpacityHasChanged, newOpacityVariant);
|
|
2485 |
|
|
2486 |
// Update.
|
|
2487 |
if (d_ptr->scene) {
|
|
2488 |
d_ptr->invalidateGraphicsEffectsRecursively();
|
|
2489 |
d_ptr->scene->d_func()->markDirty(this, QRectF(),
|
|
2490 |
/*invalidateChildren=*/true,
|
|
2491 |
/*maybeDirtyClipPath=*/false,
|
|
2492 |
/*force=*/false,
|
|
2493 |
/*ignoreOpacity=*/true);
|
|
2494 |
}
|
|
2495 |
|
|
2496 |
if (d_ptr->isObject)
|
|
2497 |
emit static_cast<QGraphicsObject *>(this)->opacityChanged();
|
|
2498 |
}
|
|
2499 |
|
|
2500 |
/*!
|
|
2501 |
Returns a pointer to this item's effect if it has one; otherwise 0.
|
|
2502 |
|
|
2503 |
\since 4.6
|
|
2504 |
*/
|
|
2505 |
QGraphicsEffect *QGraphicsItem::graphicsEffect() const
|
|
2506 |
{
|
|
2507 |
return d_ptr->graphicsEffect;
|
|
2508 |
}
|
|
2509 |
|
|
2510 |
/*!
|
|
2511 |
Sets \a effect as the item's effect. If there already is an effect installed
|
|
2512 |
on this item, QGraphicsItem will delete the existing effect before installing
|
|
2513 |
the new \a effect.
|
|
2514 |
|
|
2515 |
If \a effect is the installed on a different item, setGraphicsEffect() will remove
|
|
2516 |
the effect from the item and install it on this item.
|
|
2517 |
|
|
2518 |
\note This function will apply the effect on itself and all its children.
|
|
2519 |
|
|
2520 |
\since 4.6
|
|
2521 |
*/
|
|
2522 |
void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
|
|
2523 |
{
|
|
2524 |
if (d_ptr->graphicsEffect == effect)
|
|
2525 |
return;
|
|
2526 |
|
|
2527 |
if (d_ptr->graphicsEffect && effect) {
|
|
2528 |
delete d_ptr->graphicsEffect;
|
|
2529 |
d_ptr->graphicsEffect = 0;
|
|
2530 |
}
|
|
2531 |
|
|
2532 |
if (!effect) {
|
|
2533 |
// Unset current effect.
|
|
2534 |
QGraphicsEffectPrivate *oldEffectPrivate = d_ptr->graphicsEffect->d_func();
|
|
2535 |
d_ptr->graphicsEffect = 0;
|
|
2536 |
if (oldEffectPrivate) {
|
|
2537 |
oldEffectPrivate->setGraphicsEffectSource(0); // deletes the current source.
|
|
2538 |
if (d_ptr->scene) // Update the views directly.
|
|
2539 |
d_ptr->scene->d_func()->markDirty(this, QRectF(), false, false, false, false, true);
|
|
2540 |
}
|
|
2541 |
} else {
|
|
2542 |
// Set new effect.
|
|
2543 |
QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this);
|
|
2544 |
QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
|
|
2545 |
d_ptr->graphicsEffect = effect;
|
|
2546 |
effect->d_func()->setGraphicsEffectSource(source);
|
|
2547 |
}
|
|
2548 |
|
|
2549 |
prepareGeometryChange();
|
|
2550 |
}
|
|
2551 |
|
|
2552 |
/*!
|
|
2553 |
\internal
|
|
2554 |
\since 4.6
|
|
2555 |
Returns the effective bounding rect of the item.
|
|
2556 |
If the item has no effect, this is the same as the item's bounding rect.
|
|
2557 |
If the item has an effect, the effective rect can be larger than the item's
|
|
2558 |
bouding rect, depending on the effect.
|
|
2559 |
|
|
2560 |
\sa boundingRect()
|
|
2561 |
*/
|
|
2562 |
QRectF QGraphicsItemPrivate::effectiveBoundingRect() const
|
|
2563 |
{
|
|
2564 |
QGraphicsEffect *effect = graphicsEffect;
|
|
2565 |
QRectF brect = effect && effect->isEnabled() ? effect->boundingRect() : q_ptr->boundingRect();
|
|
2566 |
if (ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
|
|
2567 |
return brect;
|
|
2568 |
|
|
2569 |
const QGraphicsItem *effectParent = parent;
|
|
2570 |
while (effectParent) {
|
|
2571 |
effect = effectParent->d_ptr->graphicsEffect;
|
|
2572 |
if (effect && effect->isEnabled())
|
|
2573 |
brect = effect->boundingRectFor(brect);
|
|
2574 |
if (effectParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
|
|
2575 |
return brect;
|
|
2576 |
effectParent = effectParent->d_ptr->parent;
|
|
2577 |
}
|
|
2578 |
|
|
2579 |
return brect;
|
|
2580 |
}
|
|
2581 |
|
|
2582 |
/*!
|
|
2583 |
\internal
|
|
2584 |
\since 4.6
|
|
2585 |
Returns the effective bounding rect of this item in scene coordinates,
|
|
2586 |
by combining sceneTransform() with boundingRect(), taking into account
|
|
2587 |
the effect that the item might have.
|
|
2588 |
|
|
2589 |
If the item has no effect, this is the same as sceneBoundingRect().
|
|
2590 |
|
|
2591 |
\sa effectiveBoundingRect(), sceneBoundingRect()
|
|
2592 |
*/
|
|
2593 |
QRectF QGraphicsItemPrivate::sceneEffectiveBoundingRect() const
|
|
2594 |
{
|
|
2595 |
// Find translate-only offset
|
|
2596 |
// COMBINE
|
|
2597 |
QPointF offset;
|
|
2598 |
const QGraphicsItem *parentItem = q_ptr;
|
|
2599 |
const QGraphicsItemPrivate *itemd;
|
|
2600 |
do {
|
|
2601 |
itemd = parentItem->d_ptr.data();
|
|
2602 |
if (itemd->transformData)
|
|
2603 |
break;
|
|
2604 |
offset += itemd->pos;
|
|
2605 |
} while ((parentItem = itemd->parent));
|
|
2606 |
|
|
2607 |
QRectF br = effectiveBoundingRect();
|
|
2608 |
br.translate(offset);
|
|
2609 |
return !parentItem ? br : parentItem->sceneTransform().mapRect(br);
|
|
2610 |
}
|
|
2611 |
|
|
2612 |
/*!
|
|
2613 |
Returns true if this item can accept drag and drop events; otherwise,
|
|
2614 |
returns false. By default, items do not accept drag and drop events; items
|
|
2615 |
are transparent to drag and drop.
|
|
2616 |
|
|
2617 |
\sa setAcceptDrops()
|
|
2618 |
*/
|
|
2619 |
bool QGraphicsItem::acceptDrops() const
|
|
2620 |
{
|
|
2621 |
return d_ptr->acceptDrops;
|
|
2622 |
}
|
|
2623 |
|
|
2624 |
/*!
|
|
2625 |
If \a on is true, this item will accept drag and drop events; otherwise,
|
|
2626 |
it is transparent for drag and drop events. By default, items do not
|
|
2627 |
accept drag and drop events.
|
|
2628 |
|
|
2629 |
\sa acceptDrops()
|
|
2630 |
*/
|
|
2631 |
void QGraphicsItem::setAcceptDrops(bool on)
|
|
2632 |
{
|
|
2633 |
d_ptr->acceptDrops = on;
|
|
2634 |
}
|
|
2635 |
|
|
2636 |
/*!
|
|
2637 |
Returns the mouse buttons that this item accepts mouse events for. By
|
|
2638 |
default, all mouse buttons are accepted.
|
|
2639 |
|
|
2640 |
If an item accepts a mouse button, it will become the mouse
|
|
2641 |
grabber item when a mouse press event is delivered for that mouse
|
|
2642 |
button. However, if the item does not accept the button,
|
|
2643 |
QGraphicsScene will forward the mouse events to the first item
|
|
2644 |
beneath it that does.
|
|
2645 |
|
|
2646 |
\sa setAcceptedMouseButtons(), mousePressEvent()
|
|
2647 |
*/
|
|
2648 |
Qt::MouseButtons QGraphicsItem::acceptedMouseButtons() const
|
|
2649 |
{
|
|
2650 |
return Qt::MouseButtons(d_ptr->acceptedMouseButtons);
|
|
2651 |
}
|
|
2652 |
|
|
2653 |
/*!
|
|
2654 |
Sets the mouse \a buttons that this item accepts mouse events for.
|
|
2655 |
|
|
2656 |
By default, all mouse buttons are accepted. If an item accepts a
|
|
2657 |
mouse button, it will become the mouse grabber item when a mouse
|
|
2658 |
press event is delivered for that button. However, if the item
|
|
2659 |
does not accept the mouse button, QGraphicsScene will forward the
|
|
2660 |
mouse events to the first item beneath it that does.
|
|
2661 |
|
|
2662 |
To disable mouse events for an item (i.e., make it transparent for mouse
|
|
2663 |
events), call setAcceptedMouseButtons(0).
|
|
2664 |
|
|
2665 |
\sa acceptedMouseButtons(), mousePressEvent()
|
|
2666 |
*/
|
|
2667 |
void QGraphicsItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
|
|
2668 |
{
|
|
2669 |
if (Qt::MouseButtons(d_ptr->acceptedMouseButtons) != buttons) {
|
|
2670 |
if (buttons == 0 && d_ptr->scene && d_ptr->scene->mouseGrabberItem() == this
|
|
2671 |
&& d_ptr->scene->d_func()->lastMouseGrabberItemHasImplicitMouseGrab) {
|
|
2672 |
ungrabMouse();
|
|
2673 |
}
|
|
2674 |
d_ptr->acceptedMouseButtons = quint32(buttons);
|
|
2675 |
}
|
|
2676 |
}
|
|
2677 |
|
|
2678 |
/*!
|
|
2679 |
\since 4.4
|
|
2680 |
|
|
2681 |
Returns true if an item accepts hover events
|
|
2682 |
(QGraphicsSceneHoverEvent); otherwise, returns false. By default,
|
|
2683 |
items do not accept hover events.
|
|
2684 |
|
|
2685 |
\sa setAcceptedMouseButtons()
|
|
2686 |
*/
|
|
2687 |
bool QGraphicsItem::acceptHoverEvents() const
|
|
2688 |
{
|
|
2689 |
return d_ptr->acceptsHover;
|
|
2690 |
}
|
|
2691 |
|
|
2692 |
/*!
|
|
2693 |
\obsolete
|
|
2694 |
|
|
2695 |
Call acceptHoverEvents() instead.
|
|
2696 |
*/
|
|
2697 |
bool QGraphicsItem::acceptsHoverEvents() const
|
|
2698 |
{
|
|
2699 |
return d_ptr->acceptsHover;
|
|
2700 |
}
|
|
2701 |
|
|
2702 |
/*!
|
|
2703 |
\since 4.4
|
|
2704 |
|
|
2705 |
If \a enabled is true, this item will accept hover events;
|
|
2706 |
otherwise, it will ignore them. By default, items do not accept
|
|
2707 |
hover events.
|
|
2708 |
|
|
2709 |
Hover events are delivered when there is no current mouse grabber
|
|
2710 |
item. They are sent when the mouse cursor enters an item, when it
|
|
2711 |
moves around inside the item, and when the cursor leaves an
|
|
2712 |
item. Hover events are commonly used to highlight an item when
|
|
2713 |
it's entered, and for tracking the mouse cursor as it hovers over
|
|
2714 |
the item (equivalent to QWidget::mouseTracking).
|
|
2715 |
|
|
2716 |
Parent items receive hover enter events before their children, and
|
|
2717 |
leave events after their children. The parent does not receive a
|
|
2718 |
hover leave event if the cursor enters a child, though; the parent
|
|
2719 |
stays "hovered" until the cursor leaves its area, including its
|
|
2720 |
children's areas.
|
|
2721 |
|
|
2722 |
If a parent item handles child events, it will receive hover move,
|
|
2723 |
drag move, and drop events as the cursor passes through its
|
|
2724 |
children, but it does not receive hover enter and hover leave, nor
|
|
2725 |
drag enter and drag leave events on behalf of its children.
|
|
2726 |
|
|
2727 |
A QGraphicsWidget with window decorations will accept hover events
|
|
2728 |
regardless of the value of acceptHoverEvents().
|
|
2729 |
|
|
2730 |
\sa acceptHoverEvents(), hoverEnterEvent(), hoverMoveEvent(),
|
|
2731 |
hoverLeaveEvent()
|
|
2732 |
*/
|
|
2733 |
void QGraphicsItem::setAcceptHoverEvents(bool enabled)
|
|
2734 |
{
|
|
2735 |
if (d_ptr->acceptsHover == quint32(enabled))
|
|
2736 |
return;
|
|
2737 |
d_ptr->acceptsHover = quint32(enabled);
|
|
2738 |
if (d_ptr->acceptsHover && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreHoverEvents) {
|
|
2739 |
d_ptr->scene->d_func()->allItemsIgnoreHoverEvents = false;
|
|
2740 |
d_ptr->scene->d_func()->enableMouseTrackingOnViews();
|
|
2741 |
}
|
|
2742 |
}
|
|
2743 |
|
|
2744 |
/*!
|
|
2745 |
\obsolete
|
|
2746 |
|
|
2747 |
Use setAcceptHoverEvents(\a enabled) instead.
|
|
2748 |
*/
|
|
2749 |
void QGraphicsItem::setAcceptsHoverEvents(bool enabled)
|
|
2750 |
{
|
|
2751 |
setAcceptHoverEvents(enabled);
|
|
2752 |
}
|
|
2753 |
|
|
2754 |
/*! \since 4.6
|
|
2755 |
|
|
2756 |
Returns true if an item accepts \l{QTouchEvent}{touch events};
|
|
2757 |
otherwise, returns false. By default, items do not accept touch events.
|
|
2758 |
|
|
2759 |
\sa setAcceptTouchEvents()
|
|
2760 |
*/
|
|
2761 |
bool QGraphicsItem::acceptTouchEvents() const
|
|
2762 |
{
|
|
2763 |
return d_ptr->acceptTouchEvents;
|
|
2764 |
}
|
|
2765 |
|
|
2766 |
/*!
|
|
2767 |
\since 4.6
|
|
2768 |
|
|
2769 |
If \a enabled is true, this item will accept \l{QTouchEvent}{touch events};
|
|
2770 |
otherwise, it will ignore them. By default, items do not accept
|
|
2771 |
touch events.
|
|
2772 |
*/
|
|
2773 |
void QGraphicsItem::setAcceptTouchEvents(bool enabled)
|
|
2774 |
{
|
|
2775 |
if (d_ptr->acceptTouchEvents == quint32(enabled))
|
|
2776 |
return;
|
|
2777 |
d_ptr->acceptTouchEvents = quint32(enabled);
|
|
2778 |
if (d_ptr->acceptTouchEvents && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreTouchEvents) {
|
|
2779 |
d_ptr->scene->d_func()->allItemsIgnoreTouchEvents = false;
|
|
2780 |
d_ptr->scene->d_func()->enableTouchEventsOnViews();
|
|
2781 |
}
|
|
2782 |
}
|
|
2783 |
|
|
2784 |
/*!
|
|
2785 |
\since 4.6
|
|
2786 |
|
|
2787 |
Returns true if this item filters child events (i.e., all events
|
|
2788 |
intended for any of its children are instead sent to this item);
|
|
2789 |
otherwise, false is returned.
|
|
2790 |
|
|
2791 |
The default value is false; child events are not filtered.
|
|
2792 |
|
|
2793 |
\sa setFiltersChildEvents()
|
|
2794 |
*/
|
|
2795 |
bool QGraphicsItem::filtersChildEvents() const
|
|
2796 |
{
|
|
2797 |
return d_ptr->filtersDescendantEvents;
|
|
2798 |
}
|
|
2799 |
|
|
2800 |
/*!
|
|
2801 |
\since 4.6
|
|
2802 |
|
|
2803 |
If \a enabled is true, this item is set to filter all events for
|
|
2804 |
all its children (i.e., all events intented for any of its
|
|
2805 |
children are instead sent to this item); otherwise, if \a enabled
|
|
2806 |
is false, this item will only handle its own events. The default
|
|
2807 |
value is false.
|
|
2808 |
|
|
2809 |
\sa filtersChildEvents()
|
|
2810 |
*/
|
|
2811 |
void QGraphicsItem::setFiltersChildEvents(bool enabled)
|
|
2812 |
{
|
|
2813 |
if (d_ptr->filtersDescendantEvents == enabled)
|
|
2814 |
return;
|
|
2815 |
|
|
2816 |
d_ptr->filtersDescendantEvents = enabled;
|
|
2817 |
d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2));
|
|
2818 |
}
|
|
2819 |
|
|
2820 |
/*!
|
|
2821 |
\obsolete
|
|
2822 |
|
|
2823 |
Returns true if this item handles child events (i.e., all events
|
|
2824 |
intended for any of its children are instead sent to this item);
|
|
2825 |
otherwise, false is returned.
|
|
2826 |
|
|
2827 |
This property is useful for item groups; it allows one item to
|
|
2828 |
handle events on behalf of its children, as opposed to its
|
|
2829 |
children handling their events individually.
|
|
2830 |
|
|
2831 |
The default is to return false; children handle their own events.
|
|
2832 |
The exception for this is if the item is a QGraphicsItemGroup, then
|
|
2833 |
it defaults to return true.
|
|
2834 |
|
|
2835 |
\sa setHandlesChildEvents()
|
|
2836 |
*/
|
|
2837 |
bool QGraphicsItem::handlesChildEvents() const
|
|
2838 |
{
|
|
2839 |
return d_ptr->handlesChildEvents;
|
|
2840 |
}
|
|
2841 |
|
|
2842 |
/*!
|
|
2843 |
\obsolete
|
|
2844 |
|
|
2845 |
If \a enabled is true, this item is set to handle all events for
|
|
2846 |
all its children (i.e., all events intented for any of its
|
|
2847 |
children are instead sent to this item); otherwise, if \a enabled
|
|
2848 |
is false, this item will only handle its own events. The default
|
|
2849 |
value is false.
|
|
2850 |
|
|
2851 |
This property is useful for item groups; it allows one item to
|
|
2852 |
handle events on behalf of its children, as opposed to its
|
|
2853 |
children handling their events individually.
|
|
2854 |
|
|
2855 |
If a child item accepts hover events, its parent will receive
|
|
2856 |
hover move events as the cursor passes through the child, but it
|
|
2857 |
does not receive hover enter and hover leave events on behalf of
|
|
2858 |
its child.
|
|
2859 |
|
|
2860 |
\sa handlesChildEvents()
|
|
2861 |
*/
|
|
2862 |
void QGraphicsItem::setHandlesChildEvents(bool enabled)
|
|
2863 |
{
|
|
2864 |
if (d_ptr->handlesChildEvents == enabled)
|
|
2865 |
return;
|
|
2866 |
|
|
2867 |
d_ptr->handlesChildEvents = enabled;
|
|
2868 |
d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1));
|
|
2869 |
}
|
|
2870 |
/*!
|
|
2871 |
\since 4.6
|
|
2872 |
Returns true if this item is active; otherwise returns false.
|
|
2873 |
|
|
2874 |
An item can only be active if the scene is active. An item is active
|
|
2875 |
if it is, or is a descendent of, an active panel. Items in non-active
|
|
2876 |
panels are not active.
|
|
2877 |
|
|
2878 |
Items that are not part of a panel follow scene activation when the
|
|
2879 |
scene has no active panel.
|
|
2880 |
|
|
2881 |
Only active items can gain input focus.
|
|
2882 |
|
|
2883 |
\sa QGraphicsScene::isActive(), QGraphicsScene::activePanel(), panel(), isPanel()
|
|
2884 |
*/
|
|
2885 |
bool QGraphicsItem::isActive() const
|
|
2886 |
{
|
|
2887 |
if (!d_ptr->scene || !d_ptr->scene->isActive())
|
|
2888 |
return false;
|
|
2889 |
return panel() == d_ptr->scene->activePanel();
|
|
2890 |
}
|
|
2891 |
|
|
2892 |
/*!
|
|
2893 |
\since 4.6
|
|
2894 |
|
|
2895 |
If \a active is true, and the scene is active, this item's panel will be
|
|
2896 |
activated. Otherwise, the panel is deactivated.
|
|
2897 |
|
|
2898 |
If the item is not part of an active scene, \a active will decide what
|
|
2899 |
happens to the panel when the scene becomes active or the item is added to
|
|
2900 |
the scene. If true, the item's panel will be activated when the item is
|
|
2901 |
either added to the scene or the scene is activated. Otherwise, the item
|
|
2902 |
will stay inactive independent of the scene's activated state.
|
|
2903 |
|
|
2904 |
\sa isPanel(), QGraphicsScene::setActivePanel(), QGraphicsScene::isActive()
|
|
2905 |
*/
|
|
2906 |
void QGraphicsItem::setActive(bool active)
|
|
2907 |
{
|
|
2908 |
d_ptr->explicitActivate = 1;
|
|
2909 |
d_ptr->wantsActive = active;
|
|
2910 |
if (d_ptr->scene) {
|
|
2911 |
if (active) {
|
|
2912 |
// Activate this item.
|
|
2913 |
d_ptr->scene->setActivePanel(this);
|
|
2914 |
} else {
|
|
2915 |
// Deactivate this item, and reactivate the last active item
|
|
2916 |
// (if any).
|
|
2917 |
QGraphicsItem *lastActive = d_ptr->scene->d_func()->lastActivePanel;
|
|
2918 |
d_ptr->scene->setActivePanel(lastActive != this ? lastActive : 0);
|
|
2919 |
}
|
|
2920 |
}
|
|
2921 |
}
|
|
2922 |
|
|
2923 |
/*!
|
|
2924 |
Returns true if this item is active, and it or its \l{focusProxy()}{focus
|
|
2925 |
proxy} has keyboard input focus; otherwise, returns false.
|
|
2926 |
|
|
2927 |
\sa focusItem(), setFocus(), QGraphicsScene::setFocusItem(), isActive()
|
|
2928 |
*/
|
|
2929 |
bool QGraphicsItem::hasFocus() const
|
|
2930 |
{
|
|
2931 |
if (d_ptr->focusProxy)
|
|
2932 |
return d_ptr->focusProxy->hasFocus();
|
|
2933 |
return (d_ptr->scene && d_ptr->scene->focusItem() == this);
|
|
2934 |
}
|
|
2935 |
|
|
2936 |
/*!
|
|
2937 |
Gives keyboard input focus to this item. The \a focusReason argument will
|
|
2938 |
be passed into any \l{QFocusEvent}{focus event} generated by this function;
|
|
2939 |
it is used to give an explanation of what caused the item to get focus.
|
|
2940 |
|
|
2941 |
Only enabled items that set the ItemIsFocusable flag can accept keyboard
|
|
2942 |
focus.
|
|
2943 |
|
|
2944 |
If this item is not visible, not active, or not associated with a scene,
|
|
2945 |
it will not gain immediate input focus. However, it will be registered as
|
|
2946 |
the preferred focus item for its subtree of items, should it later become
|
|
2947 |
visible.
|
|
2948 |
|
|
2949 |
As a result of calling this function, this item will receive a
|
|
2950 |
\l{focusInEvent()}{focus in event} with \a focusReason. If another item
|
|
2951 |
already has focus, that item will first receive a \l{focusOutEvent()}
|
|
2952 |
{focus out event} indicating that it has lost input focus.
|
|
2953 |
|
|
2954 |
\sa clearFocus(), hasFocus(), focusItem(), focusProxy()
|
|
2955 |
*/
|
|
2956 |
void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
|
|
2957 |
{
|
|
2958 |
d_ptr->setFocusHelper(focusReason, /* climb = */ true);
|
|
2959 |
}
|
|
2960 |
|
|
2961 |
/*!
|
|
2962 |
\internal
|
|
2963 |
*/
|
|
2964 |
void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool climb)
|
|
2965 |
{
|
|
2966 |
// Disabled / unfocusable items cannot accept focus.
|
|
2967 |
if (!q_ptr->isEnabled() || !(flags & QGraphicsItem::ItemIsFocusable))
|
|
2968 |
return;
|
|
2969 |
|
|
2970 |
// Find focus proxy.
|
|
2971 |
QGraphicsItem *f = q_ptr;
|
|
2972 |
while (f->d_ptr->focusProxy)
|
|
2973 |
f = f->d_ptr->focusProxy;
|
|
2974 |
|
|
2975 |
// Return if it already has focus.
|
|
2976 |
if (scene && scene->focusItem() == f)
|
|
2977 |
return;
|
|
2978 |
|
|
2979 |
// Update focus scope item ptr.
|
|
2980 |
QGraphicsItem *p = parent;
|
|
2981 |
while (p) {
|
|
2982 |
if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
|
|
2983 |
p->d_ptr->focusScopeItem = q_ptr;
|
|
2984 |
if (!q_ptr->isActive() || !p->focusItem())
|
|
2985 |
return;
|
|
2986 |
break;
|
|
2987 |
}
|
|
2988 |
p = p->d_ptr->parent;
|
|
2989 |
}
|
|
2990 |
|
|
2991 |
if (climb) {
|
|
2992 |
while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible())
|
|
2993 |
f = f->d_ptr->focusScopeItem;
|
|
2994 |
}
|
|
2995 |
|
|
2996 |
// Update the child focus chain.
|
|
2997 |
f->d_ptr->setSubFocus();
|
|
2998 |
|
|
2999 |
// Update the scene's focus item.
|
|
3000 |
if (scene) {
|
|
3001 |
QGraphicsItem *p = q_ptr->panel();
|
|
3002 |
if ((!p && scene->isActive()) || (p && p->isActive())) {
|
|
3003 |
// Visible items immediately gain focus from scene.
|
|
3004 |
scene->d_func()->setFocusItemHelper(f, focusReason);
|
|
3005 |
}
|
|
3006 |
}
|
|
3007 |
}
|
|
3008 |
|
|
3009 |
/*!
|
|
3010 |
Takes keyboard input focus from the item.
|
|
3011 |
|
|
3012 |
If it has focus, a \l{focusOutEvent()}{focus out event} is sent to this
|
|
3013 |
item to tell it that it is about to lose the focus.
|
|
3014 |
|
|
3015 |
Only items that set the ItemIsFocusable flag, or widgets that set an
|
|
3016 |
appropriate focus policy, can accept keyboard focus.
|
|
3017 |
|
|
3018 |
\sa setFocus(), hasFocus(), QGraphicsWidget::focusPolicy
|
|
3019 |
*/
|
|
3020 |
void QGraphicsItem::clearFocus()
|
|
3021 |
{
|
|
3022 |
// Pass focus to the closest parent focus scope.
|
|
3023 |
if (!d_ptr->inDestructor) {
|
|
3024 |
QGraphicsItem *p = d_ptr->parent;
|
|
3025 |
while (p) {
|
|
3026 |
if (p->flags() & ItemIsFocusScope) {
|
|
3027 |
p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false);
|
|
3028 |
return;
|
|
3029 |
}
|
|
3030 |
p = p->d_ptr->parent;
|
|
3031 |
}
|
|
3032 |
}
|
|
3033 |
|
|
3034 |
// Invisible items with focus must explicitly clear subfocus.
|
|
3035 |
d_ptr->clearSubFocus(this);
|
|
3036 |
|
|
3037 |
if (hasFocus()) {
|
|
3038 |
// If this item has the scene's input focus, clear it.
|
|
3039 |
d_ptr->scene->setFocusItem(0);
|
|
3040 |
}
|
|
3041 |
}
|
|
3042 |
|
|
3043 |
/*!
|
|
3044 |
\since 4.6
|
|
3045 |
|
|
3046 |
Returns this item's focus proxy, or 0 if this item has no
|
|
3047 |
focus proxy.
|
|
3048 |
|
|
3049 |
\sa setFocusProxy(), setFocus(), hasFocus()
|
|
3050 |
*/
|
|
3051 |
QGraphicsItem *QGraphicsItem::focusProxy() const
|
|
3052 |
{
|
|
3053 |
return d_ptr->focusProxy;
|
|
3054 |
}
|
|
3055 |
|
|
3056 |
/*!
|
|
3057 |
\since 4.6
|
|
3058 |
|
|
3059 |
Sets the item's focus proxy to \a item.
|
|
3060 |
|
|
3061 |
If an item has a focus proxy, the focus proxy will receive
|
|
3062 |
input focus when the item gains input focus. The item itself
|
|
3063 |
will still have focus (i.e., hasFocus() will return true),
|
|
3064 |
but only the focus proxy will receive the keyboard input.
|
|
3065 |
|
|
3066 |
A focus proxy can itself have a focus proxy, and so on. In
|
|
3067 |
such case, keyboard input will be handled by the outermost
|
|
3068 |
focus proxy.
|
|
3069 |
|
|
3070 |
The focus proxy \a item must belong to the same scene as
|
|
3071 |
this item.
|
|
3072 |
|
|
3073 |
\sa focusProxy(), setFocus(), hasFocus()
|
|
3074 |
*/
|
|
3075 |
void QGraphicsItem::setFocusProxy(QGraphicsItem *item)
|
|
3076 |
{
|
|
3077 |
if (item == d_ptr->focusProxy)
|
|
3078 |
return;
|
|
3079 |
if (item == this) {
|
|
3080 |
qWarning("QGraphicsItem::setFocusProxy: cannot assign self as focus proxy");
|
|
3081 |
return;
|
|
3082 |
}
|
|
3083 |
if (item) {
|
|
3084 |
if (item->d_ptr->scene != d_ptr->scene) {
|
|
3085 |
qWarning("QGraphicsItem::setFocusProxy: focus proxy must be in same scene");
|
|
3086 |
return;
|
|
3087 |
}
|
|
3088 |
for (QGraphicsItem *f = item->focusProxy(); f != 0; f = f->focusProxy()) {
|
|
3089 |
if (f == this) {
|
|
3090 |
qWarning("QGraphicsItem::setFocusProxy: %p is already in the focus proxy chain", item);
|
|
3091 |
return;
|
|
3092 |
}
|
|
3093 |
}
|
|
3094 |
}
|
|
3095 |
|
|
3096 |
QGraphicsItem *lastFocusProxy = d_ptr->focusProxy;
|
|
3097 |
if (lastFocusProxy)
|
|
3098 |
lastFocusProxy->d_ptr->focusProxyRefs.removeOne(&d_ptr->focusProxy);
|
|
3099 |
d_ptr->focusProxy = item;
|
|
3100 |
if (item)
|
|
3101 |
item->d_ptr->focusProxyRefs << &d_ptr->focusProxy;
|
|
3102 |
}
|
|
3103 |
|
|
3104 |
/*!
|
|
3105 |
\since 4.6
|
|
3106 |
|
|
3107 |
If this item, a child or descendant of this item currently has input
|
|
3108 |
focus, this function will return a pointer to that item. If
|
|
3109 |
no descendant has input focus, 0 is returned.
|
|
3110 |
|
|
3111 |
\sa hasFocus(), setFocus(), QWidget::focusWidget()
|
|
3112 |
*/
|
|
3113 |
QGraphicsItem *QGraphicsItem::focusItem() const
|
|
3114 |
{
|
|
3115 |
return d_ptr->subFocusItem;
|
|
3116 |
}
|
|
3117 |
|
|
3118 |
/*!
|
|
3119 |
\internal
|
|
3120 |
|
|
3121 |
Returns this item's focus scope item.
|
|
3122 |
*/
|
|
3123 |
QGraphicsItem *QGraphicsItem::focusScopeItem() const
|
|
3124 |
{
|
|
3125 |
return d_ptr->focusScopeItem;
|
|
3126 |
}
|
|
3127 |
|
|
3128 |
/*!
|
|
3129 |
\since 4.4
|
|
3130 |
Grabs the mouse input.
|
|
3131 |
|
|
3132 |
This item will receive all mouse events for the scene until any of the
|
|
3133 |
following events occurs:
|
|
3134 |
|
|
3135 |
\list
|
|
3136 |
\o The item becomes invisible
|
|
3137 |
\o The item is removed from the scene
|
|
3138 |
\o The item is deleted
|
|
3139 |
\o The item call ungrabMouse()
|
|
3140 |
\o Another item calls grabMouse(); the item will regain the mouse grab
|
|
3141 |
when the other item calls ungrabMouse().
|
|
3142 |
\endlist
|
|
3143 |
|
|
3144 |
When an item gains the mouse grab, it receives a QEvent::GrabMouse
|
|
3145 |
event. When it loses the mouse grab, it receives a QEvent::UngrabMouse
|
|
3146 |
event. These events can be used to detect when your item gains or loses
|
|
3147 |
the mouse grab through other means than receiving mouse button events.
|
|
3148 |
|
|
3149 |
It is almost never necessary to explicitly grab the mouse in Qt, as Qt
|
|
3150 |
grabs and releases it sensibly. In particular, Qt grabs the mouse when you
|
|
3151 |
press a mouse button, and keeps the mouse grabbed until you release the
|
|
3152 |
last mouse button. Also, Qt::Popup widgets implicitly call grabMouse()
|
|
3153 |
when shown, and ungrabMouse() when hidden.
|
|
3154 |
|
|
3155 |
Note that only visible items can grab mouse input. Calling grabMouse() on
|
|
3156 |
an invisible item has no effect.
|
|
3157 |
|
|
3158 |
Keyboard events are not affected.
|
|
3159 |
|
|
3160 |
\sa QGraphicsScene::mouseGrabberItem(), ungrabMouse(), grabKeyboard()
|
|
3161 |
*/
|
|
3162 |
void QGraphicsItem::grabMouse()
|
|
3163 |
{
|
|
3164 |
if (!d_ptr->scene) {
|
|
3165 |
qWarning("QGraphicsItem::grabMouse: cannot grab mouse without scene");
|
|
3166 |
return;
|
|
3167 |
}
|
|
3168 |
if (!d_ptr->visible) {
|
|
3169 |
qWarning("QGraphicsItem::grabMouse: cannot grab mouse while invisible");
|
|
3170 |
return;
|
|
3171 |
}
|
|
3172 |
d_ptr->scene->d_func()->grabMouse(this);
|
|
3173 |
}
|
|
3174 |
|
|
3175 |
/*!
|
|
3176 |
\since 4.4
|
|
3177 |
Releases the mouse grab.
|
|
3178 |
|
|
3179 |
\sa grabMouse(), ungrabKeyboard()
|
|
3180 |
*/
|
|
3181 |
void QGraphicsItem::ungrabMouse()
|
|
3182 |
{
|
|
3183 |
if (!d_ptr->scene) {
|
|
3184 |
qWarning("QGraphicsItem::ungrabMouse: cannot ungrab mouse without scene");
|
|
3185 |
return;
|
|
3186 |
}
|
|
3187 |
d_ptr->scene->d_func()->ungrabMouse(this);
|
|
3188 |
}
|
|
3189 |
|
|
3190 |
/*!
|
|
3191 |
\since 4.4
|
|
3192 |
Grabs the keyboard input.
|
|
3193 |
|
|
3194 |
The item will receive all keyboard input to the scene until one of the
|
|
3195 |
following events occur:
|
|
3196 |
|
|
3197 |
\list
|
|
3198 |
\o The item becomes invisible
|
|
3199 |
\o The item is removed from the scene
|
|
3200 |
\o The item is deleted
|
|
3201 |
\o The item calls ungrabKeyboard()
|
|
3202 |
\o Another item calls grabKeyboard(); the item will regain the keyboard grab
|
|
3203 |
when the other item calls ungrabKeyboard().
|
|
3204 |
\endlist
|
|
3205 |
|
|
3206 |
When an item gains the keyboard grab, it receives a QEvent::GrabKeyboard
|
|
3207 |
event. When it loses the keyboard grab, it receives a
|
|
3208 |
QEvent::UngrabKeyboard event. These events can be used to detect when your
|
|
3209 |
item gains or loses the keyboard grab through other means than gaining
|
|
3210 |
input focus.
|
|
3211 |
|
|
3212 |
It is almost never necessary to explicitly grab the keyboard in Qt, as Qt
|
|
3213 |
grabs and releases it sensibly. In particular, Qt grabs the keyboard when
|
|
3214 |
your item gains input focus, and releases it when your item loses input
|
|
3215 |
focus, or when the item is hidden.
|
|
3216 |
|
|
3217 |
Note that only visible items can grab keyboard input. Calling
|
|
3218 |
grabKeyboard() on an invisible item has no effect.
|
|
3219 |
|
|
3220 |
Keyboard events are not affected.
|
|
3221 |
|
|
3222 |
\sa ungrabKeyboard(), grabMouse(), setFocus()
|
|
3223 |
*/
|
|
3224 |
void QGraphicsItem::grabKeyboard()
|
|
3225 |
{
|
|
3226 |
if (!d_ptr->scene) {
|
|
3227 |
qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard without scene");
|
|
3228 |
return;
|
|
3229 |
}
|
|
3230 |
if (!d_ptr->visible) {
|
|
3231 |
qWarning("QGraphicsItem::grabKeyboard: cannot grab keyboard while invisible");
|
|
3232 |
return;
|
|
3233 |
}
|
|
3234 |
d_ptr->scene->d_func()->grabKeyboard(this);
|
|
3235 |
}
|
|
3236 |
|
|
3237 |
/*!
|
|
3238 |
\since 4.4
|
|
3239 |
Releases the keyboard grab.
|
|
3240 |
|
|
3241 |
\sa grabKeyboard(), ungrabMouse()
|
|
3242 |
*/
|
|
3243 |
void QGraphicsItem::ungrabKeyboard()
|
|
3244 |
{
|
|
3245 |
if (!d_ptr->scene) {
|
|
3246 |
qWarning("QGraphicsItem::ungrabKeyboard: cannot ungrab keyboard without scene");
|
|
3247 |
return;
|
|
3248 |
}
|
|
3249 |
d_ptr->scene->d_func()->ungrabKeyboard(this);
|
|
3250 |
}
|
|
3251 |
|
|
3252 |
/*!
|
|
3253 |
Returns the position of the item in parent coordinates. If the item has no
|
|
3254 |
parent, its position is given in scene coordinates.
|
|
3255 |
|
|
3256 |
The position of the item describes its origin (local coordinate
|
|
3257 |
(0, 0)) in parent coordinates; this function returns the same as
|
|
3258 |
mapToParent(0, 0).
|
|
3259 |
|
|
3260 |
For convenience, you can also call scenePos() to determine the
|
|
3261 |
item's position in scene coordinates, regardless of its parent.
|
|
3262 |
|
|
3263 |
\sa x(), y(), setPos(), transform(), {The Graphics View Coordinate System}
|
|
3264 |
*/
|
|
3265 |
QPointF QGraphicsItem::pos() const
|
|
3266 |
{
|
|
3267 |
return d_ptr->pos;
|
|
3268 |
}
|
|
3269 |
|
|
3270 |
/*!
|
|
3271 |
\fn QGraphicsItem::x() const
|
|
3272 |
|
|
3273 |
This convenience function is equivalent to calling pos().x().
|
|
3274 |
|
|
3275 |
\sa y()
|
|
3276 |
*/
|
|
3277 |
|
|
3278 |
/*!
|
|
3279 |
\since 4.6
|
|
3280 |
|
|
3281 |
Set's the \a x coordinate of the item's position. Equivalent to
|
|
3282 |
calling setPos(x, y()).
|
|
3283 |
|
|
3284 |
\sa x(), setPos()
|
|
3285 |
*/
|
|
3286 |
void QGraphicsItem::setX(qreal x)
|
|
3287 |
{
|
|
3288 |
d_ptr->setPosHelper(QPointF(x, d_ptr->pos.y()));
|
|
3289 |
}
|
|
3290 |
|
|
3291 |
/*!
|
|
3292 |
\fn QGraphicsItem::y() const
|
|
3293 |
|
|
3294 |
This convenience function is equivalent to calling pos().y().
|
|
3295 |
|
|
3296 |
\sa x()
|
|
3297 |
*/
|
|
3298 |
|
|
3299 |
/*!
|
|
3300 |
\since 4.6
|
|
3301 |
|
|
3302 |
Set's the \a y coordinate of the item's position. Equivalent to
|
|
3303 |
calling setPos(x(), y).
|
|
3304 |
|
|
3305 |
\sa x(), setPos()
|
|
3306 |
*/
|
|
3307 |
void QGraphicsItem::setY(qreal y)
|
|
3308 |
{
|
|
3309 |
d_ptr->setPosHelper(QPointF(d_ptr->pos.x(), y));
|
|
3310 |
}
|
|
3311 |
|
|
3312 |
/*!
|
|
3313 |
Returns the item's position in scene coordinates. This is
|
|
3314 |
equivalent to calling \c mapToScene(0, 0).
|
|
3315 |
|
|
3316 |
\sa pos(), sceneTransform(), {The Graphics View Coordinate System}
|
|
3317 |
*/
|
|
3318 |
QPointF QGraphicsItem::scenePos() const
|
|
3319 |
{
|
|
3320 |
return mapToScene(0, 0);
|
|
3321 |
}
|
|
3322 |
|
|
3323 |
/*!
|
|
3324 |
\internal
|
|
3325 |
|
|
3326 |
Sets the position \a pos.
|
|
3327 |
*/
|
|
3328 |
void QGraphicsItemPrivate::setPosHelper(const QPointF &pos)
|
|
3329 |
{
|
|
3330 |
Q_Q(QGraphicsItem);
|
|
3331 |
inSetPosHelper = 1;
|
|
3332 |
updateCachedClipPathFromSetPosHelper(pos);
|
|
3333 |
if (scene)
|
|
3334 |
q->prepareGeometryChange();
|
|
3335 |
QPointF oldPos = this->pos;
|
|
3336 |
this->pos = pos;
|
|
3337 |
dirtySceneTransform = 1;
|
|
3338 |
inSetPosHelper = 0;
|
|
3339 |
if (isObject) {
|
|
3340 |
if (pos.x() != oldPos.x())
|
|
3341 |
emit static_cast<QGraphicsObject *>(q_ptr)->xChanged();
|
|
3342 |
if (pos.y() != oldPos.y())
|
|
3343 |
emit static_cast<QGraphicsObject *>(q_ptr)->yChanged();
|
|
3344 |
}
|
|
3345 |
}
|
|
3346 |
|
|
3347 |
/*!
|
|
3348 |
\internal
|
|
3349 |
|
|
3350 |
Sets the transform \a transform.
|
|
3351 |
*/
|
|
3352 |
void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
|
|
3353 |
{
|
|
3354 |
q_ptr->prepareGeometryChange();
|
|
3355 |
transformData->transform = transform;
|
|
3356 |
dirtySceneTransform = 1;
|
|
3357 |
}
|
|
3358 |
|
|
3359 |
/*!
|
|
3360 |
Sets the position of the item to \a pos, which is in parent
|
|
3361 |
coordinates. For items with no parent, \a pos is in scene
|
|
3362 |
coordinates.
|
|
3363 |
|
|
3364 |
The position of the item describes its origin (local coordinate
|
|
3365 |
(0, 0)) in parent coordinates.
|
|
3366 |
|
|
3367 |
\sa pos(), scenePos(), {The Graphics View Coordinate System}
|
|
3368 |
*/
|
|
3369 |
void QGraphicsItem::setPos(const QPointF &pos)
|
|
3370 |
{
|
|
3371 |
if (d_ptr->pos == pos)
|
|
3372 |
return;
|
|
3373 |
|
|
3374 |
// Update and repositition.
|
|
3375 |
if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
|
|
3376 |
d_ptr->setPosHelper(pos);
|
|
3377 |
return;
|
|
3378 |
}
|
|
3379 |
|
|
3380 |
// Notify the item that the position is changing.
|
|
3381 |
const QVariant newPosVariant(itemChange(ItemPositionChange, qVariantFromValue<QPointF>(pos)));
|
|
3382 |
QPointF newPos = newPosVariant.toPointF();
|
|
3383 |
if (newPos == d_ptr->pos)
|
|
3384 |
return;
|
|
3385 |
|
|
3386 |
// Update and repositition.
|
|
3387 |
d_ptr->setPosHelper(newPos);
|
|
3388 |
|
|
3389 |
// Send post-notification.
|
|
3390 |
itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant);
|
|
3391 |
}
|
|
3392 |
|
|
3393 |
/*!
|
|
3394 |
\fn void QGraphicsItem::setPos(qreal x, qreal y)
|
|
3395 |
\overload
|
|
3396 |
|
|
3397 |
This convenience function is equivalent to calling setPos(QPointF(\a x, \a
|
|
3398 |
y)).
|
|
3399 |
*/
|
|
3400 |
|
|
3401 |
/*!
|
|
3402 |
\fn void QGraphicsItem::moveBy(qreal dx, qreal dy)
|
|
3403 |
|
|
3404 |
Moves the item by \a dx points horizontally, and \a dy point
|
|
3405 |
vertically. This function is equivalent to calling setPos(pos() +
|
|
3406 |
QPointF(\a dx, \a dy)).
|
|
3407 |
*/
|
|
3408 |
|
|
3409 |
/*!
|
|
3410 |
If this item is part of a scene that is viewed by a QGraphicsView, this
|
|
3411 |
convenience function will attempt to scroll the view to ensure that \a
|
|
3412 |
rect is visible inside the view's viewport. If \a rect is a null rect (the
|
|
3413 |
default), QGraphicsItem will default to the item's bounding rect. \a xmargin
|
|
3414 |
and \a ymargin are the number of pixels the view should use for margins.
|
|
3415 |
|
|
3416 |
If the specified rect cannot be reached, the contents are scrolled to the
|
|
3417 |
nearest valid position.
|
|
3418 |
|
|
3419 |
If this item is not viewed by a QGraphicsView, this function does nothing.
|
|
3420 |
|
|
3421 |
\sa QGraphicsView::ensureVisible()
|
|
3422 |
*/
|
|
3423 |
void QGraphicsItem::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
|
|
3424 |
{
|
|
3425 |
if (d_ptr->scene) {
|
|
3426 |
QRectF sceneRect;
|
|
3427 |
if (!rect.isNull())
|
|
3428 |
sceneRect = sceneTransform().mapRect(rect);
|
|
3429 |
else
|
|
3430 |
sceneRect = sceneBoundingRect();
|
|
3431 |
foreach (QGraphicsView *view, d_ptr->scene->d_func()->views)
|
|
3432 |
view->ensureVisible(sceneRect, xmargin, ymargin);
|
|
3433 |
}
|
|
3434 |
}
|
|
3435 |
|
|
3436 |
/*!
|
|
3437 |
\fn void QGraphicsItem::ensureVisible(qreal x, qreal y, qreal w, qreal h,
|
|
3438 |
int xmargin = 50, int ymargin = 50)
|
|
3439 |
|
|
3440 |
This convenience function is equivalent to calling
|
|
3441 |
ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin):
|
|
3442 |
*/
|
|
3443 |
|
|
3444 |
/*!
|
|
3445 |
\obsolete
|
|
3446 |
|
|
3447 |
Returns the item's affine transformation matrix. This is a subset or the
|
|
3448 |
item's full transformation matrix, and might not represent the item's full
|
|
3449 |
transformation.
|
|
3450 |
|
|
3451 |
Use transform() instead.
|
|
3452 |
|
|
3453 |
\sa setTransform(), sceneTransform()
|
|
3454 |
*/
|
|
3455 |
QMatrix QGraphicsItem::matrix() const
|
|
3456 |
{
|
|
3457 |
return transform().toAffine();
|
|
3458 |
}
|
|
3459 |
|
|
3460 |
/*!
|
|
3461 |
\since 4.3
|
|
3462 |
|
|
3463 |
Returns this item's transformation matrix.
|
|
3464 |
|
|
3465 |
The transformation matrix is combined with the item's rotation(), scale()
|
|
3466 |
and transformations() into a combined transformations for the item.
|
|
3467 |
|
|
3468 |
The default transformation matrix is an identity matrix.
|
|
3469 |
|
|
3470 |
\sa setTransform(), sceneTransform()
|
|
3471 |
*/
|
|
3472 |
QTransform QGraphicsItem::transform() const
|
|
3473 |
{
|
|
3474 |
if (!d_ptr->transformData)
|
|
3475 |
return QTransform();
|
|
3476 |
return d_ptr->transformData->transform;
|
|
3477 |
}
|
|
3478 |
|
|
3479 |
/*!
|
|
3480 |
\since 4.6
|
|
3481 |
|
|
3482 |
Returns the clockwise rotation, in degrees, around the Z axis. The default
|
|
3483 |
value is 0 (i.e., the item is not rotated).
|
|
3484 |
|
|
3485 |
The rotation is combined with the item's scale(), transform() and
|
|
3486 |
transformations() to map the item's coordinate system to the parent item.
|
|
3487 |
|
|
3488 |
\sa setRotation(), transformOriginPoint(), {Transformations}
|
|
3489 |
*/
|
|
3490 |
qreal QGraphicsItem::rotation() const
|
|
3491 |
{
|
|
3492 |
if (!d_ptr->transformData)
|
|
3493 |
return 0;
|
|
3494 |
return d_ptr->transformData->rotation;
|
|
3495 |
}
|
|
3496 |
|
|
3497 |
/*!
|
|
3498 |
\since 4.6
|
|
3499 |
|
|
3500 |
Sets the clockwise rotation \a angle, in degrees, around the Z axis. The
|
|
3501 |
default value is 0 (i.e., the item is not rotated). Assigning a negative
|
|
3502 |
value will rotate the item counter-clockwise. Normally the rotation angle
|
|
3503 |
is in the range (-360, 360), but it's also possible to assign values
|
|
3504 |
outside of this range (e.g., a rotation of 370 degrees is the same as a
|
|
3505 |
rotation of 10 degrees).
|
|
3506 |
|
|
3507 |
The item is rotated around its transform origin point, which by default
|
|
3508 |
is (0, 0). You can select a different transformation origin by calling
|
|
3509 |
setTransformOriginPoint().
|
|
3510 |
|
|
3511 |
The rotation is combined with the item's scale(), transform() and
|
|
3512 |
transformations() to map the item's coordinate system to the parent item.
|
|
3513 |
|
|
3514 |
\sa rotation(), setTransformOriginPoint(), {Transformations}
|
|
3515 |
*/
|
|
3516 |
void QGraphicsItem::setRotation(qreal angle)
|
|
3517 |
{
|
|
3518 |
prepareGeometryChange();
|
|
3519 |
if (!d_ptr->transformData)
|
|
3520 |
d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
|
|
3521 |
d_ptr->transformData->rotation = angle;
|
|
3522 |
d_ptr->transformData->onlyTransform = false;
|
|
3523 |
d_ptr->dirtySceneTransform = 1;
|
|
3524 |
|
|
3525 |
if (d_ptr->isObject)
|
|
3526 |
emit static_cast<QGraphicsObject *>(this)->rotationChanged();
|
|
3527 |
}
|
|
3528 |
|
|
3529 |
/*!
|
|
3530 |
\since 4.6
|
|
3531 |
|
|
3532 |
Returns the scale factor of the item. The default scale factor is 1.0
|
|
3533 |
(i.e., the item is not scaled).
|
|
3534 |
|
|
3535 |
The scale is combined with the item's rotation(), transform() and
|
|
3536 |
transformations() to map the item's coordinate system to the parent item.
|
|
3537 |
|
|
3538 |
\sa setScale(), rotation(), {Transformations}
|
|
3539 |
*/
|
|
3540 |
qreal QGraphicsItem::scale() const
|
|
3541 |
{
|
|
3542 |
if (!d_ptr->transformData)
|
|
3543 |
return 1.;
|
|
3544 |
return d_ptr->transformData->scale;
|
|
3545 |
}
|
|
3546 |
|
|
3547 |
/*!
|
|
3548 |
\since 4.6
|
|
3549 |
|
|
3550 |
Sets the scale \a factor of the item. The default scale factor is 1.0
|
|
3551 |
(i.e., the item is not scaled). A scale factor of 0.0 will collapse the
|
|
3552 |
item to a single point. If you provide a negative scale factor, the
|
|
3553 |
item will be flipped and mirrored (i.e., rotated 180 degrees).
|
|
3554 |
|
|
3555 |
The item is scaled around its transform origin point, which by default
|
|
3556 |
is (0, 0). You can select a different transformation origin by calling
|
|
3557 |
setTransformOriginPoint().
|
|
3558 |
|
|
3559 |
The scale is combined with the item's rotation(), transform() and
|
|
3560 |
transformations() to map the item's coordinate system to the parent item.
|
|
3561 |
|
|
3562 |
\sa scale(), setTransformOriginPoint(), {Transformations}
|
|
3563 |
*/
|
|
3564 |
void QGraphicsItem::setScale(qreal factor)
|
|
3565 |
{
|
|
3566 |
prepareGeometryChange();
|
|
3567 |
if (!d_ptr->transformData)
|
|
3568 |
d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
|
|
3569 |
d_ptr->transformData->scale = factor;
|
|
3570 |
d_ptr->transformData->onlyTransform = false;
|
|
3571 |
d_ptr->dirtySceneTransform = 1;
|
|
3572 |
|
|
3573 |
if (d_ptr->isObject)
|
|
3574 |
emit static_cast<QGraphicsObject *>(this)->scaleChanged();
|
|
3575 |
}
|
|
3576 |
|
|
3577 |
|
|
3578 |
/*!
|
|
3579 |
\since 4.6
|
|
3580 |
|
|
3581 |
Returns a list of graphics transforms that currently apply to this item.
|
|
3582 |
|
|
3583 |
QGraphicsTransform is for applying and controlling a chain of individual
|
|
3584 |
transformation operations on an item. It's particularily useful in
|
|
3585 |
animations, where each transform operation needs to be interpolated
|
|
3586 |
independently, or differently.
|
|
3587 |
|
|
3588 |
The transformations are combined with the item's rotation(), scale() and
|
|
3589 |
transform() to map the item's coordinate system to the parent item.
|
|
3590 |
|
|
3591 |
\sa scale(), rotation(), transformOriginPoint(), {Transformations}
|
|
3592 |
*/
|
|
3593 |
QList<QGraphicsTransform *> QGraphicsItem::transformations() const
|
|
3594 |
{
|
|
3595 |
if (!d_ptr->transformData)
|
|
3596 |
return QList<QGraphicsTransform *>();
|
|
3597 |
return d_ptr->transformData->graphicsTransforms;
|
|
3598 |
}
|
|
3599 |
|
|
3600 |
/*!
|
|
3601 |
\since 4.6
|
|
3602 |
|
|
3603 |
Sets a list of graphics \a transformations (QGraphicsTransform) that
|
|
3604 |
currently apply to this item.
|
|
3605 |
|
|
3606 |
If all you want is to rotate or scale an item, you should call setRotation()
|
|
3607 |
or setScale() instead. If you want to set an arbitrary transformation on
|
|
3608 |
an item, you can call setTransform().
|
|
3609 |
|
|
3610 |
QGraphicsTransform is for applying and controlling a chain of individual
|
|
3611 |
transformation operations on an item. It's particularily useful in
|
|
3612 |
animations, where each transform operation needs to be interpolated
|
|
3613 |
independently, or differently.
|
|
3614 |
|
|
3615 |
The transformations are combined with the item's rotation(), scale() and
|
|
3616 |
transform() to map the item's coordinate system to the parent item.
|
|
3617 |
|
|
3618 |
\sa scale(), setTransformOriginPoint(), {Transformations}
|
|
3619 |
*/
|
|
3620 |
void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transformations)
|
|
3621 |
{
|
|
3622 |
prepareGeometryChange();
|
|
3623 |
if (!d_ptr->transformData)
|
|
3624 |
d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
|
|
3625 |
d_ptr->transformData->graphicsTransforms = transformations;
|
|
3626 |
for (int i = 0; i < transformations.size(); ++i)
|
|
3627 |
transformations.at(i)->d_func()->setItem(this);
|
|
3628 |
d_ptr->transformData->onlyTransform = false;
|
|
3629 |
d_ptr->dirtySceneTransform = 1;
|
|
3630 |
}
|
|
3631 |
|
|
3632 |
/*!
|
|
3633 |
\internal
|
|
3634 |
*/
|
|
3635 |
void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t)
|
|
3636 |
{
|
|
3637 |
if (!transformData)
|
|
3638 |
transformData = new QGraphicsItemPrivate::TransformData;
|
|
3639 |
if (!transformData->graphicsTransforms.contains(t))
|
|
3640 |
transformData->graphicsTransforms.append(t);
|
|
3641 |
|
|
3642 |
Q_Q(QGraphicsItem);
|
|
3643 |
t->d_func()->setItem(q);
|
|
3644 |
transformData->onlyTransform = false;
|
|
3645 |
dirtySceneTransform = 1;
|
|
3646 |
}
|
|
3647 |
|
|
3648 |
/*!
|
|
3649 |
\since 4.6
|
|
3650 |
|
|
3651 |
Returns the origin point for the transformation in item coordinates.
|
|
3652 |
|
|
3653 |
The default is QPointF(0,0).
|
|
3654 |
|
|
3655 |
\sa setTransformOriginPoint(), {Transformations}
|
|
3656 |
*/
|
|
3657 |
QPointF QGraphicsItem::transformOriginPoint() const
|
|
3658 |
{
|
|
3659 |
if (!d_ptr->transformData)
|
|
3660 |
return QPointF(0,0);
|
|
3661 |
return QPointF(d_ptr->transformData->xOrigin, d_ptr->transformData->yOrigin);
|
|
3662 |
}
|
|
3663 |
|
|
3664 |
/*!
|
|
3665 |
\since 4.6
|
|
3666 |
|
|
3667 |
Sets the \a origin point for the transformation in item coordinates.
|
|
3668 |
|
|
3669 |
\sa transformOriginPoint(), {Transformations}
|
|
3670 |
*/
|
|
3671 |
void QGraphicsItem::setTransformOriginPoint(const QPointF &origin)
|
|
3672 |
{
|
|
3673 |
prepareGeometryChange();
|
|
3674 |
if (!d_ptr->transformData)
|
|
3675 |
d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
|
|
3676 |
d_ptr->transformData->xOrigin = origin.x();
|
|
3677 |
d_ptr->transformData->yOrigin = origin.y();
|
|
3678 |
d_ptr->transformData->onlyTransform = false;
|
|
3679 |
d_ptr->dirtySceneTransform = 1;
|
|
3680 |
}
|
|
3681 |
|
|
3682 |
/*!
|
|
3683 |
\fn void QGraphicsItem::setTransformOriginPoint(qreal x, qreal y)
|
|
3684 |
|
|
3685 |
\since 4.6
|
|
3686 |
\overload
|
|
3687 |
|
|
3688 |
Sets the origin point for the transformation in item coordinates.
|
|
3689 |
This is equivalent to calling setTransformOriginPoint(QPointF(\a x, \a y)).
|
|
3690 |
|
|
3691 |
\sa setTransformOriginPoint(), {Transformations}
|
|
3692 |
*/
|
|
3693 |
|
|
3694 |
|
|
3695 |
/*!
|
|
3696 |
\obsolete
|
|
3697 |
|
|
3698 |
Use sceneTransform() instead.
|
|
3699 |
|
|
3700 |
\sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}
|
|
3701 |
*/
|
|
3702 |
QMatrix QGraphicsItem::sceneMatrix() const
|
|
3703 |
{
|
|
3704 |
d_ptr->ensureSceneTransform();
|
|
3705 |
return d_ptr->sceneTransform.toAffine();
|
|
3706 |
}
|
|
3707 |
|
|
3708 |
|
|
3709 |
/*!
|
|
3710 |
\since 4.3
|
|
3711 |
|
|
3712 |
Returns this item's scene transformation matrix. This matrix can be used
|
|
3713 |
to map coordinates and geometrical shapes from this item's local
|
|
3714 |
coordinate system to the scene's coordinate system. To map coordinates
|
|
3715 |
from the scene, you must first invert the returned matrix.
|
|
3716 |
|
|
3717 |
Example:
|
|
3718 |
|
|
3719 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 4
|
|
3720 |
|
|
3721 |
Unlike transform(), which returns only an item's local transformation, this
|
|
3722 |
function includes the item's (and any parents') position, and all the transfomation properties.
|
|
3723 |
|
|
3724 |
\sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate System}, {Transformations}
|
|
3725 |
*/
|
|
3726 |
QTransform QGraphicsItem::sceneTransform() const
|
|
3727 |
{
|
|
3728 |
d_ptr->ensureSceneTransform();
|
|
3729 |
return d_ptr->sceneTransform;
|
|
3730 |
}
|
|
3731 |
|
|
3732 |
/*!
|
|
3733 |
\since 4.3
|
|
3734 |
|
|
3735 |
Returns this item's device transformation matrix, using \a
|
|
3736 |
viewportTransform to map from scene to device coordinates. This matrix can
|
|
3737 |
be used to map coordinates and geometrical shapes from this item's local
|
|
3738 |
coordinate system to the viewport's (or any device's) coordinate
|
|
3739 |
system. To map coordinates from the viewport, you must first invert the
|
|
3740 |
returned matrix.
|
|
3741 |
|
|
3742 |
Example:
|
|
3743 |
|
|
3744 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 5
|
|
3745 |
|
|
3746 |
This function is the same as combining this item's scene transform with
|
|
3747 |
the view's viewport transform, but it also understands the
|
|
3748 |
ItemIgnoresTransformations flag. The device transform can be used to do
|
|
3749 |
accurate coordinate mapping (and collision detection) for untransformable
|
|
3750 |
items.
|
|
3751 |
|
|
3752 |
\sa transform(), setTransform(), scenePos(), {The Graphics View Coordinate
|
|
3753 |
System}, itemTransform()
|
|
3754 |
*/
|
|
3755 |
QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) const
|
|
3756 |
{
|
|
3757 |
// Ensure we return the standard transform if we're not untransformable.
|
|
3758 |
if (!d_ptr->itemIsUntransformable()) {
|
|
3759 |
d_ptr->ensureSceneTransform();
|
|
3760 |
return d_ptr->sceneTransform * viewportTransform;
|
|
3761 |
}
|
|
3762 |
|
|
3763 |
// Find the topmost item that ignores view transformations.
|
|
3764 |
const QGraphicsItem *untransformedAncestor = this;
|
|
3765 |
QList<const QGraphicsItem *> parents;
|
|
3766 |
while (untransformedAncestor && ((untransformedAncestor->d_ptr->ancestorFlags
|
|
3767 |
& QGraphicsItemPrivate::AncestorIgnoresTransformations))) {
|
|
3768 |
parents.prepend(untransformedAncestor);
|
|
3769 |
untransformedAncestor = untransformedAncestor->parentItem();
|
|
3770 |
}
|
|
3771 |
|
|
3772 |
if (!untransformedAncestor) {
|
|
3773 |
// Assert in debug mode, continue in release.
|
|
3774 |
Q_ASSERT_X(untransformedAncestor, "QGraphicsItem::deviceTransform",
|
|
3775 |
"Invalid object structure!");
|
|
3776 |
return QTransform();
|
|
3777 |
}
|
|
3778 |
|
|
3779 |
// First translate the base untransformable item.
|
|
3780 |
untransformedAncestor->d_ptr->ensureSceneTransform();
|
|
3781 |
QPointF mappedPoint = (untransformedAncestor->d_ptr->sceneTransform * viewportTransform).map(QPointF(0, 0));
|
|
3782 |
|
|
3783 |
// COMBINE
|
|
3784 |
QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y());
|
|
3785 |
if (untransformedAncestor->d_ptr->transformData)
|
|
3786 |
matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform(&matrix);
|
|
3787 |
|
|
3788 |
// Then transform and translate all children.
|
|
3789 |
for (int i = 0; i < parents.size(); ++i) {
|
|
3790 |
const QGraphicsItem *parent = parents.at(i);
|
|
3791 |
parent->d_ptr->combineTransformFromParent(&matrix);
|
|
3792 |
}
|
|
3793 |
|
|
3794 |
return matrix;
|
|
3795 |
}
|
|
3796 |
|
|
3797 |
/*!
|
|
3798 |
\since 4.5
|
|
3799 |
|
|
3800 |
Returns a QTransform that maps coordinates from this item to \a other. If
|
|
3801 |
\a ok is not null, and if there is no such transform, the boolean pointed
|
|
3802 |
to by \a ok will be set to false; otherwise it will be set to true.
|
|
3803 |
|
|
3804 |
This transform provides an alternative to the mapToItem() or mapFromItem()
|
|
3805 |
functions, by returning the appropriate transform so that you can map
|
|
3806 |
shapes and coordinates yourself. It also helps you write more efficient
|
|
3807 |
code when repeatedly mapping between the same two items.
|
|
3808 |
|
|
3809 |
\note In rare circumstances, there is no transform that maps between two
|
|
3810 |
items.
|
|
3811 |
|
|
3812 |
\sa mapToItem(), mapFromItem(), deviceTransform()
|
|
3813 |
*/
|
|
3814 |
QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) const
|
|
3815 |
{
|
|
3816 |
// Catch simple cases first.
|
|
3817 |
if (other == 0) {
|
|
3818 |
qWarning("QGraphicsItem::itemTransform: null pointer passed");
|
|
3819 |
return QTransform();
|
|
3820 |
}
|
|
3821 |
if (other == this) {
|
|
3822 |
if (ok)
|
|
3823 |
*ok = true;
|
|
3824 |
return QTransform();
|
|
3825 |
}
|
|
3826 |
|
|
3827 |
QGraphicsItem *parent = d_ptr->parent;
|
|
3828 |
const QGraphicsItem *otherParent = other->d_ptr->parent;
|
|
3829 |
|
|
3830 |
// This is other's child
|
|
3831 |
if (parent == other) {
|
|
3832 |
if (ok)
|
|
3833 |
*ok = true;
|
|
3834 |
QTransform x;
|
|
3835 |
d_ptr->combineTransformFromParent(&x);
|
|
3836 |
return x;
|
|
3837 |
}
|
|
3838 |
|
|
3839 |
// This is other's parent
|
|
3840 |
if (otherParent == this) {
|
|
3841 |
const QPointF &otherPos = other->d_ptr->pos;
|
|
3842 |
if (other->d_ptr->transformData) {
|
|
3843 |
QTransform otherToParent;
|
|
3844 |
other->d_ptr->combineTransformFromParent(&otherToParent);
|
|
3845 |
return otherToParent.inverted(ok);
|
|
3846 |
}
|
|
3847 |
if (ok)
|
|
3848 |
*ok = true;
|
|
3849 |
return QTransform::fromTranslate(-otherPos.x(), -otherPos.y());
|
|
3850 |
}
|
|
3851 |
|
|
3852 |
// Siblings
|
|
3853 |
if (parent == otherParent) {
|
|
3854 |
// COMBINE
|
|
3855 |
const QPointF &itemPos = d_ptr->pos;
|
|
3856 |
const QPointF &otherPos = other->d_ptr->pos;
|
|
3857 |
if (!d_ptr->transformData && !other->d_ptr->transformData) {
|
|
3858 |
QPointF delta = itemPos - otherPos;
|
|
3859 |
if (ok)
|
|
3860 |
*ok = true;
|
|
3861 |
return QTransform::fromTranslate(delta.x(), delta.y());
|
|
3862 |
}
|
|
3863 |
|
|
3864 |
QTransform itemToParent;
|
|
3865 |
d_ptr->combineTransformFromParent(&itemToParent);
|
|
3866 |
QTransform otherToParent;
|
|
3867 |
other->d_ptr->combineTransformFromParent(&otherToParent);
|
|
3868 |
return itemToParent * otherToParent.inverted(ok);
|
|
3869 |
}
|
|
3870 |
|
|
3871 |
// Find the closest common ancestor. If the two items don't share an
|
|
3872 |
// ancestor, then the only way is to combine their scene transforms.
|
|
3873 |
const QGraphicsItem *commonAncestor = commonAncestorItem(other);
|
|
3874 |
if (!commonAncestor) {
|
|
3875 |
d_ptr->ensureSceneTransform();
|
|
3876 |
other->d_ptr->ensureSceneTransform();
|
|
3877 |
return d_ptr->sceneTransform * other->d_ptr->sceneTransform.inverted(ok);
|
|
3878 |
}
|
|
3879 |
|
|
3880 |
// If the two items are cousins (in sibling branches), map both to the
|
|
3881 |
// common ancestor, and combine the two transforms.
|
|
3882 |
bool cousins = other != commonAncestor && this != commonAncestor;
|
|
3883 |
if (cousins) {
|
|
3884 |
bool good = false;
|
|
3885 |
QTransform thisToScene = itemTransform(commonAncestor, &good);
|
|
3886 |
QTransform otherToScene(Qt::Uninitialized);
|
|
3887 |
if (good)
|
|
3888 |
otherToScene = other->itemTransform(commonAncestor, &good);
|
|
3889 |
if (!good) {
|
|
3890 |
if (ok)
|
|
3891 |
*ok = false;
|
|
3892 |
return QTransform();
|
|
3893 |
}
|
|
3894 |
return thisToScene * otherToScene.inverted(ok);
|
|
3895 |
}
|
|
3896 |
|
|
3897 |
// One is an ancestor of the other; walk the chain.
|
|
3898 |
bool parentOfOther = isAncestorOf(other);
|
|
3899 |
const QGraphicsItem *child = parentOfOther ? other : this;
|
|
3900 |
const QGraphicsItem *root = parentOfOther ? this : other;
|
|
3901 |
|
|
3902 |
QTransform x;
|
|
3903 |
const QGraphicsItem *p = child;
|
|
3904 |
do {
|
|
3905 |
p->d_ptr.data()->combineTransformToParent(&x);
|
|
3906 |
} while ((p = p->d_ptr->parent) && p != root);
|
|
3907 |
if (parentOfOther)
|
|
3908 |
return x.inverted(ok);
|
|
3909 |
if (ok)
|
|
3910 |
*ok = true;
|
|
3911 |
return x;
|
|
3912 |
}
|
|
3913 |
|
|
3914 |
/*!
|
|
3915 |
\obsolete
|
|
3916 |
|
|
3917 |
Sets the item's affine transformation matrix. This is a subset or the
|
|
3918 |
item's full transformation matrix, and might not represent the item's full
|
|
3919 |
transformation.
|
|
3920 |
|
|
3921 |
Use setTransform() instead.
|
|
3922 |
|
|
3923 |
\sa transform(), {The Graphics View Coordinate System}
|
|
3924 |
*/
|
|
3925 |
void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine)
|
|
3926 |
{
|
|
3927 |
if (!d_ptr->transformData)
|
|
3928 |
d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
|
|
3929 |
|
|
3930 |
QTransform newTransform(combine ? QTransform(matrix) * d_ptr->transformData->transform : QTransform(matrix));
|
|
3931 |
if (d_ptr->transformData->transform == newTransform)
|
|
3932 |
return;
|
|
3933 |
|
|
3934 |
// Update and set the new transformation.
|
|
3935 |
if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
|
|
3936 |
d_ptr->setTransformHelper(newTransform);
|
|
3937 |
return;
|
|
3938 |
}
|
|
3939 |
|
|
3940 |
// Notify the item that the transformation matrix is changing.
|
|
3941 |
const QVariant newMatrixVariant = qVariantFromValue<QMatrix>(newTransform.toAffine());
|
|
3942 |
newTransform = QTransform(qVariantValue<QMatrix>(itemChange(ItemMatrixChange, newMatrixVariant)));
|
|
3943 |
if (d_ptr->transformData->transform == newTransform)
|
|
3944 |
return;
|
|
3945 |
|
|
3946 |
// Update and set the new transformation.
|
|
3947 |
d_ptr->setTransformHelper(newTransform);
|
|
3948 |
|
|
3949 |
// Send post-notification.
|
|
3950 |
itemChange(ItemTransformHasChanged, qVariantFromValue<QTransform>(newTransform));
|
|
3951 |
}
|
|
3952 |
|
|
3953 |
/*!
|
|
3954 |
\since 4.3
|
|
3955 |
|
|
3956 |
Sets the item's current transformation matrix to \a matrix.
|
|
3957 |
|
|
3958 |
If \a combine is true, then \a matrix is combined with the current matrix;
|
|
3959 |
otherwise, \a matrix \e replaces the current matrix. \a combine is false
|
|
3960 |
by default.
|
|
3961 |
|
|
3962 |
To simplify interation with items using a transformed view, QGraphicsItem
|
|
3963 |
provides mapTo... and mapFrom... functions that can translate between
|
|
3964 |
items' and the scene's coordinates. For example, you can call mapToScene()
|
|
3965 |
to map an item coordiate to a scene coordinate, or mapFromScene() to map
|
|
3966 |
from scene coordinates to item coordinates.
|
|
3967 |
|
|
3968 |
The transformation matrix is combined with the item's rotation(), scale()
|
|
3969 |
and transformations() into a combined transformation that maps the item's
|
|
3970 |
coordinate system to its parent.
|
|
3971 |
|
|
3972 |
\sa transform(), setRotation(), setScale(), setTransformOriginPoint(), {The Graphics View Coordinate System}, {Transformations}
|
|
3973 |
*/
|
|
3974 |
void QGraphicsItem::setTransform(const QTransform &matrix, bool combine)
|
|
3975 |
{
|
|
3976 |
if (!d_ptr->transformData)
|
|
3977 |
d_ptr->transformData = new QGraphicsItemPrivate::TransformData;
|
|
3978 |
|
|
3979 |
QTransform newTransform(combine ? matrix * d_ptr->transformData->transform : matrix);
|
|
3980 |
if (d_ptr->transformData->transform == newTransform)
|
|
3981 |
return;
|
|
3982 |
|
|
3983 |
// Update and set the new transformation.
|
|
3984 |
if (!(d_ptr->flags & ItemSendsGeometryChanges)) {
|
|
3985 |
d_ptr->setTransformHelper(newTransform);
|
|
3986 |
return;
|
|
3987 |
}
|
|
3988 |
|
|
3989 |
// Notify the item that the transformation matrix is changing.
|
|
3990 |
const QVariant newTransformVariant(itemChange(ItemTransformChange,
|
|
3991 |
qVariantFromValue<QTransform>(newTransform)));
|
|
3992 |
newTransform = qVariantValue<QTransform>(newTransformVariant);
|
|
3993 |
if (d_ptr->transformData->transform == newTransform)
|
|
3994 |
return;
|
|
3995 |
|
|
3996 |
// Update and set the new transformation.
|
|
3997 |
d_ptr->setTransformHelper(newTransform);
|
|
3998 |
|
|
3999 |
// Send post-notification.
|
|
4000 |
itemChange(ItemTransformHasChanged, newTransformVariant);
|
|
4001 |
}
|
|
4002 |
|
|
4003 |
/*!
|
|
4004 |
\obsolete
|
|
4005 |
|
|
4006 |
Use resetTransform() instead.
|
|
4007 |
*/
|
|
4008 |
void QGraphicsItem::resetMatrix()
|
|
4009 |
{
|
|
4010 |
resetTransform();
|
|
4011 |
}
|
|
4012 |
|
|
4013 |
/*!
|
|
4014 |
\since 4.3
|
|
4015 |
|
|
4016 |
Resets this item's transformation matrix to the identity matrix or
|
|
4017 |
all the transformation properties to their default values.
|
|
4018 |
This is equivalent to calling \c setTransform(QTransform()).
|
|
4019 |
|
|
4020 |
\sa setTransform(), transform()
|
|
4021 |
*/
|
|
4022 |
void QGraphicsItem::resetTransform()
|
|
4023 |
{
|
|
4024 |
setTransform(QTransform(), false);
|
|
4025 |
}
|
|
4026 |
|
|
4027 |
/*!
|
|
4028 |
\obsolete
|
|
4029 |
|
|
4030 |
Use
|
|
4031 |
|
|
4032 |
\code
|
|
4033 |
setRotation(rotation() + angle);
|
|
4034 |
\endcode
|
|
4035 |
|
|
4036 |
instead.
|
|
4037 |
|
|
4038 |
Rotates the current item transformation \a angle degrees clockwise around
|
|
4039 |
its origin. To translate around an arbitrary point (x, y), you need to
|
|
4040 |
combine translation and rotation with setTransform().
|
|
4041 |
|
|
4042 |
Example:
|
|
4043 |
|
|
4044 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 6
|
|
4045 |
|
|
4046 |
\sa setTransform(), transform(), scale(), shear(), translate()
|
|
4047 |
*/
|
|
4048 |
void QGraphicsItem::rotate(qreal angle)
|
|
4049 |
{
|
|
4050 |
setTransform(QTransform().rotate(angle), true);
|
|
4051 |
}
|
|
4052 |
|
|
4053 |
/*!
|
|
4054 |
\obsolete
|
|
4055 |
|
|
4056 |
Use
|
|
4057 |
|
|
4058 |
\code
|
|
4059 |
setTransform(QTransform::fromScale(sx, sy), true);
|
|
4060 |
\endcode
|
|
4061 |
|
|
4062 |
instead.
|
|
4063 |
|
|
4064 |
Scales the current item transformation by (\a sx, \a sy) around its
|
|
4065 |
origin. To scale from an arbitrary point (x, y), you need to combine
|
|
4066 |
translation and scaling with setTransform().
|
|
4067 |
|
|
4068 |
Example:
|
|
4069 |
|
|
4070 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 7
|
|
4071 |
|
|
4072 |
\sa setTransform(), transform()
|
|
4073 |
*/
|
|
4074 |
void QGraphicsItem::scale(qreal sx, qreal sy)
|
|
4075 |
{
|
|
4076 |
setTransform(QTransform::fromScale(sx, sy), true);
|
|
4077 |
}
|
|
4078 |
|
|
4079 |
/*!
|
|
4080 |
\obsolete
|
|
4081 |
|
|
4082 |
Use
|
|
4083 |
|
|
4084 |
\code
|
|
4085 |
setTransform(QTransform().shear(sh, sv), true);
|
|
4086 |
\endcode
|
|
4087 |
|
|
4088 |
instead.
|
|
4089 |
|
|
4090 |
Shears the current item transformation by (\a sh, \a sv).
|
|
4091 |
|
|
4092 |
\sa setTransform(), transform()
|
|
4093 |
*/
|
|
4094 |
void QGraphicsItem::shear(qreal sh, qreal sv)
|
|
4095 |
{
|
|
4096 |
setTransform(QTransform().shear(sh, sv), true);
|
|
4097 |
}
|
|
4098 |
|
|
4099 |
/*!
|
|
4100 |
\obsolete
|
|
4101 |
|
|
4102 |
Use setPos() or setTransformOriginPoint() instead. For identical
|
|
4103 |
behavior, use
|
|
4104 |
|
|
4105 |
\code
|
|
4106 |
setTransform(QTransform::fromTranslate(dx, dy), true);
|
|
4107 |
\endcode
|
|
4108 |
|
|
4109 |
Translates the current item transformation by (\a dx, \a dy).
|
|
4110 |
|
|
4111 |
If all you want is to move an item, you should call moveBy() or
|
|
4112 |
setPos() instead; this function changes the item's translation,
|
|
4113 |
which is conceptually separate from its position.
|
|
4114 |
|
|
4115 |
\sa setTransform(), transform()
|
|
4116 |
*/
|
|
4117 |
void QGraphicsItem::translate(qreal dx, qreal dy)
|
|
4118 |
{
|
|
4119 |
setTransform(QTransform::fromTranslate(dx, dy), true);
|
|
4120 |
}
|
|
4121 |
|
|
4122 |
/*!
|
|
4123 |
This virtual function is called twice for all items by the
|
|
4124 |
QGraphicsScene::advance() slot. In the first phase, all items are called
|
|
4125 |
with \a phase == 0, indicating that items on the scene are about to
|
|
4126 |
advance, and then all items are called with \a phase == 1. Reimplement
|
|
4127 |
this function to update your item if you need simple scene-controlled
|
|
4128 |
animation.
|
|
4129 |
|
|
4130 |
The default implementation does nothing.
|
|
4131 |
|
|
4132 |
For individual item animation, an alternative to this function is to
|
|
4133 |
either use QGraphicsItemAnimation, or to multiple-inherit from QObject and
|
|
4134 |
QGraphicsItem, and animate your item using QObject::startTimer() and
|
|
4135 |
QObject::timerEvent().
|
|
4136 |
|
|
4137 |
\sa QGraphicsItemAnimation, QTimeLine
|
|
4138 |
*/
|
|
4139 |
void QGraphicsItem::advance(int phase)
|
|
4140 |
{
|
|
4141 |
Q_UNUSED(phase);
|
|
4142 |
}
|
|
4143 |
|
|
4144 |
/*!
|
|
4145 |
Returns the Z-value of the item. The Z-value affects the stacking order of
|
|
4146 |
sibling (neighboring) items.
|
|
4147 |
|
|
4148 |
The default Z-value is 0.
|
|
4149 |
|
|
4150 |
\sa setZValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
|
|
4151 |
*/
|
|
4152 |
qreal QGraphicsItem::zValue() const
|
|
4153 |
{
|
|
4154 |
return d_ptr->z;
|
|
4155 |
}
|
|
4156 |
|
|
4157 |
/*!
|
|
4158 |
Sets the Z-value of the item to \a z. The Z value decides the stacking
|
|
4159 |
order of sibling (neighboring) items. A sibling item of high Z value will
|
|
4160 |
always be drawn on top of another sibling item with a lower Z value.
|
|
4161 |
|
|
4162 |
If you restore the Z value, the item's insertion order will decide its
|
|
4163 |
stacking order.
|
|
4164 |
|
|
4165 |
The Z-value does not affect the item's size in any way.
|
|
4166 |
|
|
4167 |
The default Z-value is 0.
|
|
4168 |
|
|
4169 |
\sa zValue(), {QGraphicsItem#Sorting}{Sorting}, stackBefore(), ItemStacksBehindParent
|
|
4170 |
*/
|
|
4171 |
void QGraphicsItem::setZValue(qreal z)
|
|
4172 |
{
|
|
4173 |
const QVariant newZVariant(itemChange(ItemZValueChange, z));
|
|
4174 |
qreal newZ = newZVariant.toReal();
|
|
4175 |
if (newZ == d_ptr->z)
|
|
4176 |
return;
|
|
4177 |
|
|
4178 |
if (d_ptr->scene) {
|
|
4179 |
// Z Value has changed, we have to notify the index.
|
|
4180 |
d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant);
|
|
4181 |
}
|
|
4182 |
|
|
4183 |
d_ptr->z = newZ;
|
|
4184 |
if (d_ptr->parent)
|
|
4185 |
d_ptr->parent->d_ptr->needSortChildren = 1;
|
|
4186 |
else if (d_ptr->scene)
|
|
4187 |
d_ptr->scene->d_func()->needSortTopLevelItems = 1;
|
|
4188 |
|
|
4189 |
if (d_ptr->scene)
|
|
4190 |
d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true);
|
|
4191 |
|
|
4192 |
itemChange(ItemZValueHasChanged, newZVariant);
|
|
4193 |
|
|
4194 |
if (d_ptr->flags & ItemNegativeZStacksBehindParent)
|
|
4195 |
setFlag(QGraphicsItem::ItemStacksBehindParent, z < qreal(0.0));
|
|
4196 |
|
|
4197 |
if (d_ptr->isObject)
|
|
4198 |
emit static_cast<QGraphicsObject *>(this)->zChanged();
|
|
4199 |
}
|
|
4200 |
|
|
4201 |
/*!
|
|
4202 |
\internal
|
|
4203 |
|
|
4204 |
Ensures that the list of children is sorted by insertion order, and that
|
|
4205 |
the siblingIndexes are packed (no gaps), and start at 0.
|
|
4206 |
|
|
4207 |
### This function is almost identical to
|
|
4208 |
QGraphicsScenePrivate::ensureSequentialTopLevelSiblingIndexes().
|
|
4209 |
*/
|
|
4210 |
void QGraphicsItemPrivate::ensureSequentialSiblingIndex()
|
|
4211 |
{
|
|
4212 |
if (!sequentialOrdering) {
|
|
4213 |
qSort(children.begin(), children.end(), insertionOrder);
|
|
4214 |
sequentialOrdering = 1;
|
|
4215 |
needSortChildren = 1;
|
|
4216 |
}
|
|
4217 |
if (holesInSiblingIndex) {
|
|
4218 |
holesInSiblingIndex = 0;
|
|
4219 |
for (int i = 0; i < children.size(); ++i)
|
|
4220 |
children[i]->d_ptr->siblingIndex = i;
|
|
4221 |
}
|
|
4222 |
}
|
|
4223 |
|
|
4224 |
/*!
|
|
4225 |
\since 4.6
|
|
4226 |
|
|
4227 |
Stacks this item before \a sibling, which must be a sibling item (i.e., the
|
|
4228 |
two items must share the same parent item, or must both be toplevel items).
|
|
4229 |
The \a sibling must have the same Z value as this item, otherwise calling
|
|
4230 |
this function will have no effect.
|
|
4231 |
|
|
4232 |
By default, all sibling items are stacked by insertion order (i.e., the
|
|
4233 |
first item you add is drawn before the next item you add). If two items' Z
|
|
4234 |
values are different, then the item with the highest Z value is drawn on
|
|
4235 |
top. When the Z values are the same, the insertion order will decide the
|
|
4236 |
stacking order.
|
|
4237 |
|
|
4238 |
\sa setZValue(), ItemStacksBehindParent, {QGraphicsItem#Sorting}{Sorting}
|
|
4239 |
*/
|
|
4240 |
void QGraphicsItem::stackBefore(const QGraphicsItem *sibling)
|
|
4241 |
{
|
|
4242 |
if (sibling == this)
|
|
4243 |
return;
|
|
4244 |
if (!sibling || d_ptr->parent != sibling->parentItem()) {
|
|
4245 |
qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
|
|
4246 |
return;
|
|
4247 |
}
|
|
4248 |
QList<QGraphicsItem *> *siblings = d_ptr->parent
|
|
4249 |
? &d_ptr->parent->d_ptr->children
|
|
4250 |
: (d_ptr->scene ? &d_ptr->scene->d_func()->topLevelItems : 0);
|
|
4251 |
if (!siblings) {
|
|
4252 |
qWarning("QGraphicsItem::stackUnder: cannot stack under %p, which must be a sibling", sibling);
|
|
4253 |
return;
|
|
4254 |
}
|
|
4255 |
|
|
4256 |
// First, make sure that the sibling indexes have no holes. This also
|
|
4257 |
// marks the children list for sorting.
|
|
4258 |
if (d_ptr->parent)
|
|
4259 |
d_ptr->parent->d_ptr->ensureSequentialSiblingIndex();
|
|
4260 |
else
|
|
4261 |
d_ptr->scene->d_func()->ensureSequentialTopLevelSiblingIndexes();
|
|
4262 |
|
|
4263 |
// Only move items with the same Z value, and that need moving.
|
|
4264 |
int siblingIndex = sibling->d_ptr->siblingIndex;
|
|
4265 |
int myIndex = d_ptr->siblingIndex;
|
|
4266 |
if (myIndex >= siblingIndex && d_ptr->z == sibling->d_ptr->z) {
|
|
4267 |
siblings->move(myIndex, siblingIndex);
|
|
4268 |
// Fixup the insertion ordering.
|
|
4269 |
for (int i = 0; i < siblings->size(); ++i) {
|
|
4270 |
int &index = siblings->at(i)->d_ptr->siblingIndex;
|
|
4271 |
if (i != siblingIndex && index >= siblingIndex && index <= myIndex)
|
|
4272 |
++index;
|
|
4273 |
}
|
|
4274 |
d_ptr->siblingIndex = siblingIndex;
|
|
4275 |
}
|
|
4276 |
}
|
|
4277 |
|
|
4278 |
/*!
|
|
4279 |
Returns the bounding rect of this item's descendants (i.e., its
|
|
4280 |
children, their children, etc.) in local coordinates. The
|
|
4281 |
rectangle will contain all descendants after they have been mapped
|
|
4282 |
to local coordinates. If the item has no children, this function
|
|
4283 |
returns an empty QRectF.
|
|
4284 |
|
|
4285 |
This does not include this item's own bounding rect; it only returns
|
|
4286 |
its descendants' accumulated bounding rect. If you need to include this
|
|
4287 |
item's bounding rect, you can add boundingRect() to childrenBoundingRect()
|
|
4288 |
using QRectF::operator|().
|
|
4289 |
|
|
4290 |
This function is linear in complexity; it determines the size of the
|
|
4291 |
returned bounding rect by iterating through all descendants.
|
|
4292 |
|
|
4293 |
\sa boundingRect(), sceneBoundingRect()
|
|
4294 |
*/
|
|
4295 |
QRectF QGraphicsItem::childrenBoundingRect() const
|
|
4296 |
{
|
|
4297 |
if (!d_ptr->dirtyChildrenBoundingRect)
|
|
4298 |
return d_ptr->childrenBoundingRect;
|
|
4299 |
|
|
4300 |
d_ptr->childrenBoundingRect = QRectF();
|
|
4301 |
d_ptr->childrenBoundingRectHelper(0, &d_ptr->childrenBoundingRect);
|
|
4302 |
d_ptr->dirtyChildrenBoundingRect = 0;
|
|
4303 |
return d_ptr->childrenBoundingRect;
|
|
4304 |
}
|
|
4305 |
|
|
4306 |
/*!
|
|
4307 |
\fn virtual QRectF QGraphicsItem::boundingRect() const = 0
|
|
4308 |
|
|
4309 |
This pure virtual function defines the outer bounds of the item as
|
|
4310 |
a rectangle; all painting must be restricted to inside an item's
|
|
4311 |
bounding rect. QGraphicsView uses this to determine whether the
|
|
4312 |
item requires redrawing.
|
|
4313 |
|
|
4314 |
Although the item's shape can be arbitrary, the bounding rect is
|
|
4315 |
always rectangular, and it is unaffected by the items'
|
|
4316 |
transformation.
|
|
4317 |
|
|
4318 |
If you want to change the item's bounding rectangle, you must first call
|
|
4319 |
prepareGeometryChange(). This notifies the scene of the imminent change,
|
|
4320 |
so that its can update its item geometry index; otherwise, the scene will
|
|
4321 |
be unaware of the item's new geometry, and the results are undefined
|
|
4322 |
(typically, rendering artifacts are left around in the view).
|
|
4323 |
|
|
4324 |
Reimplement this function to let QGraphicsView determine what
|
|
4325 |
parts of the widget, if any, need to be redrawn.
|
|
4326 |
|
|
4327 |
Note: For shapes that paint an outline / stroke, it is important
|
|
4328 |
to include half the pen width in the bounding rect. It is not
|
|
4329 |
necessary to compensate for antialiasing, though.
|
|
4330 |
|
|
4331 |
Example:
|
|
4332 |
|
|
4333 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 8
|
|
4334 |
|
|
4335 |
\sa boundingRegion(), shape(), contains(), {The Graphics View Coordinate
|
|
4336 |
System}, prepareGeometryChange()
|
|
4337 |
*/
|
|
4338 |
|
|
4339 |
/*!
|
|
4340 |
Returns the bounding rect of this item in scene coordinates, by combining
|
|
4341 |
sceneTransform() with boundingRect().
|
|
4342 |
|
|
4343 |
\sa boundingRect(), {The Graphics View Coordinate System}
|
|
4344 |
*/
|
|
4345 |
QRectF QGraphicsItem::sceneBoundingRect() const
|
|
4346 |
{
|
|
4347 |
// Find translate-only offset
|
|
4348 |
// COMBINE
|
|
4349 |
QPointF offset;
|
|
4350 |
const QGraphicsItem *parentItem = this;
|
|
4351 |
const QGraphicsItemPrivate *itemd;
|
|
4352 |
do {
|
|
4353 |
itemd = parentItem->d_ptr.data();
|
|
4354 |
if (itemd->transformData)
|
|
4355 |
break;
|
|
4356 |
offset += itemd->pos;
|
|
4357 |
} while ((parentItem = itemd->parent));
|
|
4358 |
|
|
4359 |
QRectF br = boundingRect();
|
|
4360 |
br.translate(offset);
|
|
4361 |
if (!parentItem)
|
|
4362 |
return br;
|
|
4363 |
if (parentItem->d_ptr->hasTranslateOnlySceneTransform()) {
|
|
4364 |
br.translate(parentItem->d_ptr->sceneTransform.dx(), parentItem->d_ptr->sceneTransform.dy());
|
|
4365 |
return br;
|
|
4366 |
}
|
|
4367 |
return parentItem->d_ptr->sceneTransform.mapRect(br);
|
|
4368 |
}
|
|
4369 |
|
|
4370 |
/*!
|
|
4371 |
Returns the shape of this item as a QPainterPath in local
|
|
4372 |
coordinates. The shape is used for many things, including collision
|
|
4373 |
detection, hit tests, and for the QGraphicsScene::items() functions.
|
|
4374 |
|
|
4375 |
The default implementation calls boundingRect() to return a simple
|
|
4376 |
rectangular shape, but subclasses can reimplement this function to return
|
|
4377 |
a more accurate shape for non-rectangular items. For example, a round item
|
|
4378 |
may choose to return an elliptic shape for better collision detection. For
|
|
4379 |
example:
|
|
4380 |
|
|
4381 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 9
|
|
4382 |
|
|
4383 |
The outline of a shape can vary depending on the width and style of the
|
|
4384 |
pen used when drawing. If you want to include this outline in the item's
|
|
4385 |
shape, you can create a shape from the stroke using QPainterPathStroker.
|
|
4386 |
|
|
4387 |
This function is called by the default implementations of contains() and
|
|
4388 |
collidesWithPath().
|
|
4389 |
|
|
4390 |
\sa boundingRect(), contains(), prepareGeometryChange(), QPainterPathStroker
|
|
4391 |
*/
|
|
4392 |
QPainterPath QGraphicsItem::shape() const
|
|
4393 |
{
|
|
4394 |
QPainterPath path;
|
|
4395 |
path.addRect(boundingRect());
|
|
4396 |
return path;
|
|
4397 |
}
|
|
4398 |
|
|
4399 |
/*!
|
|
4400 |
Returns true if this item is clipped. An item is clipped if it has either
|
|
4401 |
set the \l ItemClipsToShape flag, or if it or any of its ancestors has set
|
|
4402 |
the \l ItemClipsChildrenToShape flag.
|
|
4403 |
|
|
4404 |
Clipping affects the item's appearance (i.e., painting), as well as mouse
|
|
4405 |
and hover event delivery.
|
|
4406 |
|
|
4407 |
\sa clipPath(), shape(), setFlags()
|
|
4408 |
*/
|
|
4409 |
bool QGraphicsItem::isClipped() const
|
|
4410 |
{
|
|
4411 |
Q_D(const QGraphicsItem);
|
|
4412 |
return (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
|
|
4413 |
|| (d->flags & QGraphicsItem::ItemClipsToShape);
|
|
4414 |
}
|
|
4415 |
|
|
4416 |
/*!
|
|
4417 |
\since 4.5
|
|
4418 |
|
|
4419 |
Returns this item's clip path, or an empty QPainterPath if this item is
|
|
4420 |
not clipped. The clip path constrains the item's appearance and
|
|
4421 |
interaction (i.e., restricts the area the item can draw, and it also
|
|
4422 |
restricts the area that the item receives events).
|
|
4423 |
|
|
4424 |
You can enable clipping by setting the ItemClipsToShape or
|
|
4425 |
ItemClipsChildrenToShape flags. The item's clip path is calculated by
|
|
4426 |
intersecting all clipping ancestors' shapes. If the item sets
|
|
4427 |
ItemClipsToShape, the final clip is intersected with the item's own shape.
|
|
4428 |
|
|
4429 |
\note Clipping introduces a performance penalty for all items involved;
|
|
4430 |
you should generally avoid using clipping if you can (e.g., if your items
|
|
4431 |
always draw inside boundingRect() or shape() boundaries, clipping is not
|
|
4432 |
necessary).
|
|
4433 |
|
|
4434 |
\sa isClipped(), shape(), setFlags()
|
|
4435 |
*/
|
|
4436 |
QPainterPath QGraphicsItem::clipPath() const
|
|
4437 |
{
|
|
4438 |
Q_D(const QGraphicsItem);
|
|
4439 |
if (!d->dirtyClipPath)
|
|
4440 |
return d->emptyClipPath ? QPainterPath() : d->cachedClipPath;
|
|
4441 |
|
|
4442 |
if (!isClipped()) {
|
|
4443 |
d_ptr->setCachedClipPath(QPainterPath());
|
|
4444 |
return d->cachedClipPath;
|
|
4445 |
}
|
|
4446 |
|
|
4447 |
const QRectF thisBoundingRect(boundingRect());
|
|
4448 |
if (thisBoundingRect.isEmpty()) {
|
|
4449 |
if (d_ptr->flags & ItemClipsChildrenToShape)
|
|
4450 |
d_ptr->setEmptyCachedClipPathRecursively();
|
|
4451 |
else
|
|
4452 |
d_ptr->setEmptyCachedClipPath();
|
|
4453 |
return QPainterPath();
|
|
4454 |
}
|
|
4455 |
|
|
4456 |
QPainterPath clip;
|
|
4457 |
// Start with the item's bounding rect.
|
|
4458 |
clip.addRect(thisBoundingRect);
|
|
4459 |
|
|
4460 |
if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
|
|
4461 |
const QGraphicsItem *parent = this;
|
|
4462 |
const QGraphicsItem *lastParent = this;
|
|
4463 |
|
|
4464 |
// Intersect any in-between clips starting at the top and moving downwards.
|
|
4465 |
bool foundValidClipPath = false;
|
|
4466 |
while ((parent = parent->d_ptr->parent)) {
|
|
4467 |
if (parent->d_ptr->flags & ItemClipsChildrenToShape) {
|
|
4468 |
// Map clip to the current parent and intersect with its shape/clipPath
|
|
4469 |
clip = lastParent->itemTransform(parent).map(clip);
|
|
4470 |
if ((foundValidClipPath = !parent->d_ptr->dirtyClipPath && parent->isClipped())) {
|
|
4471 |
if (parent->d_ptr->emptyClipPath) {
|
|
4472 |
if (d_ptr->flags & ItemClipsChildrenToShape)
|
|
4473 |
d_ptr->setEmptyCachedClipPathRecursively();
|
|
4474 |
else
|
|
4475 |
d_ptr->setEmptyCachedClipPath();
|
|
4476 |
return QPainterPath();
|
|
4477 |
}
|
|
4478 |
clip = clip.intersected(parent->d_ptr->cachedClipPath);
|
|
4479 |
if (!(parent->d_ptr->flags & ItemClipsToShape))
|
|
4480 |
clip = clip.intersected(parent->shape());
|
|
4481 |
} else {
|
|
4482 |
clip = clip.intersected(parent->shape());
|
|
4483 |
}
|
|
4484 |
|
|
4485 |
if (clip.isEmpty()) {
|
|
4486 |
if (d_ptr->flags & ItemClipsChildrenToShape)
|
|
4487 |
d_ptr->setEmptyCachedClipPathRecursively();
|
|
4488 |
else
|
|
4489 |
d_ptr->setEmptyCachedClipPath();
|
|
4490 |
return clip;
|
|
4491 |
}
|
|
4492 |
lastParent = parent;
|
|
4493 |
}
|
|
4494 |
|
|
4495 |
if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)
|
|
4496 |
|| foundValidClipPath) {
|
|
4497 |
break;
|
|
4498 |
}
|
|
4499 |
}
|
|
4500 |
|
|
4501 |
if (lastParent != this) {
|
|
4502 |
// Map clip back to the item's transform.
|
|
4503 |
// ### what if itemtransform fails
|
|
4504 |
clip = lastParent->itemTransform(this).map(clip);
|
|
4505 |
}
|
|
4506 |
}
|
|
4507 |
|
|
4508 |
if (d->flags & ItemClipsToShape)
|
|
4509 |
clip = clip.intersected(shape());
|
|
4510 |
|
|
4511 |
d_ptr->setCachedClipPath(clip);
|
|
4512 |
return clip;
|
|
4513 |
}
|
|
4514 |
|
|
4515 |
/*!
|
|
4516 |
Returns true if this item contains \a point, which is in local
|
|
4517 |
coordinates; otherwise, false is returned. It is most often called from
|
|
4518 |
QGraphicsView to determine what item is under the cursor, and for that
|
|
4519 |
reason, the implementation of this function should be as light-weight as
|
|
4520 |
possible.
|
|
4521 |
|
|
4522 |
By default, this function calls shape(), but you can reimplement it in a
|
|
4523 |
subclass to provide a (perhaps more efficient) implementation.
|
|
4524 |
|
|
4525 |
\sa shape(), boundingRect(), collidesWithPath()
|
|
4526 |
*/
|
|
4527 |
bool QGraphicsItem::contains(const QPointF &point) const
|
|
4528 |
{
|
|
4529 |
return isClipped() ? clipPath().contains(point) : shape().contains(point);
|
|
4530 |
}
|
|
4531 |
|
|
4532 |
/*!
|
|
4533 |
|
|
4534 |
Returns true if this item collides with \a other; otherwise
|
|
4535 |
returns false.
|
|
4536 |
|
|
4537 |
The \a mode is applied to \a other, and the resulting shape or
|
|
4538 |
bounding rectangle is then compared to this item's shape. The
|
|
4539 |
default value for \a mode is Qt::IntersectsItemShape; \a other
|
|
4540 |
collides with this item if it either intersects, contains, or is
|
|
4541 |
contained by this item's shape (see Qt::ItemSelectionMode for
|
|
4542 |
details).
|
|
4543 |
|
|
4544 |
The default implementation is based on shape intersection, and it calls
|
|
4545 |
shape() on both items. Because the complexity of arbitrary shape-shape
|
|
4546 |
intersection grows with an order of magnitude when the shapes are complex,
|
|
4547 |
this operation can be noticably time consuming. You have the option of
|
|
4548 |
reimplementing this function in a subclass of QGraphicsItem to provide a
|
|
4549 |
custom algorithm. This allows you to make use of natural constraints in
|
|
4550 |
the shapes of your own items, in order to improve the performance of the
|
|
4551 |
collision detection. For instance, two untransformed perfectly circular
|
|
4552 |
items' collision can be determined very efficiently by comparing their
|
|
4553 |
positions and radii.
|
|
4554 |
|
|
4555 |
Keep in mind that when reimplementing this function and calling shape() or
|
|
4556 |
boundingRect() on \a other, the returned coordinates must be mapped to
|
|
4557 |
this item's coordinate system before any intersection can take place.
|
|
4558 |
|
|
4559 |
\sa contains(), shape()
|
|
4560 |
*/
|
|
4561 |
bool QGraphicsItem::collidesWithItem(const QGraphicsItem *other, Qt::ItemSelectionMode mode) const
|
|
4562 |
{
|
|
4563 |
if (other == this)
|
|
4564 |
return true;
|
|
4565 |
if (!other)
|
|
4566 |
return false;
|
|
4567 |
// The items share the same clip if their closest clipper is the same, or
|
|
4568 |
// if one clips the other.
|
|
4569 |
bool clips = (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
|
|
4570 |
bool otherClips = (other->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren);
|
|
4571 |
if (clips || otherClips) {
|
|
4572 |
const QGraphicsItem *closestClipper = isAncestorOf(other) ? this : parentItem();
|
|
4573 |
while (closestClipper && !(closestClipper->flags() & ItemClipsChildrenToShape))
|
|
4574 |
closestClipper = closestClipper->parentItem();
|
|
4575 |
const QGraphicsItem *otherClosestClipper = other->isAncestorOf(this) ? other : other->parentItem();
|
|
4576 |
while (otherClosestClipper && !(otherClosestClipper->flags() & ItemClipsChildrenToShape))
|
|
4577 |
otherClosestClipper = otherClosestClipper->parentItem();
|
|
4578 |
if (closestClipper == otherClosestClipper) {
|
|
4579 |
d_ptr->localCollisionHack = 1;
|
|
4580 |
bool res = collidesWithPath(mapFromItem(other, other->shape()), mode);
|
|
4581 |
d_ptr->localCollisionHack = 0;
|
|
4582 |
return res;
|
|
4583 |
}
|
|
4584 |
}
|
|
4585 |
|
|
4586 |
QPainterPath otherShape = other->isClipped() ? other->clipPath() : other->shape();
|
|
4587 |
return collidesWithPath(mapFromItem(other, otherShape), mode);
|
|
4588 |
}
|
|
4589 |
|
|
4590 |
/*!
|
|
4591 |
Returns true if this item collides with \a path.
|
|
4592 |
|
|
4593 |
The collision is determined by \a mode. The default value for \a mode is
|
|
4594 |
Qt::IntersectsItemShape; \a path collides with this item if it either
|
|
4595 |
intersects, contains, or is contained by this item's shape.
|
|
4596 |
|
|
4597 |
Note that this function checks whether the item's shape or
|
|
4598 |
bounding rectangle (depending on \a mode) is contained within \a
|
|
4599 |
path, and not whether \a path is contained within the items shape
|
|
4600 |
or bounding rectangle.
|
|
4601 |
|
|
4602 |
\sa collidesWithItem(), contains(), shape()
|
|
4603 |
*/
|
|
4604 |
bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelectionMode mode) const
|
|
4605 |
{
|
|
4606 |
if (path.isEmpty()) {
|
|
4607 |
// No collision with empty paths.
|
|
4608 |
return false;
|
|
4609 |
}
|
|
4610 |
|
|
4611 |
QRectF rectA(boundingRect());
|
|
4612 |
_q_adjustRect(&rectA);
|
|
4613 |
QRectF rectB(path.controlPointRect());
|
|
4614 |
_q_adjustRect(&rectB);
|
|
4615 |
if (!rectA.intersects(rectB)) {
|
|
4616 |
// This we can determine efficiently. If the two rects neither
|
|
4617 |
// intersect nor contain eachother, then the two items do not collide.
|
|
4618 |
return false;
|
|
4619 |
}
|
|
4620 |
|
|
4621 |
// For further testing, we need this item's shape or bounding rect.
|
|
4622 |
QPainterPath thisShape;
|
|
4623 |
if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape)
|
|
4624 |
thisShape = (isClipped() && !d_ptr->localCollisionHack) ? clipPath() : shape();
|
|
4625 |
else
|
|
4626 |
thisShape.addRect(rectA);
|
|
4627 |
|
|
4628 |
if (thisShape == QPainterPath()) {
|
|
4629 |
// Empty shape? No collision.
|
|
4630 |
return false;
|
|
4631 |
}
|
|
4632 |
|
|
4633 |
// Use QPainterPath boolean operations to determine the collision, O(N*logN).
|
|
4634 |
if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
|
|
4635 |
return path.intersects(thisShape);
|
|
4636 |
return path.contains(thisShape);
|
|
4637 |
}
|
|
4638 |
|
|
4639 |
/*!
|
|
4640 |
Returns a list of all items that collide with this item.
|
|
4641 |
|
|
4642 |
The way collisions are detected is determined by applying \a mode
|
|
4643 |
to items that are compared to this item, i.e., each item's shape
|
|
4644 |
or bounding rectangle is checked against this item's shape. The
|
|
4645 |
default value for \a mode is Qt::IntersectsItemShape.
|
|
4646 |
|
|
4647 |
\sa collidesWithItem()
|
|
4648 |
*/
|
|
4649 |
QList<QGraphicsItem *> QGraphicsItem::collidingItems(Qt::ItemSelectionMode mode) const
|
|
4650 |
{
|
|
4651 |
if (d_ptr->scene)
|
|
4652 |
return d_ptr->scene->collidingItems(this, mode);
|
|
4653 |
return QList<QGraphicsItem *>();
|
|
4654 |
}
|
|
4655 |
|
|
4656 |
/*!
|
|
4657 |
Returns true if this item's bounding rect is completely obscured by the
|
|
4658 |
opaque shape of any of colliding items above it (i.e., with a higher Z
|
|
4659 |
value than this item).
|
|
4660 |
|
|
4661 |
Its implementation is based on calling isObscuredBy(), which you can
|
|
4662 |
reimplement to provide a custom obscurity algorithm.
|
|
4663 |
|
|
4664 |
\sa opaqueArea()
|
|
4665 |
*/
|
|
4666 |
bool QGraphicsItem::isObscured() const
|
|
4667 |
{
|
|
4668 |
return isObscured(QRectF());
|
|
4669 |
}
|
|
4670 |
|
|
4671 |
/*!
|
|
4672 |
\internal
|
|
4673 |
|
|
4674 |
Item obscurity helper function.
|
|
4675 |
|
|
4676 |
Returns true if the subrect \a rect of \a item's bounding rect is obscured
|
|
4677 |
by \a other (i.e., \a other's opaque area covers \a item's \a rect
|
|
4678 |
completely. \a other is assumed to already be "on top of" \a item
|
|
4679 |
wrt. stacking order.
|
|
4680 |
*/
|
|
4681 |
static bool qt_QGraphicsItem_isObscured(const QGraphicsItem *item,
|
|
4682 |
const QGraphicsItem *other,
|
|
4683 |
const QRectF &rect)
|
|
4684 |
{
|
|
4685 |
return other->mapToItem(item, other->opaqueArea()).contains(rect);
|
|
4686 |
}
|
|
4687 |
|
|
4688 |
/*!
|
|
4689 |
\overload
|
|
4690 |
\since 4.3
|
|
4691 |
|
|
4692 |
Returns true if \a rect is completely obscured by the opaque shape of any
|
|
4693 |
of colliding items above it (i.e., with a higher Z value than this item).
|
|
4694 |
|
|
4695 |
Unlike the default isObscured() function, this function does not call
|
|
4696 |
isObscuredBy().
|
|
4697 |
|
|
4698 |
\sa opaqueArea()
|
|
4699 |
*/
|
|
4700 |
bool QGraphicsItem::isObscured(const QRectF &rect) const
|
|
4701 |
{
|
|
4702 |
Q_D(const QGraphicsItem);
|
|
4703 |
if (!d->scene)
|
|
4704 |
return false;
|
|
4705 |
|
|
4706 |
QRectF br = boundingRect();
|
|
4707 |
QRectF testRect = rect.isNull() ? br : rect;
|
|
4708 |
|
|
4709 |
foreach (QGraphicsItem *item, d->scene->items(mapToScene(br), Qt::IntersectsItemBoundingRect)) {
|
|
4710 |
if (item == this)
|
|
4711 |
break;
|
|
4712 |
if (qt_QGraphicsItem_isObscured(this, item, testRect))
|
|
4713 |
return true;
|
|
4714 |
}
|
|
4715 |
return false;
|
|
4716 |
}
|
|
4717 |
|
|
4718 |
/*!
|
|
4719 |
\fn bool QGraphicsItem::isObscured(qreal x, qreal y, qreal w, qreal h) const
|
|
4720 |
\since 4.3
|
|
4721 |
|
|
4722 |
This convenience function is equivalent to calling isObscured(QRectF(\a x, \a y, \a w, \a h)).
|
|
4723 |
*/
|
|
4724 |
|
|
4725 |
/*!
|
|
4726 |
Returns true if this item's bounding rect is completely obscured by the
|
|
4727 |
opaque shape of \a item.
|
|
4728 |
|
|
4729 |
The base implementation maps \a item's opaqueArea() to this item's
|
|
4730 |
coordinate system, and then checks if this item's boundingRect() is fully
|
|
4731 |
contained within the mapped shape.
|
|
4732 |
|
|
4733 |
You can reimplement this function to provide a custom algorithm for
|
|
4734 |
determining whether this item is obscured by \a item.
|
|
4735 |
|
|
4736 |
\sa opaqueArea(), isObscured()
|
|
4737 |
*/
|
|
4738 |
bool QGraphicsItem::isObscuredBy(const QGraphicsItem *item) const
|
|
4739 |
{
|
|
4740 |
if (!item)
|
|
4741 |
return false;
|
|
4742 |
return qt_closestItemFirst(item, this)
|
|
4743 |
&& qt_QGraphicsItem_isObscured(this, item, boundingRect());
|
|
4744 |
}
|
|
4745 |
|
|
4746 |
/*!
|
|
4747 |
This virtual function returns a shape representing the area where this
|
|
4748 |
item is opaque. An area is opaque if it is filled using an opaque brush or
|
|
4749 |
color (i.e., not transparent).
|
|
4750 |
|
|
4751 |
This function is used by isObscuredBy(), which is called by underlying
|
|
4752 |
items to determine if they are obscured by this item.
|
|
4753 |
|
|
4754 |
The default implementation returns an empty QPainterPath, indicating that
|
|
4755 |
this item is completely transparent and does not obscure any other items.
|
|
4756 |
|
|
4757 |
\sa isObscuredBy(), isObscured(), shape()
|
|
4758 |
*/
|
|
4759 |
QPainterPath QGraphicsItem::opaqueArea() const
|
|
4760 |
{
|
|
4761 |
return QPainterPath();
|
|
4762 |
}
|
|
4763 |
|
|
4764 |
/*!
|
|
4765 |
\since 4.4
|
|
4766 |
|
|
4767 |
Returns the bounding region for this item. The coordinate space of the
|
|
4768 |
returned region depends on \a itemToDeviceTransform. If you pass an
|
|
4769 |
identity QTransform as a parameter, this function will return a local
|
|
4770 |
coordinate region.
|
|
4771 |
|
|
4772 |
The bounding region describes a coarse outline of the item's visual
|
|
4773 |
contents. Although it's expensive to calculate, it's also more precise
|
|
4774 |
than boundingRect(), and it can help to avoid unnecessary repainting when
|
|
4775 |
an item is updated. This is particularily efficient for thin items (e.g.,
|
|
4776 |
lines or simple polygons). You can tune the granularity for the bounding
|
|
4777 |
region by calling setBoundingRegionGranularity(). The default granularity
|
|
4778 |
is 0; in which the item's bounding region is the same as its bounding
|
|
4779 |
rect.
|
|
4780 |
|
|
4781 |
\a itemToDeviceTransform is the transformation from item coordinates to
|
|
4782 |
device coordinates. If you want this function to return a QRegion in scene
|
|
4783 |
coordinates, you can pass sceneTransform() as an argument.
|
|
4784 |
|
|
4785 |
\sa boundingRegionGranularity()
|
|
4786 |
*/
|
|
4787 |
QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) const
|
|
4788 |
{
|
|
4789 |
// ### Ideally we would have a better way to generate this region,
|
|
4790 |
// preferably something in the lines of QPainterPath::toRegion(QTransform)
|
|
4791 |
// coupled with a way to generate a painter path from a set of painter
|
|
4792 |
// operations (e.g., QPicture::toPainterPath() or so). The current
|
|
4793 |
// approach generates a bitmap with the size of the item's bounding rect
|
|
4794 |
// in device coordinates, scaled by b.r.granularity, then paints the item
|
|
4795 |
// into the bitmap, converts the result to a QRegion and scales the region
|
|
4796 |
// back to device space with inverse granularity.
|
|
4797 |
qreal granularity = boundingRegionGranularity();
|
|
4798 |
QRect deviceRect = itemToDeviceTransform.mapRect(boundingRect()).toRect();
|
|
4799 |
_q_adjustRect(&deviceRect);
|
|
4800 |
if (granularity == 0.0)
|
|
4801 |
return QRegion(deviceRect);
|
|
4802 |
|
|
4803 |
int pad = 1;
|
|
4804 |
QSize bitmapSize(qMax(1, int(deviceRect.width() * granularity) + pad * 2),
|
|
4805 |
qMax(1, int(deviceRect.height() * granularity) + pad * 2));
|
|
4806 |
QImage mask(bitmapSize, QImage::Format_ARGB32_Premultiplied);
|
|
4807 |
mask.fill(0);
|
|
4808 |
QPainter p(&mask);
|
|
4809 |
p.setRenderHints(QPainter::Antialiasing);
|
|
4810 |
|
|
4811 |
// Transform painter (### this code is from QGraphicsScene::drawItemHelper
|
|
4812 |
// and doesn't work properly with perspective transformations).
|
|
4813 |
QPointF viewOrigo = itemToDeviceTransform.map(QPointF(0, 0));
|
|
4814 |
QPointF offset = viewOrigo - deviceRect.topLeft();
|
|
4815 |
p.scale(granularity, granularity);
|
|
4816 |
p.translate(offset);
|
|
4817 |
p.translate(pad, pad);
|
|
4818 |
p.setWorldTransform(itemToDeviceTransform, true);
|
|
4819 |
p.translate(itemToDeviceTransform.inverted().map(QPointF(0, 0)));
|
|
4820 |
|
|
4821 |
// Render
|
|
4822 |
QStyleOptionGraphicsItem option;
|
|
4823 |
const_cast<QGraphicsItem *>(this)->paint(&p, &option, 0);
|
|
4824 |
p.end();
|
|
4825 |
|
|
4826 |
// Transform QRegion back to device space
|
|
4827 |
QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity);
|
|
4828 |
QRegion r;
|
|
4829 |
QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0));
|
|
4830 |
foreach (const QRect &rect, QRegion( colorMask ).rects()) {
|
|
4831 |
QRect xrect = unscale.mapRect(rect).translated(deviceRect.topLeft() - QPoint(pad, pad));
|
|
4832 |
r += xrect.adjusted(-1, -1, 1, 1) & deviceRect;
|
|
4833 |
}
|
|
4834 |
return r;
|
|
4835 |
}
|
|
4836 |
|
|
4837 |
/*!
|
|
4838 |
\since 4.4
|
|
4839 |
|
|
4840 |
Returns the item's bounding region granularity; a value between and
|
|
4841 |
including 0 and 1. The default value is 0 (i.e., the lowest granularity,
|
|
4842 |
where the bounding region corresponds to the item's bounding rectangle).
|
|
4843 |
|
|
4844 |
\omit
|
|
4845 |
### NOTE
|
|
4846 |
\endomit
|
|
4847 |
|
|
4848 |
\sa setBoundingRegionGranularity()
|
|
4849 |
*/
|
|
4850 |
qreal QGraphicsItem::boundingRegionGranularity() const
|
|
4851 |
{
|
|
4852 |
return d_ptr->hasBoundingRegionGranularity
|
|
4853 |
? qVariantValue<qreal>(d_ptr->extra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity))
|
|
4854 |
: 0;
|
|
4855 |
}
|
|
4856 |
|
|
4857 |
/*!
|
|
4858 |
\since 4.4
|
|
4859 |
Sets the bounding region granularity to \a granularity; a value between
|
|
4860 |
and including 0 and 1. The default value is 0 (i.e., the lowest
|
|
4861 |
granularity, where the bounding region corresponds to the item's bounding
|
|
4862 |
rectangle).
|
|
4863 |
|
|
4864 |
The granularity is used by boundingRegion() to calculate how fine the
|
|
4865 |
bounding region of the item should be. The highest achievable granularity
|
|
4866 |
is 1, where boundingRegion() will return the finest outline possible for
|
|
4867 |
the respective device (e.g., for a QGraphicsView viewport, this gives you
|
|
4868 |
a pixel-perfect bounding region). The lowest possible granularity is
|
|
4869 |
0. The value of \a granularity describes the ratio between device
|
|
4870 |
resolution and the resolution of the bounding region (e.g., a value of
|
|
4871 |
0.25 will provide a region where each chunk corresponds to 4x4 device
|
|
4872 |
units / pixels).
|
|
4873 |
|
|
4874 |
\sa boundingRegionGranularity()
|
|
4875 |
*/
|
|
4876 |
void QGraphicsItem::setBoundingRegionGranularity(qreal granularity)
|
|
4877 |
{
|
|
4878 |
if (granularity < 0.0 || granularity > 1.0) {
|
|
4879 |
qWarning("QGraphicsItem::setBoundingRegionGranularity: invalid granularity %g", granularity);
|
|
4880 |
return;
|
|
4881 |
}
|
|
4882 |
if (granularity == 0.0) {
|
|
4883 |
d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity);
|
|
4884 |
d_ptr->hasBoundingRegionGranularity = 0;
|
|
4885 |
return;
|
|
4886 |
}
|
|
4887 |
d_ptr->hasBoundingRegionGranularity = 1;
|
|
4888 |
d_ptr->setExtra(QGraphicsItemPrivate::ExtraBoundingRegionGranularity,
|
|
4889 |
qVariantFromValue<qreal>(granularity));
|
|
4890 |
}
|
|
4891 |
|
|
4892 |
/*!
|
|
4893 |
\fn virtual void QGraphicsItem::paint(QPainter *painter, const
|
|
4894 |
QStyleOptionGraphicsItem *option, QWidget *widget = 0) = 0
|
|
4895 |
|
|
4896 |
This function, which is usually called by QGraphicsView, paints the
|
|
4897 |
contents of an item in local coordinates.
|
|
4898 |
|
|
4899 |
Reimplement this function in a QGraphicsItem subclass to provide the
|
|
4900 |
item's painting implementation, using \a painter. The \a option parameter
|
|
4901 |
provides style options for the item, such as its state, exposed area and
|
|
4902 |
its level-of-detail hints. The \a widget argument is optional. If
|
|
4903 |
provided, it points to the widget that is being painted on; otherwise, it
|
|
4904 |
is 0. For cached painting, \a widget is always 0.
|
|
4905 |
|
|
4906 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 10
|
|
4907 |
|
|
4908 |
The painter's pen is 0-width by default, and its pen is initialized to the
|
|
4909 |
QPalette::Text brush from the paint device's palette. The brush is
|
|
4910 |
initialized to QPalette::Window.
|
|
4911 |
|
|
4912 |
Make sure to constrain all painting inside the boundaries of
|
|
4913 |
boundingRect() to avoid rendering artifacts (as QGraphicsView does not
|
|
4914 |
clip the painter for you). In particular, when QPainter renders the
|
|
4915 |
outline of a shape using an assigned QPen, half of the outline will be
|
|
4916 |
drawn outside, and half inside, the shape you're rendering (e.g., with a
|
|
4917 |
pen width of 2 units, you must draw outlines 1 unit inside
|
|
4918 |
boundingRect()). QGraphicsItem does not support use of cosmetic pens with
|
|
4919 |
a non-zero width.
|
|
4920 |
|
|
4921 |
All painting is done in local coordinates.
|
|
4922 |
|
|
4923 |
\sa setCacheMode(), QPen::width(), {Item Coordinates}, ItemUsesExtendedStyleOption
|
|
4924 |
*/
|
|
4925 |
|
|
4926 |
/*!
|
|
4927 |
\internal
|
|
4928 |
Returns true if we can discard an update request; otherwise false.
|
|
4929 |
*/
|
|
4930 |
bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, bool ignoreVisibleBit,
|
|
4931 |
bool ignoreDirtyBit, bool ignoreOpacity) const
|
|
4932 |
{
|
|
4933 |
// No scene, or if the scene is updating everything, means we have nothing
|
|
4934 |
// to do. The only exception is if the scene tracks the growing scene rect.
|
|
4935 |
return !scene
|
|
4936 |
|| (!visible && !ignoreVisibleBit && !this->ignoreVisible)
|
|
4937 |
|| (!ignoreDirtyBit && fullUpdatePending)
|
|
4938 |
|| (!ignoreClipping && (childrenClippedToShape() && isClippedAway()))
|
|
4939 |
|| (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent());
|
|
4940 |
}
|
|
4941 |
|
|
4942 |
/*!
|
|
4943 |
\internal
|
|
4944 |
*/
|
|
4945 |
int QGraphicsItemPrivate::depth() const
|
|
4946 |
{
|
|
4947 |
if (itemDepth == -1)
|
|
4948 |
const_cast<QGraphicsItemPrivate *>(this)->resolveDepth();
|
|
4949 |
|
|
4950 |
return itemDepth;
|
|
4951 |
}
|
|
4952 |
|
|
4953 |
/*!
|
|
4954 |
\internal
|
|
4955 |
*/
|
|
4956 |
void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively()
|
|
4957 |
{
|
|
4958 |
QGraphicsItemPrivate *itemPrivate = this;
|
|
4959 |
do {
|
|
4960 |
if (itemPrivate->graphicsEffect) {
|
|
4961 |
itemPrivate->notifyInvalidated = 1;
|
|
4962 |
|
|
4963 |
if (!itemPrivate->updateDueToGraphicsEffect)
|
|
4964 |
static_cast<QGraphicsItemEffectSourcePrivate *>(itemPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache();
|
|
4965 |
}
|
|
4966 |
} while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0));
|
|
4967 |
}
|
|
4968 |
|
|
4969 |
/*!
|
|
4970 |
\internal
|
|
4971 |
*/
|
|
4972 |
void QGraphicsItemPrivate::invalidateDepthRecursively()
|
|
4973 |
{
|
|
4974 |
if (itemDepth == -1)
|
|
4975 |
return;
|
|
4976 |
|
|
4977 |
itemDepth = -1;
|
|
4978 |
for (int i = 0; i < children.size(); ++i)
|
|
4979 |
children.at(i)->d_ptr->invalidateDepthRecursively();
|
|
4980 |
}
|
|
4981 |
|
|
4982 |
/*!
|
|
4983 |
\internal
|
|
4984 |
|
|
4985 |
Resolves the stacking depth of this object and all its ancestors.
|
|
4986 |
*/
|
|
4987 |
void QGraphicsItemPrivate::resolveDepth()
|
|
4988 |
{
|
|
4989 |
if (!parent)
|
|
4990 |
itemDepth = 0;
|
|
4991 |
else {
|
|
4992 |
if (parent->d_ptr->itemDepth == -1)
|
|
4993 |
parent->d_ptr->resolveDepth();
|
|
4994 |
itemDepth = parent->d_ptr->itemDepth + 1;
|
|
4995 |
}
|
|
4996 |
}
|
|
4997 |
|
|
4998 |
/*!
|
|
4999 |
\internal
|
|
5000 |
|
|
5001 |
### This function is almost identical to
|
|
5002 |
QGraphicsScenePrivate::registerTopLevelItem().
|
|
5003 |
*/
|
|
5004 |
void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
|
|
5005 |
{
|
|
5006 |
// Remove all holes from the sibling index list. Now the max index
|
|
5007 |
// number is equal to the size of the children list.
|
|
5008 |
ensureSequentialSiblingIndex();
|
|
5009 |
needSortChildren = 1; // ### maybe 0
|
|
5010 |
child->d_ptr->siblingIndex = children.size();
|
|
5011 |
children.append(child);
|
|
5012 |
}
|
|
5013 |
|
|
5014 |
/*!
|
|
5015 |
\internal
|
|
5016 |
|
|
5017 |
### This function is almost identical to
|
|
5018 |
QGraphicsScenePrivate::unregisterTopLevelItem().
|
|
5019 |
*/
|
|
5020 |
void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
|
|
5021 |
{
|
|
5022 |
// When removing elements in the middle of the children list,
|
|
5023 |
// there will be a "gap" in the list of sibling indexes (0,1,3,4).
|
|
5024 |
if (!holesInSiblingIndex)
|
|
5025 |
holesInSiblingIndex = child->d_ptr->siblingIndex != children.size() - 1;
|
|
5026 |
if (sequentialOrdering && !holesInSiblingIndex)
|
|
5027 |
children.removeAt(child->d_ptr->siblingIndex);
|
|
5028 |
else
|
|
5029 |
children.removeOne(child);
|
|
5030 |
// NB! Do not use children.removeAt(child->d_ptr->siblingIndex) because
|
|
5031 |
// the child is not guaranteed to be at the index after the list is sorted.
|
|
5032 |
// (see ensureSortedChildren()).
|
|
5033 |
child->d_ptr->siblingIndex = -1;
|
|
5034 |
}
|
|
5035 |
|
|
5036 |
/*!
|
|
5037 |
\internal
|
|
5038 |
*/
|
|
5039 |
QGraphicsItemCache *QGraphicsItemPrivate::maybeExtraItemCache() const
|
|
5040 |
{
|
|
5041 |
return (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
|
|
5042 |
}
|
|
5043 |
|
|
5044 |
/*!
|
|
5045 |
\internal
|
|
5046 |
*/
|
|
5047 |
QGraphicsItemCache *QGraphicsItemPrivate::extraItemCache() const
|
|
5048 |
{
|
|
5049 |
QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
|
|
5050 |
if (!c) {
|
|
5051 |
QGraphicsItemPrivate *that = const_cast<QGraphicsItemPrivate *>(this);
|
|
5052 |
c = new QGraphicsItemCache;
|
|
5053 |
that->setExtra(ExtraCacheData, qVariantFromValue<void *>(c));
|
|
5054 |
}
|
|
5055 |
return c;
|
|
5056 |
}
|
|
5057 |
|
|
5058 |
/*!
|
|
5059 |
\internal
|
|
5060 |
*/
|
|
5061 |
void QGraphicsItemPrivate::removeExtraItemCache()
|
|
5062 |
{
|
|
5063 |
QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
|
|
5064 |
if (c) {
|
|
5065 |
c->purge();
|
|
5066 |
delete c;
|
|
5067 |
}
|
|
5068 |
unsetExtra(ExtraCacheData);
|
|
5069 |
}
|
|
5070 |
|
|
5071 |
void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect)
|
|
5072 |
{
|
|
5073 |
setEmptyCachedClipPath();
|
|
5074 |
|
|
5075 |
const bool checkRect = !emptyIfOutsideThisRect.isNull()
|
|
5076 |
&& !(flags & QGraphicsItem::ItemClipsChildrenToShape);
|
|
5077 |
for (int i = 0; i < children.size(); ++i) {
|
|
5078 |
if (!checkRect) {
|
|
5079 |
children.at(i)->d_ptr->setEmptyCachedClipPathRecursively();
|
|
5080 |
continue;
|
|
5081 |
}
|
|
5082 |
|
|
5083 |
QGraphicsItem *child = children.at(i);
|
|
5084 |
const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect);
|
|
5085 |
if (rect.intersects(child->boundingRect()))
|
|
5086 |
child->d_ptr->invalidateCachedClipPathRecursively(false, rect);
|
|
5087 |
else
|
|
5088 |
child->d_ptr->setEmptyCachedClipPathRecursively(rect);
|
|
5089 |
}
|
|
5090 |
}
|
|
5091 |
|
|
5092 |
void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly, const QRectF &emptyIfOutsideThisRect)
|
|
5093 |
{
|
|
5094 |
if (!childrenOnly)
|
|
5095 |
invalidateCachedClipPath();
|
|
5096 |
|
|
5097 |
const bool checkRect = !emptyIfOutsideThisRect.isNull();
|
|
5098 |
for (int i = 0; i < children.size(); ++i) {
|
|
5099 |
if (!checkRect) {
|
|
5100 |
children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false);
|
|
5101 |
continue;
|
|
5102 |
}
|
|
5103 |
|
|
5104 |
QGraphicsItem *child = children.at(i);
|
|
5105 |
const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect);
|
|
5106 |
if (rect.intersects(child->boundingRect()))
|
|
5107 |
child->d_ptr->invalidateCachedClipPathRecursively(false, rect);
|
|
5108 |
else
|
|
5109 |
child->d_ptr->setEmptyCachedClipPathRecursively(rect);
|
|
5110 |
}
|
|
5111 |
}
|
|
5112 |
|
|
5113 |
void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &newPos)
|
|
5114 |
{
|
|
5115 |
Q_ASSERT(inSetPosHelper);
|
|
5116 |
|
|
5117 |
if (inDestructor || !(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren))
|
|
5118 |
return; // Not clipped by any ancestor.
|
|
5119 |
|
|
5120 |
// Find closest clip ancestor and transform.
|
|
5121 |
Q_Q(QGraphicsItem);
|
|
5122 |
// COMBINE
|
|
5123 |
QTransform thisToParentTransform = QTransform::fromTranslate(newPos.x(), newPos.y());
|
|
5124 |
if (transformData)
|
|
5125 |
thisToParentTransform = transformData->computedFullTransform(&thisToParentTransform);
|
|
5126 |
QGraphicsItem *clipParent = parent;
|
|
5127 |
while (clipParent && !clipParent->d_ptr->inDestructor && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) {
|
|
5128 |
thisToParentTransform *= clipParent->d_ptr->transformToParent();
|
|
5129 |
clipParent = clipParent->d_ptr->parent;
|
|
5130 |
}
|
|
5131 |
|
|
5132 |
// Ensure no parents are currently being deleted. This can only
|
|
5133 |
// happen if the item is moved by a dying ancestor.
|
|
5134 |
QGraphicsItem *p = clipParent;
|
|
5135 |
while (p) {
|
|
5136 |
if (p->d_ptr->inDestructor)
|
|
5137 |
return;
|
|
5138 |
p = p->d_ptr->parent;
|
|
5139 |
}
|
|
5140 |
|
|
5141 |
// From here everything is calculated in clip parent's coordinates.
|
|
5142 |
const QRectF parentBoundingRect(clipParent->boundingRect());
|
|
5143 |
const QRectF thisBoundingRect(thisToParentTransform.mapRect(q->boundingRect()));
|
|
5144 |
|
|
5145 |
if (!parentBoundingRect.intersects(thisBoundingRect)) {
|
|
5146 |
// Item is moved outside the clip parent's bounding rect,
|
|
5147 |
// i.e. it is fully clipped and the clip path is empty.
|
|
5148 |
if (flags & QGraphicsItem::ItemClipsChildrenToShape)
|
|
5149 |
setEmptyCachedClipPathRecursively();
|
|
5150 |
else
|
|
5151 |
setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentBoundingRect));
|
|
5152 |
return;
|
|
5153 |
}
|
|
5154 |
|
|
5155 |
const QPainterPath parentClip(clipParent->isClipped() ? clipParent->clipPath() : clipParent->shape());
|
|
5156 |
if (parentClip.contains(thisBoundingRect))
|
|
5157 |
return; // Item is inside the clip parent's shape. No update required.
|
|
5158 |
|
|
5159 |
const QRectF parentClipRect(parentClip.controlPointRect());
|
|
5160 |
if (!parentClipRect.intersects(thisBoundingRect)) {
|
|
5161 |
// Item is moved outside the clip parent's shape,
|
|
5162 |
// i.e. it is fully clipped and the clip path is empty.
|
|
5163 |
if (flags & QGraphicsItem::ItemClipsChildrenToShape)
|
|
5164 |
setEmptyCachedClipPathRecursively();
|
|
5165 |
else
|
|
5166 |
setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentClipRect));
|
|
5167 |
} else {
|
|
5168 |
// Item is partially inside the clip parent's shape,
|
|
5169 |
// i.e. the cached clip path must be invalidated.
|
|
5170 |
invalidateCachedClipPathRecursively(false, thisToParentTransform.inverted().mapRect(parentClipRect));
|
|
5171 |
}
|
|
5172 |
}
|
|
5173 |
|
|
5174 |
// Traverses all the ancestors up to the top-level and updates the pointer to
|
|
5175 |
// always point to the top-most item that has a dirty scene transform.
|
|
5176 |
// It then backtracks to the top-most dirty item and start calculating the
|
|
5177 |
// scene transform by combining the item's transform (+pos) with the parent's
|
|
5178 |
// cached scene transform (which we at this point know for sure is valid).
|
|
5179 |
void QGraphicsItemPrivate::ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem)
|
|
5180 |
{
|
|
5181 |
Q_ASSERT(topMostDirtyItem);
|
|
5182 |
|
|
5183 |
if (dirtySceneTransform)
|
|
5184 |
*topMostDirtyItem = q_ptr;
|
|
5185 |
|
|
5186 |
if (parent)
|
|
5187 |
parent->d_ptr->ensureSceneTransformRecursive(topMostDirtyItem);
|
|
5188 |
|
|
5189 |
if (*topMostDirtyItem == q_ptr) {
|
|
5190 |
if (!dirtySceneTransform)
|
|
5191 |
return; // OK, neither my ancestors nor I have dirty scene transforms.
|
|
5192 |
*topMostDirtyItem = 0;
|
|
5193 |
} else if (*topMostDirtyItem) {
|
|
5194 |
return; // Continue backtrack.
|
|
5195 |
}
|
|
5196 |
|
|
5197 |
// This item and all its descendants have dirty scene transforms.
|
|
5198 |
// We're about to validate this item's scene transform, so we have to
|
|
5199 |
// invalidate all the children; otherwise there's no way for the descendants
|
|
5200 |
// to detect that the ancestor has changed.
|
|
5201 |
invalidateChildrenSceneTransform();
|
|
5202 |
|
|
5203 |
// COMBINE my transform with the parent's scene transform.
|
|
5204 |
updateSceneTransformFromParent();
|
|
5205 |
Q_ASSERT(!dirtySceneTransform);
|
|
5206 |
}
|
|
5207 |
|
|
5208 |
/*!
|
|
5209 |
\internal
|
|
5210 |
*/
|
|
5211 |
void QGraphicsItemPrivate::setSubFocus(QGraphicsItem *rootItem)
|
|
5212 |
{
|
|
5213 |
// Update focus child chain. Stop at panels, or if this item
|
|
5214 |
// is hidden, stop at the first item with a visible parent.
|
|
5215 |
QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
|
|
5216 |
do {
|
|
5217 |
// Clear any existing ancestor's subFocusItem.
|
|
5218 |
if (parent != q_ptr && parent->d_ptr->subFocusItem) {
|
|
5219 |
if (parent->d_ptr->subFocusItem == q_ptr)
|
|
5220 |
break;
|
|
5221 |
parent->d_ptr->subFocusItem->d_ptr->clearSubFocus();
|
|
5222 |
}
|
|
5223 |
parent->d_ptr->subFocusItem = q_ptr;
|
|
5224 |
parent->d_ptr->subFocusItemChange();
|
|
5225 |
} while (!parent->isPanel() && (parent = parent->d_ptr->parent) && (visible || !parent->d_ptr->visible));
|
|
5226 |
|
|
5227 |
if (scene && !scene->isActive())
|
|
5228 |
scene->d_func()->lastFocusItem = subFocusItem;
|
|
5229 |
}
|
|
5230 |
|
|
5231 |
/*!
|
|
5232 |
\internal
|
|
5233 |
*/
|
|
5234 |
void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem)
|
|
5235 |
{
|
|
5236 |
// Reset sub focus chain.
|
|
5237 |
QGraphicsItem *parent = rootItem ? rootItem : q_ptr;
|
|
5238 |
do {
|
|
5239 |
if (parent->d_ptr->subFocusItem != q_ptr)
|
|
5240 |
break;
|
|
5241 |
parent->d_ptr->subFocusItem = 0;
|
|
5242 |
parent->d_ptr->subFocusItemChange();
|
|
5243 |
} while (!parent->isPanel() && (parent = parent->d_ptr->parent));
|
|
5244 |
}
|
|
5245 |
|
|
5246 |
/*!
|
|
5247 |
\internal
|
|
5248 |
|
|
5249 |
Sets the focusProxy pointer to 0 for all items that have this item as their
|
|
5250 |
focusProxy. ### Qt 5: Use QPointer instead.
|
|
5251 |
*/
|
|
5252 |
void QGraphicsItemPrivate::resetFocusProxy()
|
|
5253 |
{
|
|
5254 |
for (int i = 0; i < focusProxyRefs.size(); ++i)
|
|
5255 |
*focusProxyRefs.at(i) = 0;
|
|
5256 |
focusProxyRefs.clear();
|
|
5257 |
}
|
|
5258 |
|
|
5259 |
/*!
|
|
5260 |
\internal
|
|
5261 |
|
|
5262 |
Subclasses can reimplement this function to be notified when subFocusItem
|
|
5263 |
changes.
|
|
5264 |
*/
|
|
5265 |
void QGraphicsItemPrivate::subFocusItemChange()
|
|
5266 |
{
|
|
5267 |
}
|
|
5268 |
|
|
5269 |
/*!
|
|
5270 |
\internal
|
|
5271 |
|
|
5272 |
Tells us if it is a proxy widget
|
|
5273 |
*/
|
|
5274 |
bool QGraphicsItemPrivate::isProxyWidget() const
|
|
5275 |
{
|
|
5276 |
return false;
|
|
5277 |
}
|
|
5278 |
|
|
5279 |
/*!
|
|
5280 |
Schedules a redraw of the area covered by \a rect in this item. You can
|
|
5281 |
call this function whenever your item needs to be redrawn, such as if it
|
|
5282 |
changes appearance or size.
|
|
5283 |
|
|
5284 |
This function does not cause an immediate paint; instead it schedules a
|
|
5285 |
paint request that is processed by QGraphicsView after control reaches the
|
|
5286 |
event loop. The item will only be redrawn if it is visible in any
|
|
5287 |
associated view.
|
|
5288 |
|
|
5289 |
As a side effect of the item being repainted, other items that overlap the
|
|
5290 |
area \a rect may also be repainted.
|
|
5291 |
|
|
5292 |
If the item is invisible (i.e., isVisible() returns false), this function
|
|
5293 |
does nothing.
|
|
5294 |
|
|
5295 |
\sa paint(), boundingRect()
|
|
5296 |
*/
|
|
5297 |
void QGraphicsItem::update(const QRectF &rect)
|
|
5298 |
{
|
|
5299 |
if (rect.isEmpty() && !rect.isNull())
|
|
5300 |
return;
|
|
5301 |
|
|
5302 |
// Make sure we notify effects about invalidated source.
|
|
5303 |
d_ptr->invalidateGraphicsEffectsRecursively();
|
|
5304 |
|
|
5305 |
if (CacheMode(d_ptr->cacheMode) != NoCache) {
|
|
5306 |
// Invalidate cache.
|
|
5307 |
QGraphicsItemCache *cache = d_ptr->extraItemCache();
|
|
5308 |
if (!cache->allExposed) {
|
|
5309 |
if (rect.isNull()) {
|
|
5310 |
cache->allExposed = true;
|
|
5311 |
cache->exposed.clear();
|
|
5312 |
} else {
|
|
5313 |
cache->exposed.append(rect);
|
|
5314 |
}
|
|
5315 |
}
|
|
5316 |
// Only invalidate cache; item is already dirty.
|
|
5317 |
if (d_ptr->fullUpdatePending)
|
|
5318 |
return;
|
|
5319 |
}
|
|
5320 |
|
|
5321 |
if (d_ptr->discardUpdateRequest())
|
|
5322 |
return;
|
|
5323 |
|
|
5324 |
if (d_ptr->scene)
|
|
5325 |
d_ptr->scene->d_func()->markDirty(this, rect);
|
|
5326 |
}
|
|
5327 |
|
|
5328 |
/*!
|
|
5329 |
\since 4.4
|
|
5330 |
Scrolls the contents of \a rect by \a dx, \a dy. If \a rect is a null rect
|
|
5331 |
(the default), the item's bounding rect is scrolled.
|
|
5332 |
|
|
5333 |
Scrolling provides a fast alternative to simply redrawing when the
|
|
5334 |
contents of the item (or parts of the item) are shifted vertically or
|
|
5335 |
horizontally. Depending on the current transformation and the capabilities
|
|
5336 |
of the paint device (i.e., the viewport), this operation may consist of
|
|
5337 |
simply moving pixels from one location to another using memmove(). In most
|
|
5338 |
cases this is faster than rerendering the entire area.
|
|
5339 |
|
|
5340 |
After scrolling, the item will issue an update for the newly exposed
|
|
5341 |
areas. If scrolling is not supported (e.g., you are rendering to an OpenGL
|
|
5342 |
viewport, which does not benefit from scroll optimizations), this function
|
|
5343 |
is equivalent to calling update(\a rect).
|
|
5344 |
|
|
5345 |
\sa boundingRect()
|
|
5346 |
*/
|
|
5347 |
void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect)
|
|
5348 |
{
|
|
5349 |
Q_D(QGraphicsItem);
|
|
5350 |
if (dx == 0.0 && dy == 0.0)
|
|
5351 |
return;
|
|
5352 |
if (!d->scene)
|
|
5353 |
return;
|
|
5354 |
if (d->cacheMode != NoCache) {
|
|
5355 |
QGraphicsItemCache *c;
|
|
5356 |
bool scrollCache = qFuzzyIsNull(dx - int(dx)) && qFuzzyIsNull(dy - int(dy))
|
|
5357 |
&& (c = (QGraphicsItemCache *)qVariantValue<void *>(d_ptr->extra(QGraphicsItemPrivate::ExtraCacheData)))
|
|
5358 |
&& (d->cacheMode == ItemCoordinateCache && !c->fixedSize.isValid());
|
|
5359 |
if (scrollCache) {
|
|
5360 |
QPixmap pix;
|
|
5361 |
if (QPixmapCache::find(c->key, &pix)) {
|
|
5362 |
// Adjust with 2 pixel margin. Notice the loss of precision
|
|
5363 |
// when converting to QRect.
|
|
5364 |
int adjust = 2;
|
|
5365 |
QRectF br = boundingRect().adjusted(-adjust, -adjust, adjust, adjust);
|
|
5366 |
QRect irect = rect.toRect().translated(-br.x(), -br.y());
|
|
5367 |
|
|
5368 |
pix.scroll(dx, dy, irect);
|
|
5369 |
|
|
5370 |
QPixmapCache::replace(c->key, pix);
|
|
5371 |
|
|
5372 |
// Translate the existing expose.
|
|
5373 |
foreach (QRectF exposedRect, c->exposed)
|
|
5374 |
c->exposed += exposedRect.translated(dx, dy) & rect;
|
|
5375 |
|
|
5376 |
// Calculate exposure.
|
|
5377 |
QRegion exposed;
|
|
5378 |
QRect r = rect.toRect();
|
|
5379 |
exposed += r;
|
|
5380 |
exposed -= r.translated(dx, dy);
|
|
5381 |
foreach (QRect rect, exposed.rects())
|
|
5382 |
update(rect);
|
|
5383 |
d->scene->d_func()->markDirty(this);
|
|
5384 |
} else {
|
|
5385 |
update(rect);
|
|
5386 |
}
|
|
5387 |
} else {
|
|
5388 |
// ### This is very slow, and can be done much better. If the cache is
|
|
5389 |
// local and matches the below criteria for rotation and scaling, we
|
|
5390 |
// can easily scroll. And if the cache is in device coordinates, we
|
|
5391 |
// can scroll both the viewport and the cache.
|
|
5392 |
update(rect);
|
|
5393 |
}
|
|
5394 |
return;
|
|
5395 |
}
|
|
5396 |
|
|
5397 |
QRectF scrollRect = !rect.isNull() ? rect : boundingRect();
|
|
5398 |
int couldntScroll = d->scene->views().size();
|
|
5399 |
foreach (QGraphicsView *view, d->scene->views()) {
|
|
5400 |
if (view->viewport()->inherits("QGLWidget")) {
|
|
5401 |
// ### Please replace with a widget attribute; any widget that
|
|
5402 |
// doesn't support partial updates / doesn't support scrolling
|
|
5403 |
// should be skipped in this code. Qt::WA_NoPartialUpdates or so.
|
|
5404 |
continue;
|
|
5405 |
}
|
|
5406 |
|
|
5407 |
static const QLineF up(0, 0, 0, -1);
|
|
5408 |
static const QLineF down(0, 0, 0, 1);
|
|
5409 |
static const QLineF left(0, 0, -1, 0);
|
|
5410 |
static const QLineF right(0, 0, 1, 0);
|
|
5411 |
|
|
5412 |
QTransform deviceTr = deviceTransform(view->viewportTransform());
|
|
5413 |
QRect deviceScrollRect = deviceTr.mapRect(scrollRect).toRect();
|
|
5414 |
QLineF v1 = deviceTr.map(right);
|
|
5415 |
QLineF v2 = deviceTr.map(down);
|
|
5416 |
QLineF u1 = v1.unitVector(); u1.translate(-v1.p1());
|
|
5417 |
QLineF u2 = v2.unitVector(); u2.translate(-v2.p1());
|
|
5418 |
bool noScroll = false;
|
|
5419 |
|
|
5420 |
// Check if the delta resolves to ints in device space.
|
|
5421 |
QPointF deviceDelta = deviceTr.map(QPointF(dx, dy));
|
|
5422 |
if ((deviceDelta.x() - int(deviceDelta.x()))
|
|
5423 |
|| (deviceDelta.y() - int(deviceDelta.y()))) {
|
|
5424 |
noScroll = true;
|
|
5425 |
} else {
|
|
5426 |
// Check if the unit vectors have no fraction in device space.
|
|
5427 |
qreal v1l = v1.length();
|
|
5428 |
if (v1l - int(v1l)) {
|
|
5429 |
noScroll = true;
|
|
5430 |
} else {
|
|
5431 |
dx *= v1.length();
|
|
5432 |
}
|
|
5433 |
qreal v2l = v2.length();
|
|
5434 |
if (v2l - int(v2l)) {
|
|
5435 |
noScroll = true;
|
|
5436 |
} else {
|
|
5437 |
dy *= v2.length();
|
|
5438 |
}
|
|
5439 |
}
|
|
5440 |
|
|
5441 |
if (!noScroll) {
|
|
5442 |
if (u1 == right) {
|
|
5443 |
if (u2 == up) {
|
|
5444 |
// flipped
|
|
5445 |
dy = -dy;
|
|
5446 |
} else if (u2 == down) {
|
|
5447 |
// normal
|
|
5448 |
} else {
|
|
5449 |
noScroll = true;
|
|
5450 |
}
|
|
5451 |
} else if (u1 == left) {
|
|
5452 |
if (u2 == up) {
|
|
5453 |
// mirrored & flipped / rotated 180 degrees
|
|
5454 |
dx = -dx;
|
|
5455 |
dy = -dy;
|
|
5456 |
} else if (u2 == down) {
|
|
5457 |
// mirrored
|
|
5458 |
dx = -dx;
|
|
5459 |
} else {
|
|
5460 |
noScroll = true;
|
|
5461 |
}
|
|
5462 |
} else if (u1 == up) {
|
|
5463 |
if (u2 == left) {
|
|
5464 |
// rotated -90 & mirrored
|
|
5465 |
qreal tmp = dy;
|
|
5466 |
dy = -dx;
|
|
5467 |
dx = -tmp;
|
|
5468 |
} else if (u2 == right) {
|
|
5469 |
// rotated -90
|
|
5470 |
qreal tmp = dy;
|
|
5471 |
dy = -dx;
|
|
5472 |
dx = tmp;
|
|
5473 |
} else {
|
|
5474 |
noScroll = true;
|
|
5475 |
}
|
|
5476 |
} else if (u1 == down) {
|
|
5477 |
if (u2 == left) {
|
|
5478 |
// rotated 90
|
|
5479 |
qreal tmp = dy;
|
|
5480 |
dy = dx;
|
|
5481 |
dx = -tmp;
|
|
5482 |
} else if (u2 == right) {
|
|
5483 |
// rotated 90 & mirrored
|
|
5484 |
qreal tmp = dy;
|
|
5485 |
dy = dx;
|
|
5486 |
dx = tmp;
|
|
5487 |
} else {
|
|
5488 |
noScroll = true;
|
|
5489 |
}
|
|
5490 |
}
|
|
5491 |
}
|
|
5492 |
|
|
5493 |
if (!noScroll) {
|
|
5494 |
view->viewport()->scroll(int(dx), int(dy), deviceScrollRect);
|
|
5495 |
--couldntScroll;
|
|
5496 |
}
|
|
5497 |
}
|
|
5498 |
if (couldntScroll)
|
|
5499 |
update(rect);
|
|
5500 |
}
|
|
5501 |
|
|
5502 |
/*!
|
|
5503 |
\fn void QGraphicsItem::update(qreal x, qreal y, qreal width, qreal height)
|
|
5504 |
\overload
|
|
5505 |
|
|
5506 |
This convenience function is equivalent to calling update(QRectF(\a x, \a
|
|
5507 |
y, \a width, \a height)).
|
|
5508 |
*/
|
|
5509 |
|
|
5510 |
/*!
|
|
5511 |
Maps the point \a point, which is in this item's coordinate system, to \a
|
|
5512 |
item's coordinate system, and returns the mapped coordinate.
|
|
5513 |
|
|
5514 |
If \a item is 0, this function returns the same as mapToScene().
|
|
5515 |
|
|
5516 |
\sa itemTransform(), mapToParent(), mapToScene(), transform(), mapFromItem(), {The Graphics
|
|
5517 |
View Coordinate System}
|
|
5518 |
*/
|
|
5519 |
QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF &point) const
|
|
5520 |
{
|
|
5521 |
if (item)
|
|
5522 |
return itemTransform(item).map(point);
|
|
5523 |
return mapToScene(point);
|
|
5524 |
}
|
|
5525 |
|
|
5526 |
/*!
|
|
5527 |
\fn QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y) const
|
|
5528 |
\overload
|
|
5529 |
|
|
5530 |
This convenience function is equivalent to calling mapToItem(\a item,
|
|
5531 |
QPointF(\a x, \a y)).
|
|
5532 |
*/
|
|
5533 |
|
|
5534 |
/*!
|
|
5535 |
Maps the point \a point, which is in this item's coordinate system, to its
|
|
5536 |
parent's coordinate system, and returns the mapped coordinate. If the item
|
|
5537 |
has no parent, \a point will be mapped to the scene's coordinate system.
|
|
5538 |
|
|
5539 |
\sa mapToItem(), mapToScene(), transform(), mapFromParent(), {The Graphics
|
|
5540 |
View Coordinate System}
|
|
5541 |
*/
|
|
5542 |
QPointF QGraphicsItem::mapToParent(const QPointF &point) const
|
|
5543 |
{
|
|
5544 |
// COMBINE
|
|
5545 |
if (!d_ptr->transformData)
|
|
5546 |
return point + d_ptr->pos;
|
|
5547 |
return d_ptr->transformToParent().map(point);
|
|
5548 |
}
|
|
5549 |
|
|
5550 |
/*!
|
|
5551 |
\fn QPointF QGraphicsItem::mapToParent(qreal x, qreal y) const
|
|
5552 |
\overload
|
|
5553 |
|
|
5554 |
This convenience function is equivalent to calling mapToParent(QPointF(\a
|
|
5555 |
x, \a y)).
|
|
5556 |
*/
|
|
5557 |
|
|
5558 |
/*!
|
|
5559 |
Maps the point \a point, which is in this item's coordinate system, to the
|
|
5560 |
scene's coordinate system, and returns the mapped coordinate.
|
|
5561 |
|
|
5562 |
\sa mapToItem(), mapToParent(), transform(), mapFromScene(), {The Graphics
|
|
5563 |
View Coordinate System}
|
|
5564 |
*/
|
|
5565 |
QPointF QGraphicsItem::mapToScene(const QPointF &point) const
|
|
5566 |
{
|
|
5567 |
if (d_ptr->hasTranslateOnlySceneTransform())
|
|
5568 |
return QPointF(point.x() + d_ptr->sceneTransform.dx(), point.y() + d_ptr->sceneTransform.dy());
|
|
5569 |
return d_ptr->sceneTransform.map(point);
|
|
5570 |
}
|
|
5571 |
|
|
5572 |
/*!
|
|
5573 |
\fn QPointF QGraphicsItem::mapToScene(qreal x, qreal y) const
|
|
5574 |
\overload
|
|
5575 |
|
|
5576 |
This convenience function is equivalent to calling mapToScene(QPointF(\a
|
|
5577 |
x, \a y)).
|
|
5578 |
*/
|
|
5579 |
|
|
5580 |
/*!
|
|
5581 |
Maps the rectangle \a rect, which is in this item's coordinate system, to
|
|
5582 |
\a item's coordinate system, and returns the mapped rectangle as a polygon.
|
|
5583 |
|
|
5584 |
If \a item is 0, this function returns the same as mapToScene().
|
|
5585 |
|
|
5586 |
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
|
|
5587 |
Graphics View Coordinate System}
|
|
5588 |
*/
|
|
5589 |
QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect) const
|
|
5590 |
{
|
|
5591 |
if (item)
|
|
5592 |
return itemTransform(item).map(rect);
|
|
5593 |
return mapToScene(rect);
|
|
5594 |
}
|
|
5595 |
|
|
5596 |
/*!
|
|
5597 |
\fn QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
|
|
5598 |
\since 4.3
|
|
5599 |
|
|
5600 |
This convenience function is equivalent to calling mapToItem(item, QRectF(\a x, \a y, \a w, \a h)).
|
|
5601 |
*/
|
|
5602 |
|
|
5603 |
/*!
|
|
5604 |
Maps the rectangle \a rect, which is in this item's coordinate system, to
|
|
5605 |
its parent's coordinate system, and returns the mapped rectangle as a
|
|
5606 |
polygon. If the item has no parent, \a rect will be mapped to the scene's
|
|
5607 |
coordinate system.
|
|
5608 |
|
|
5609 |
\sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
|
|
5610 |
Coordinate System}
|
|
5611 |
*/
|
|
5612 |
QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const
|
|
5613 |
{
|
|
5614 |
// COMBINE
|
|
5615 |
if (!d_ptr->transformData)
|
|
5616 |
return rect.translated(d_ptr->pos);
|
|
5617 |
return d_ptr->transformToParent().map(rect);
|
|
5618 |
}
|
|
5619 |
|
|
5620 |
/*!
|
|
5621 |
\fn QPolygonF QGraphicsItem::mapToParent(qreal x, qreal y, qreal w, qreal h) const
|
|
5622 |
\since 4.3
|
|
5623 |
|
|
5624 |
This convenience function is equivalent to calling mapToParent(QRectF(\a x, \a y, \a w, \a h)).
|
|
5625 |
*/
|
|
5626 |
|
|
5627 |
/*!
|
|
5628 |
Maps the rectangle \a rect, which is in this item's coordinate system, to
|
|
5629 |
the scene's coordinate system, and returns the mapped rectangle as a polygon.
|
|
5630 |
|
|
5631 |
\sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
|
|
5632 |
Coordinate System}
|
|
5633 |
*/
|
|
5634 |
QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const
|
|
5635 |
{
|
|
5636 |
if (d_ptr->hasTranslateOnlySceneTransform())
|
|
5637 |
return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
|
|
5638 |
return d_ptr->sceneTransform.map(rect);
|
|
5639 |
}
|
|
5640 |
|
|
5641 |
/*!
|
|
5642 |
\fn QPolygonF QGraphicsItem::mapToScene(qreal x, qreal y, qreal w, qreal h) const
|
|
5643 |
\since 4.3
|
|
5644 |
|
|
5645 |
This convenience function is equivalent to calling mapToScene(QRectF(\a x, \a y, \a w, \a h)).
|
|
5646 |
*/
|
|
5647 |
|
|
5648 |
/*!
|
|
5649 |
\since 4.5
|
|
5650 |
|
|
5651 |
Maps the rectangle \a rect, which is in this item's coordinate system, to
|
|
5652 |
\a item's coordinate system, and returns the mapped rectangle as a new
|
|
5653 |
rectangle (i.e., the bounding rectangle of the resulting polygon).
|
|
5654 |
|
|
5655 |
If \a item is 0, this function returns the same as mapRectToScene().
|
|
5656 |
|
|
5657 |
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
|
|
5658 |
Graphics View Coordinate System}
|
|
5659 |
*/
|
|
5660 |
QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, const QRectF &rect) const
|
|
5661 |
{
|
|
5662 |
if (item)
|
|
5663 |
return itemTransform(item).mapRect(rect);
|
|
5664 |
return mapRectToScene(rect);
|
|
5665 |
}
|
|
5666 |
|
|
5667 |
/*!
|
|
5668 |
\fn QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
|
|
5669 |
\since 4.5
|
|
5670 |
|
|
5671 |
This convenience function is equivalent to calling mapRectToItem(item, QRectF(\a x, \a y, \a w, \a h)).
|
|
5672 |
*/
|
|
5673 |
|
|
5674 |
/*!
|
|
5675 |
\since 4.5
|
|
5676 |
|
|
5677 |
Maps the rectangle \a rect, which is in this item's coordinate system, to
|
|
5678 |
its parent's coordinate system, and returns the mapped rectangle as a new
|
|
5679 |
rectangle (i.e., the bounding rectangle of the resulting polygon).
|
|
5680 |
|
|
5681 |
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
|
|
5682 |
Graphics View Coordinate System}
|
|
5683 |
*/
|
|
5684 |
QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const
|
|
5685 |
{
|
|
5686 |
// COMBINE
|
|
5687 |
if (!d_ptr->transformData)
|
|
5688 |
return rect.translated(d_ptr->pos);
|
|
5689 |
return d_ptr->transformToParent().mapRect(rect);
|
|
5690 |
}
|
|
5691 |
|
|
5692 |
/*!
|
|
5693 |
\fn QRectF QGraphicsItem::mapRectToParent(qreal x, qreal y, qreal w, qreal h) const
|
|
5694 |
\since 4.5
|
|
5695 |
|
|
5696 |
This convenience function is equivalent to calling mapRectToParent(QRectF(\a x, \a y, \a w, \a h)).
|
|
5697 |
*/
|
|
5698 |
|
|
5699 |
/*!
|
|
5700 |
\since 4.5
|
|
5701 |
|
|
5702 |
Maps the rectangle \a rect, which is in this item's coordinate system, to
|
|
5703 |
the scene coordinate system, and returns the mapped rectangle as a new
|
|
5704 |
rectangle (i.e., the bounding rectangle of the resulting polygon).
|
|
5705 |
|
|
5706 |
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
|
|
5707 |
Graphics View Coordinate System}
|
|
5708 |
*/
|
|
5709 |
QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const
|
|
5710 |
{
|
|
5711 |
if (d_ptr->hasTranslateOnlySceneTransform())
|
|
5712 |
return rect.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
|
|
5713 |
return d_ptr->sceneTransform.mapRect(rect);
|
|
5714 |
}
|
|
5715 |
|
|
5716 |
/*!
|
|
5717 |
\fn QRectF QGraphicsItem::mapRectToScene(qreal x, qreal y, qreal w, qreal h) const
|
|
5718 |
\since 4.5
|
|
5719 |
|
|
5720 |
This convenience function is equivalent to calling mapRectToScene(QRectF(\a x, \a y, \a w, \a h)).
|
|
5721 |
*/
|
|
5722 |
|
|
5723 |
/*!
|
|
5724 |
\since 4.5
|
|
5725 |
|
|
5726 |
Maps the rectangle \a rect, which is in \a item's coordinate system, to
|
|
5727 |
this item's coordinate system, and returns the mapped rectangle as a new
|
|
5728 |
rectangle (i.e., the bounding rectangle of the resulting polygon).
|
|
5729 |
|
|
5730 |
If \a item is 0, this function returns the same as mapRectFromScene().
|
|
5731 |
|
|
5732 |
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
|
|
5733 |
Graphics View Coordinate System}
|
|
5734 |
*/
|
|
5735 |
QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, const QRectF &rect) const
|
|
5736 |
{
|
|
5737 |
if (item)
|
|
5738 |
return item->itemTransform(this).mapRect(rect);
|
|
5739 |
return mapRectFromScene(rect);
|
|
5740 |
}
|
|
5741 |
|
|
5742 |
/*!
|
|
5743 |
\fn QRectF QGraphicsItem::mapRectFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
|
|
5744 |
\since 4.5
|
|
5745 |
|
|
5746 |
This convenience function is equivalent to calling mapRectFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
|
|
5747 |
*/
|
|
5748 |
|
|
5749 |
/*!
|
|
5750 |
\since 4.5
|
|
5751 |
|
|
5752 |
Maps the rectangle \a rect, which is in this item's parent's coordinate
|
|
5753 |
system, to this item's coordinate system, and returns the mapped rectangle
|
|
5754 |
as a new rectangle (i.e., the bounding rectangle of the resulting
|
|
5755 |
polygon).
|
|
5756 |
|
|
5757 |
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
|
|
5758 |
Graphics View Coordinate System}
|
|
5759 |
*/
|
|
5760 |
QRectF QGraphicsItem::mapRectFromParent(const QRectF &rect) const
|
|
5761 |
{
|
|
5762 |
// COMBINE
|
|
5763 |
if (!d_ptr->transformData)
|
|
5764 |
return rect.translated(-d_ptr->pos);
|
|
5765 |
return d_ptr->transformToParent().inverted().mapRect(rect);
|
|
5766 |
}
|
|
5767 |
|
|
5768 |
/*!
|
|
5769 |
\fn QRectF QGraphicsItem::mapRectFromParent(qreal x, qreal y, qreal w, qreal h) const
|
|
5770 |
\since 4.5
|
|
5771 |
|
|
5772 |
This convenience function is equivalent to calling mapRectFromParent(QRectF(\a x, \a y, \a w, \a h)).
|
|
5773 |
*/
|
|
5774 |
|
|
5775 |
/*!
|
|
5776 |
\since 4.5
|
|
5777 |
|
|
5778 |
Maps the rectangle \a rect, which is in scene coordinates, to this item's
|
|
5779 |
coordinate system, and returns the mapped rectangle as a new rectangle
|
|
5780 |
(i.e., the bounding rectangle of the resulting polygon).
|
|
5781 |
|
|
5782 |
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
|
|
5783 |
Graphics View Coordinate System}
|
|
5784 |
*/
|
|
5785 |
QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const
|
|
5786 |
{
|
|
5787 |
if (d_ptr->hasTranslateOnlySceneTransform())
|
|
5788 |
return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
|
|
5789 |
return d_ptr->sceneTransform.inverted().mapRect(rect);
|
|
5790 |
}
|
|
5791 |
|
|
5792 |
/*!
|
|
5793 |
\fn QRectF QGraphicsItem::mapRectFromScene(qreal x, qreal y, qreal w, qreal h) const
|
|
5794 |
\since 4.5
|
|
5795 |
|
|
5796 |
This convenience function is equivalent to calling mapRectFromScene(QRectF(\a x, \a y, \a w, \a h)).
|
|
5797 |
*/
|
|
5798 |
|
|
5799 |
/*!
|
|
5800 |
Maps the polygon \a polygon, which is in this item's coordinate system, to
|
|
5801 |
\a item's coordinate system, and returns the mapped polygon.
|
|
5802 |
|
|
5803 |
If \a item is 0, this function returns the same as mapToScene().
|
|
5804 |
|
|
5805 |
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
|
|
5806 |
Graphics View Coordinate System}
|
|
5807 |
*/
|
|
5808 |
QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &polygon) const
|
|
5809 |
{
|
|
5810 |
if (item)
|
|
5811 |
return itemTransform(item).map(polygon);
|
|
5812 |
return mapToScene(polygon);
|
|
5813 |
}
|
|
5814 |
|
|
5815 |
/*!
|
|
5816 |
Maps the polygon \a polygon, which is in this item's coordinate system, to
|
|
5817 |
its parent's coordinate system, and returns the mapped polygon. If the
|
|
5818 |
item has no parent, \a polygon will be mapped to the scene's coordinate
|
|
5819 |
system.
|
|
5820 |
|
|
5821 |
\sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
|
|
5822 |
Coordinate System}
|
|
5823 |
*/
|
|
5824 |
QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const
|
|
5825 |
{
|
|
5826 |
// COMBINE
|
|
5827 |
if (!d_ptr->transformData)
|
|
5828 |
return polygon.translated(d_ptr->pos);
|
|
5829 |
return d_ptr->transformToParent().map(polygon);
|
|
5830 |
}
|
|
5831 |
|
|
5832 |
/*!
|
|
5833 |
Maps the polygon \a polygon, which is in this item's coordinate system, to
|
|
5834 |
the scene's coordinate system, and returns the mapped polygon.
|
|
5835 |
|
|
5836 |
\sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
|
|
5837 |
Coordinate System}
|
|
5838 |
*/
|
|
5839 |
QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const
|
|
5840 |
{
|
|
5841 |
if (d_ptr->hasTranslateOnlySceneTransform())
|
|
5842 |
return polygon.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
|
|
5843 |
return d_ptr->sceneTransform.map(polygon);
|
|
5844 |
}
|
|
5845 |
|
|
5846 |
/*!
|
|
5847 |
Maps the path \a path, which is in this item's coordinate system, to
|
|
5848 |
\a item's coordinate system, and returns the mapped path.
|
|
5849 |
|
|
5850 |
If \a item is 0, this function returns the same as mapToScene().
|
|
5851 |
|
|
5852 |
\sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The
|
|
5853 |
Graphics View Coordinate System}
|
|
5854 |
*/
|
|
5855 |
QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterPath &path) const
|
|
5856 |
{
|
|
5857 |
if (item)
|
|
5858 |
return itemTransform(item).map(path);
|
|
5859 |
return mapToScene(path);
|
|
5860 |
}
|
|
5861 |
|
|
5862 |
/*!
|
|
5863 |
Maps the path \a path, which is in this item's coordinate system, to
|
|
5864 |
its parent's coordinate system, and returns the mapped path. If the
|
|
5865 |
item has no parent, \a path will be mapped to the scene's coordinate
|
|
5866 |
system.
|
|
5867 |
|
|
5868 |
\sa mapToScene(), mapToItem(), mapFromParent(), {The Graphics View
|
|
5869 |
Coordinate System}
|
|
5870 |
*/
|
|
5871 |
QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const
|
|
5872 |
{
|
|
5873 |
// COMBINE
|
|
5874 |
if (!d_ptr->transformData)
|
|
5875 |
return path.translated(d_ptr->pos);
|
|
5876 |
return d_ptr->transformToParent().map(path);
|
|
5877 |
}
|
|
5878 |
|
|
5879 |
/*!
|
|
5880 |
Maps the path \a path, which is in this item's coordinate system, to
|
|
5881 |
the scene's coordinate system, and returns the mapped path.
|
|
5882 |
|
|
5883 |
\sa mapToParent(), mapToItem(), mapFromScene(), {The Graphics View
|
|
5884 |
Coordinate System}
|
|
5885 |
*/
|
|
5886 |
QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const
|
|
5887 |
{
|
|
5888 |
if (d_ptr->hasTranslateOnlySceneTransform())
|
|
5889 |
return path.translated(d_ptr->sceneTransform.dx(), d_ptr->sceneTransform.dy());
|
|
5890 |
return d_ptr->sceneTransform.map(path);
|
|
5891 |
}
|
|
5892 |
|
|
5893 |
/*!
|
|
5894 |
Maps the point \a point, which is in \a item's coordinate system, to this
|
|
5895 |
item's coordinate system, and returns the mapped coordinate.
|
|
5896 |
|
|
5897 |
If \a item is 0, this function returns the same as mapFromScene().
|
|
5898 |
|
|
5899 |
\sa itemTransform(), mapFromParent(), mapFromScene(), transform(), mapToItem(), {The Graphics
|
|
5900 |
View Coordinate System}
|
|
5901 |
*/
|
|
5902 |
QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPointF &point) const
|
|
5903 |
{
|
|
5904 |
if (item)
|
|
5905 |
return item->itemTransform(this).map(point);
|
|
5906 |
return mapFromScene(point);
|
|
5907 |
}
|
|
5908 |
|
|
5909 |
/*!
|
|
5910 |
\fn QPointF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y) const
|
|
5911 |
\overload
|
|
5912 |
|
|
5913 |
This convenience function is equivalent to calling mapFromItem(\a item,
|
|
5914 |
QPointF(\a x, \a y)).
|
|
5915 |
*/
|
|
5916 |
|
|
5917 |
/*!
|
|
5918 |
Maps the point \a point, which is in this item's parent's coordinate
|
|
5919 |
system, to this item's coordinate system, and returns the mapped
|
|
5920 |
coordinate.
|
|
5921 |
|
|
5922 |
\sa mapFromItem(), mapFromScene(), transform(), mapToParent(), {The Graphics
|
|
5923 |
View Coordinate System}
|
|
5924 |
*/
|
|
5925 |
QPointF QGraphicsItem::mapFromParent(const QPointF &point) const
|
|
5926 |
{
|
|
5927 |
// COMBINE
|
|
5928 |
if (d_ptr->transformData)
|
|
5929 |
return d_ptr->transformToParent().inverted().map(point);
|
|
5930 |
return point - d_ptr->pos;
|
|
5931 |
}
|
|
5932 |
|
|
5933 |
/*!
|
|
5934 |
\fn QPointF QGraphicsItem::mapFromParent(qreal x, qreal y) const
|
|
5935 |
\overload
|
|
5936 |
|
|
5937 |
This convenience function is equivalent to calling
|
|
5938 |
mapFromParent(QPointF(\a x, \a y)).
|
|
5939 |
*/
|
|
5940 |
|
|
5941 |
/*!
|
|
5942 |
Maps the point \a point, which is in this item's scene's coordinate
|
|
5943 |
system, to this item's coordinate system, and returns the mapped
|
|
5944 |
coordinate.
|
|
5945 |
|
|
5946 |
\sa mapFromItem(), mapFromParent(), transform(), mapToScene(), {The Graphics
|
|
5947 |
View Coordinate System}
|
|
5948 |
*/
|
|
5949 |
QPointF QGraphicsItem::mapFromScene(const QPointF &point) const
|
|
5950 |
{
|
|
5951 |
if (d_ptr->hasTranslateOnlySceneTransform())
|
|
5952 |
return QPointF(point.x() - d_ptr->sceneTransform.dx(), point.y() - d_ptr->sceneTransform.dy());
|
|
5953 |
return d_ptr->sceneTransform.inverted().map(point);
|
|
5954 |
}
|
|
5955 |
|
|
5956 |
/*!
|
|
5957 |
\fn QPointF QGraphicsItem::mapFromScene(qreal x, qreal y) const
|
|
5958 |
\overload
|
|
5959 |
|
|
5960 |
This convenience function is equivalent to calling mapFromScene(QPointF(\a
|
|
5961 |
x, \a y)).
|
|
5962 |
*/
|
|
5963 |
|
|
5964 |
/*!
|
|
5965 |
Maps the rectangle \a rect, which is in \a item's coordinate system, to
|
|
5966 |
this item's coordinate system, and returns the mapped rectangle as a
|
|
5967 |
polygon.
|
|
5968 |
|
|
5969 |
If \a item is 0, this function returns the same as mapFromScene()
|
|
5970 |
|
|
5971 |
\sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The Graphics View Coordinate
|
|
5972 |
System}
|
|
5973 |
*/
|
|
5974 |
QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QRectF &rect) const
|
|
5975 |
{
|
|
5976 |
if (item)
|
|
5977 |
return item->itemTransform(this).map(rect);
|
|
5978 |
return mapFromScene(rect);
|
|
5979 |
}
|
|
5980 |
|
|
5981 |
/*!
|
|
5982 |
\fn QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, qreal x, qreal y, qreal w, qreal h) const
|
|
5983 |
\since 4.3
|
|
5984 |
|
|
5985 |
This convenience function is equivalent to calling mapFromItem(item, QRectF(\a x, \a y, \a w, \a h)).
|
|
5986 |
*/
|
|
5987 |
|
|
5988 |
/*!
|
|
5989 |
Maps the rectangle \a rect, which is in this item's parent's coordinate
|
|
5990 |
system, to this item's coordinate system, and returns the mapped rectangle
|
|
5991 |
as a polygon.
|
|
5992 |
|
|
5993 |
\sa mapToParent(), mapFromItem(), transform(), {The Graphics View Coordinate
|
|
5994 |
System}
|
|
5995 |
*/
|
|
5996 |
QPolygonF QGraphicsItem::mapFromParent(const QRectF &rect) const
|
|
5997 |
{
|
|
5998 |
// COMBINE
|
|
5999 |
if (!d_ptr->transformData)
|
|
6000 |
return rect.translated(-d_ptr->pos);
|
|
6001 |
return d_ptr->transformToParent().inverted().map(rect);
|
|
6002 |
}
|
|
6003 |
|
|
6004 |
/*!
|
|
6005 |
\fn QPolygonF QGraphicsItem::mapFromParent(qreal x, qreal y, qreal w, qreal h) const
|
|
6006 |
\since 4.3
|
|
6007 |
|
|
6008 |
This convenience function is equivalent to calling mapFromItem(QRectF(\a x, \a y, \a w, \a h)).
|
|
6009 |
*/
|
|
6010 |
|
|
6011 |
/*!
|
|
6012 |
Maps the rectangle \a rect, which is in this item's scene's coordinate
|
|
6013 |
system, to this item's coordinate system, and returns the mapped rectangle
|
|
6014 |
as a polygon.
|
|
6015 |
|
|
6016 |
\sa mapToScene(), mapFromItem(), transform(), {The Graphics View Coordinate
|
|
6017 |
System}
|
|
6018 |
*/
|
|
6019 |
QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const
|
|
6020 |
{
|
|
6021 |
if (d_ptr->hasTranslateOnlySceneTransform())
|
|
6022 |
return rect.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
|
|
6023 |
return d_ptr->sceneTransform.inverted().map(rect);
|
|
6024 |
}
|
|
6025 |
|
|
6026 |
/*!
|
|
6027 |
\fn QPolygonF QGraphicsItem::mapFromScene(qreal x, qreal y, qreal w, qreal h) const
|
|
6028 |
\since 4.3
|
|
6029 |
|
|
6030 |
This convenience function is equivalent to calling mapFromScene(QRectF(\a x, \a y, \a w, \a h)).
|
|
6031 |
*/
|
|
6032 |
|
|
6033 |
/*!
|
|
6034 |
Maps the polygon \a polygon, which is in \a item's coordinate system, to
|
|
6035 |
this item's coordinate system, and returns the mapped polygon.
|
|
6036 |
|
|
6037 |
If \a item is 0, this function returns the same as mapFromScene().
|
|
6038 |
|
|
6039 |
\sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The
|
|
6040 |
Graphics View Coordinate System}
|
|
6041 |
*/
|
|
6042 |
QPolygonF QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPolygonF &polygon) const
|
|
6043 |
{
|
|
6044 |
if (item)
|
|
6045 |
return item->itemTransform(this).map(polygon);
|
|
6046 |
return mapFromScene(polygon);
|
|
6047 |
}
|
|
6048 |
|
|
6049 |
/*!
|
|
6050 |
Maps the polygon \a polygon, which is in this item's parent's coordinate
|
|
6051 |
system, to this item's coordinate system, and returns the mapped polygon.
|
|
6052 |
|
|
6053 |
\sa mapToParent(), mapToItem(), transform(), {The Graphics View Coordinate
|
|
6054 |
System}
|
|
6055 |
*/
|
|
6056 |
QPolygonF QGraphicsItem::mapFromParent(const QPolygonF &polygon) const
|
|
6057 |
{
|
|
6058 |
// COMBINE
|
|
6059 |
if (!d_ptr->transformData)
|
|
6060 |
return polygon.translated(-d_ptr->pos);
|
|
6061 |
return d_ptr->transformToParent().inverted().map(polygon);
|
|
6062 |
}
|
|
6063 |
|
|
6064 |
/*!
|
|
6065 |
Maps the polygon \a polygon, which is in this item's scene's coordinate
|
|
6066 |
system, to this item's coordinate system, and returns the mapped polygon.
|
|
6067 |
|
|
6068 |
\sa mapToScene(), mapFromParent(), transform(), {The Graphics View Coordinate
|
|
6069 |
System}
|
|
6070 |
*/
|
|
6071 |
QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const
|
|
6072 |
{
|
|
6073 |
if (d_ptr->hasTranslateOnlySceneTransform())
|
|
6074 |
return polygon.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
|
|
6075 |
return d_ptr->sceneTransform.inverted().map(polygon);
|
|
6076 |
}
|
|
6077 |
|
|
6078 |
/*!
|
|
6079 |
Maps the path \a path, which is in \a item's coordinate system, to
|
|
6080 |
this item's coordinate system, and returns the mapped path.
|
|
6081 |
|
|
6082 |
If \a item is 0, this function returns the same as mapFromScene().
|
|
6083 |
|
|
6084 |
\sa itemTransform(), mapFromParent(), mapFromScene(), mapToItem(), {The
|
|
6085 |
Graphics View Coordinate System}
|
|
6086 |
*/
|
|
6087 |
QPainterPath QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPainterPath &path) const
|
|
6088 |
{
|
|
6089 |
if (item)
|
|
6090 |
return item->itemTransform(this).map(path);
|
|
6091 |
return mapFromScene(path);
|
|
6092 |
}
|
|
6093 |
|
|
6094 |
/*!
|
|
6095 |
Maps the path \a path, which is in this item's parent's coordinate
|
|
6096 |
system, to this item's coordinate system, and returns the mapped path.
|
|
6097 |
|
|
6098 |
\sa mapFromScene(), mapFromItem(), mapToParent(), {The Graphics View
|
|
6099 |
Coordinate System}
|
|
6100 |
*/
|
|
6101 |
QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const
|
|
6102 |
{
|
|
6103 |
// COMBINE
|
|
6104 |
if (!d_ptr->transformData)
|
|
6105 |
return path.translated(-d_ptr->pos);
|
|
6106 |
return d_ptr->transformToParent().inverted().map(path);
|
|
6107 |
}
|
|
6108 |
|
|
6109 |
/*!
|
|
6110 |
Maps the path \a path, which is in this item's scene's coordinate
|
|
6111 |
system, to this item's coordinate system, and returns the mapped path.
|
|
6112 |
|
|
6113 |
\sa mapFromParent(), mapFromItem(), mapToScene(), {The Graphics View
|
|
6114 |
Coordinate System}
|
|
6115 |
*/
|
|
6116 |
QPainterPath QGraphicsItem::mapFromScene(const QPainterPath &path) const
|
|
6117 |
{
|
|
6118 |
if (d_ptr->hasTranslateOnlySceneTransform())
|
|
6119 |
return path.translated(-d_ptr->sceneTransform.dx(), -d_ptr->sceneTransform.dy());
|
|
6120 |
return d_ptr->sceneTransform.inverted().map(path);
|
|
6121 |
}
|
|
6122 |
|
|
6123 |
/*!
|
|
6124 |
Returns true if this item is an ancestor of \a child (i.e., if this item
|
|
6125 |
is \a child's parent, or one of \a child's parent's ancestors).
|
|
6126 |
|
|
6127 |
\sa parentItem()
|
|
6128 |
*/
|
|
6129 |
bool QGraphicsItem::isAncestorOf(const QGraphicsItem *child) const
|
|
6130 |
{
|
|
6131 |
if (!child || child == this)
|
|
6132 |
return false;
|
|
6133 |
if (child->d_ptr->depth() < d_ptr->depth())
|
|
6134 |
return false;
|
|
6135 |
const QGraphicsItem *ancestor = child;
|
|
6136 |
while ((ancestor = ancestor->d_ptr->parent)) {
|
|
6137 |
if (ancestor == this)
|
|
6138 |
return true;
|
|
6139 |
}
|
|
6140 |
return false;
|
|
6141 |
}
|
|
6142 |
|
|
6143 |
/*!
|
|
6144 |
\since 4.4
|
|
6145 |
|
|
6146 |
Returns the closest common ancestor item of this item and \a other, or 0
|
|
6147 |
if either \a other is 0, or there is no common ancestor.
|
|
6148 |
|
|
6149 |
\sa isAncestorOf()
|
|
6150 |
*/
|
|
6151 |
QGraphicsItem *QGraphicsItem::commonAncestorItem(const QGraphicsItem *other) const
|
|
6152 |
{
|
|
6153 |
if (!other)
|
|
6154 |
return 0;
|
|
6155 |
if (other == this)
|
|
6156 |
return const_cast<QGraphicsItem *>(this);
|
|
6157 |
const QGraphicsItem *thisw = this;
|
|
6158 |
const QGraphicsItem *otherw = other;
|
|
6159 |
int thisDepth = d_ptr->depth();
|
|
6160 |
int otherDepth = other->d_ptr->depth();
|
|
6161 |
while (thisDepth > otherDepth) {
|
|
6162 |
thisw = thisw->d_ptr->parent;
|
|
6163 |
--thisDepth;
|
|
6164 |
}
|
|
6165 |
while (otherDepth > thisDepth) {
|
|
6166 |
otherw = otherw->d_ptr->parent;
|
|
6167 |
--otherDepth;
|
|
6168 |
}
|
|
6169 |
while (thisw && thisw != otherw) {
|
|
6170 |
thisw = thisw->d_ptr->parent;
|
|
6171 |
otherw = otherw->d_ptr->parent;
|
|
6172 |
}
|
|
6173 |
return const_cast<QGraphicsItem *>(thisw);
|
|
6174 |
}
|
|
6175 |
|
|
6176 |
/*!
|
|
6177 |
\since 4,4
|
|
6178 |
Returns true if this item is currently under the mouse cursor in one of
|
|
6179 |
the views; otherwise, false is returned.
|
|
6180 |
|
|
6181 |
\sa QGraphicsScene::views(), QCursor::pos()
|
|
6182 |
*/
|
|
6183 |
bool QGraphicsItem::isUnderMouse() const
|
|
6184 |
{
|
|
6185 |
Q_D(const QGraphicsItem);
|
|
6186 |
if (!d->scene)
|
|
6187 |
return false;
|
|
6188 |
|
|
6189 |
QPoint cursorPos = QCursor::pos();
|
|
6190 |
foreach (QGraphicsView *view, d->scene->views()) {
|
|
6191 |
if (contains(mapFromScene(view->mapToScene(view->mapFromGlobal(cursorPos)))))
|
|
6192 |
return true;
|
|
6193 |
}
|
|
6194 |
return false;
|
|
6195 |
}
|
|
6196 |
|
|
6197 |
/*!
|
|
6198 |
Returns this item's custom data for the key \a key as a QVariant.
|
|
6199 |
|
|
6200 |
Custom item data is useful for storing arbitrary properties in any
|
|
6201 |
item. Example:
|
|
6202 |
|
|
6203 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 11
|
|
6204 |
|
|
6205 |
Qt does not use this feature for storing data; it is provided solely
|
|
6206 |
for the convenience of the user.
|
|
6207 |
|
|
6208 |
\sa setData()
|
|
6209 |
*/
|
|
6210 |
QVariant QGraphicsItem::data(int key) const
|
|
6211 |
{
|
|
6212 |
QGraphicsItemCustomDataStore *store = qt_dataStore();
|
|
6213 |
if (!store->data.contains(this))
|
|
6214 |
return QVariant();
|
|
6215 |
return store->data.value(this).value(key);
|
|
6216 |
}
|
|
6217 |
|
|
6218 |
/*!
|
|
6219 |
Sets this item's custom data for the key \a key to \a value.
|
|
6220 |
|
|
6221 |
Custom item data is useful for storing arbitrary properties for any
|
|
6222 |
item. Qt does not use this feature for storing data; it is provided solely
|
|
6223 |
for the convenience of the user.
|
|
6224 |
|
|
6225 |
\sa data()
|
|
6226 |
*/
|
|
6227 |
void QGraphicsItem::setData(int key, const QVariant &value)
|
|
6228 |
{
|
|
6229 |
qt_dataStore()->data[this][key] = value;
|
|
6230 |
}
|
|
6231 |
|
|
6232 |
/*!
|
|
6233 |
\fn T qgraphicsitem_cast(QGraphicsItem *item)
|
|
6234 |
\relates QGraphicsItem
|
|
6235 |
\since 4.2
|
|
6236 |
|
|
6237 |
Returns the given \a item cast to type T if \a item is of type T;
|
|
6238 |
otherwise, 0 is returned.
|
|
6239 |
|
|
6240 |
\note To make this function work correctly with custom items, reimplement
|
|
6241 |
the \l{QGraphicsItem::}{type()} function for each custom QGraphicsItem
|
|
6242 |
subclass.
|
|
6243 |
|
|
6244 |
\sa QGraphicsItem::type(), QGraphicsItem::UserType
|
|
6245 |
*/
|
|
6246 |
|
|
6247 |
/*!
|
|
6248 |
Returns the type of an item as an int. All standard graphicsitem classes
|
|
6249 |
are associated with a unique value; see QGraphicsItem::Type. This type
|
|
6250 |
information is used by qgraphicsitem_cast() to distinguish between types.
|
|
6251 |
|
|
6252 |
The default implementation (in QGraphicsItem) returns UserType.
|
|
6253 |
|
|
6254 |
To enable use of qgraphicsitem_cast() with a custom item, reimplement this
|
|
6255 |
function and declare a Type enum value equal to your custom item's type.
|
|
6256 |
Custom items must return a value larger than or equal to UserType (65536).
|
|
6257 |
|
|
6258 |
For example:
|
|
6259 |
|
|
6260 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp QGraphicsItem type
|
|
6261 |
|
|
6262 |
\sa UserType
|
|
6263 |
*/
|
|
6264 |
int QGraphicsItem::type() const
|
|
6265 |
{
|
|
6266 |
return (int)UserType;
|
|
6267 |
}
|
|
6268 |
|
|
6269 |
/*!
|
|
6270 |
Installs an event filter for this item on \a filterItem, causing
|
|
6271 |
all events for this item to first pass through \a filterItem's
|
|
6272 |
sceneEventFilter() function.
|
|
6273 |
|
|
6274 |
To filter another item's events, install this item as an event filter
|
|
6275 |
for the other item. Example:
|
|
6276 |
|
|
6277 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 12
|
|
6278 |
|
|
6279 |
An item can only filter events for other items in the same
|
|
6280 |
scene. Also, an item cannot filter its own events; instead, you
|
|
6281 |
can reimplement sceneEvent() directly.
|
|
6282 |
|
|
6283 |
Items must belong to a scene for scene event filters to be installed and
|
|
6284 |
used.
|
|
6285 |
|
|
6286 |
\sa removeSceneEventFilter(), sceneEventFilter(), sceneEvent()
|
|
6287 |
*/
|
|
6288 |
void QGraphicsItem::installSceneEventFilter(QGraphicsItem *filterItem)
|
|
6289 |
{
|
|
6290 |
if (!d_ptr->scene) {
|
|
6291 |
qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
|
|
6292 |
" on items in a scene.");
|
|
6293 |
return;
|
|
6294 |
}
|
|
6295 |
if (d_ptr->scene != filterItem->scene()) {
|
|
6296 |
qWarning("QGraphicsItem::installSceneEventFilter: event filters can only be installed"
|
|
6297 |
" on items in the same scene.");
|
|
6298 |
return;
|
|
6299 |
}
|
|
6300 |
d_ptr->scene->d_func()->installSceneEventFilter(this, filterItem);
|
|
6301 |
}
|
|
6302 |
|
|
6303 |
/*!
|
|
6304 |
Removes an event filter on this item from \a filterItem.
|
|
6305 |
|
|
6306 |
\sa installSceneEventFilter()
|
|
6307 |
*/
|
|
6308 |
void QGraphicsItem::removeSceneEventFilter(QGraphicsItem *filterItem)
|
|
6309 |
{
|
|
6310 |
if (!d_ptr->scene || d_ptr->scene != filterItem->scene())
|
|
6311 |
return;
|
|
6312 |
d_ptr->scene->d_func()->removeSceneEventFilter(this, filterItem);
|
|
6313 |
}
|
|
6314 |
|
|
6315 |
/*!
|
|
6316 |
Filters events for the item \a watched. \a event is the filtered
|
|
6317 |
event.
|
|
6318 |
|
|
6319 |
Reimplementing this function in a subclass makes it possible
|
|
6320 |
for the item to be used as an event filter for other items,
|
|
6321 |
intercepting all the events send to those items before they are
|
|
6322 |
able to respond.
|
|
6323 |
|
|
6324 |
Reimplementations must return true to prevent further processing of
|
|
6325 |
a given event, ensuring that it will not be delivered to the watched
|
|
6326 |
item, or return false to indicate that the event should be propagated
|
|
6327 |
further by the event system.
|
|
6328 |
|
|
6329 |
\sa installSceneEventFilter()
|
|
6330 |
*/
|
|
6331 |
bool QGraphicsItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
|
|
6332 |
{
|
|
6333 |
Q_UNUSED(watched);
|
|
6334 |
Q_UNUSED(event);
|
|
6335 |
return false;
|
|
6336 |
}
|
|
6337 |
|
|
6338 |
/*!
|
|
6339 |
This virtual function receives events to this item. Reimplement
|
|
6340 |
this function to intercept events before they are dispatched to
|
|
6341 |
the specialized event handlers contextMenuEvent(), focusInEvent(),
|
|
6342 |
focusOutEvent(), hoverEnterEvent(), hoverMoveEvent(),
|
|
6343 |
hoverLeaveEvent(), keyPressEvent(), keyReleaseEvent(),
|
|
6344 |
mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent(), and
|
|
6345 |
mouseDoubleClickEvent().
|
|
6346 |
|
|
6347 |
Returns true if the event was recognized and handled; otherwise, (e.g., if
|
|
6348 |
the event type was not recognized,) false is returned.
|
|
6349 |
|
|
6350 |
\a event is the intercepted event.
|
|
6351 |
*/
|
|
6352 |
bool QGraphicsItem::sceneEvent(QEvent *event)
|
|
6353 |
{
|
|
6354 |
if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents) {
|
|
6355 |
if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverLeave
|
|
6356 |
|| event->type() == QEvent::DragEnter || event->type() == QEvent::DragLeave) {
|
|
6357 |
// Hover enter and hover leave events for children are ignored;
|
|
6358 |
// hover move events are forwarded.
|
|
6359 |
return true;
|
|
6360 |
}
|
|
6361 |
|
|
6362 |
QGraphicsItem *handler = this;
|
|
6363 |
do {
|
|
6364 |
handler = handler->d_ptr->parent;
|
|
6365 |
Q_ASSERT(handler);
|
|
6366 |
} while (handler->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents);
|
|
6367 |
// Forward the event to the closest parent that handles child
|
|
6368 |
// events, mapping existing item-local coordinates to its
|
|
6369 |
// coordinate system.
|
|
6370 |
d_ptr->remapItemPos(event, handler);
|
|
6371 |
handler->sceneEvent(event);
|
|
6372 |
return true;
|
|
6373 |
}
|
|
6374 |
|
|
6375 |
if (!d_ptr->visible) {
|
|
6376 |
// Eaten
|
|
6377 |
return true;
|
|
6378 |
}
|
|
6379 |
|
|
6380 |
switch (event->type()) {
|
|
6381 |
case QEvent::FocusIn:
|
|
6382 |
focusInEvent(static_cast<QFocusEvent *>(event));
|
|
6383 |
break;
|
|
6384 |
case QEvent::FocusOut:
|
|
6385 |
focusOutEvent(static_cast<QFocusEvent *>(event));
|
|
6386 |
break;
|
|
6387 |
case QEvent::GraphicsSceneContextMenu:
|
|
6388 |
contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event));
|
|
6389 |
break;
|
|
6390 |
case QEvent::GraphicsSceneDragEnter:
|
|
6391 |
dragEnterEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
|
|
6392 |
break;
|
|
6393 |
case QEvent::GraphicsSceneDragMove:
|
|
6394 |
dragMoveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
|
|
6395 |
break;
|
|
6396 |
case QEvent::GraphicsSceneDragLeave:
|
|
6397 |
dragLeaveEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
|
|
6398 |
break;
|
|
6399 |
case QEvent::GraphicsSceneDrop:
|
|
6400 |
dropEvent(static_cast<QGraphicsSceneDragDropEvent *>(event));
|
|
6401 |
break;
|
|
6402 |
case QEvent::GraphicsSceneHoverEnter:
|
|
6403 |
hoverEnterEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
|
|
6404 |
break;
|
|
6405 |
case QEvent::GraphicsSceneHoverMove:
|
|
6406 |
hoverMoveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
|
|
6407 |
break;
|
|
6408 |
case QEvent::GraphicsSceneHoverLeave:
|
|
6409 |
hoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent *>(event));
|
|
6410 |
break;
|
|
6411 |
case QEvent::GraphicsSceneMouseMove:
|
|
6412 |
mouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
|
|
6413 |
break;
|
|
6414 |
case QEvent::GraphicsSceneMousePress:
|
|
6415 |
mousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
|
|
6416 |
break;
|
|
6417 |
case QEvent::GraphicsSceneMouseRelease:
|
|
6418 |
mouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
|
|
6419 |
break;
|
|
6420 |
case QEvent::GraphicsSceneMouseDoubleClick:
|
|
6421 |
mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
|
|
6422 |
break;
|
|
6423 |
case QEvent::GraphicsSceneWheel:
|
|
6424 |
wheelEvent(static_cast<QGraphicsSceneWheelEvent *>(event));
|
|
6425 |
break;
|
|
6426 |
case QEvent::KeyPress: {
|
|
6427 |
QKeyEvent *k = static_cast<QKeyEvent *>(event);
|
|
6428 |
if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
|
|
6429 |
if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
|
|
6430 |
bool res = false;
|
|
6431 |
if (k->key() == Qt::Key_Backtab
|
|
6432 |
|| (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier))) {
|
|
6433 |
if (d_ptr->isWidget) {
|
|
6434 |
res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(false);
|
|
6435 |
} else if (d_ptr->scene) {
|
|
6436 |
res = d_ptr->scene->focusNextPrevChild(false);
|
|
6437 |
}
|
|
6438 |
} else if (k->key() == Qt::Key_Tab) {
|
|
6439 |
if (d_ptr->isWidget) {
|
|
6440 |
res = static_cast<QGraphicsWidget *>(this)->focusNextPrevChild(true);
|
|
6441 |
} else if (d_ptr->scene) {
|
|
6442 |
res = d_ptr->scene->focusNextPrevChild(true);
|
|
6443 |
}
|
|
6444 |
}
|
|
6445 |
if (!res)
|
|
6446 |
event->ignore();
|
|
6447 |
return true;
|
|
6448 |
}
|
|
6449 |
}
|
|
6450 |
keyPressEvent(static_cast<QKeyEvent *>(event));
|
|
6451 |
break;
|
|
6452 |
}
|
|
6453 |
case QEvent::KeyRelease:
|
|
6454 |
keyReleaseEvent(static_cast<QKeyEvent *>(event));
|
|
6455 |
break;
|
|
6456 |
case QEvent::InputMethod:
|
|
6457 |
inputMethodEvent(static_cast<QInputMethodEvent *>(event));
|
|
6458 |
break;
|
|
6459 |
case QEvent::WindowActivate:
|
|
6460 |
case QEvent::WindowDeactivate:
|
|
6461 |
// Propagate panel activation.
|
|
6462 |
if (d_ptr->scene) {
|
|
6463 |
for (int i = 0; i < d_ptr->children.size(); ++i) {
|
|
6464 |
QGraphicsItem *child = d_ptr->children.at(i);
|
|
6465 |
if (child->isVisible() && !child->isPanel()) {
|
|
6466 |
if (!(child->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorHandlesChildEvents))
|
|
6467 |
d_ptr->scene->sendEvent(child, event);
|
|
6468 |
}
|
|
6469 |
}
|
|
6470 |
}
|
|
6471 |
break;
|
|
6472 |
default:
|
|
6473 |
return false;
|
|
6474 |
}
|
|
6475 |
|
|
6476 |
return true;
|
|
6477 |
}
|
|
6478 |
|
|
6479 |
/*!
|
|
6480 |
This event handler can be reimplemented in a subclass to process context
|
|
6481 |
menu events. The \a event parameter contains details about the event to
|
|
6482 |
be handled.
|
|
6483 |
|
|
6484 |
If you ignore the event, (i.e., by calling QEvent::ignore(),) \a event
|
|
6485 |
will propagate to any item beneath this item. If no items accept the
|
|
6486 |
event, it will be ignored by the scene, and propagate to the view.
|
|
6487 |
|
|
6488 |
It's common to open a QMenu in response to receiving a context menu
|
|
6489 |
event. Example:
|
|
6490 |
|
|
6491 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 13
|
|
6492 |
|
|
6493 |
The default implementation ignores the event.
|
|
6494 |
|
|
6495 |
\sa sceneEvent()
|
|
6496 |
*/
|
|
6497 |
void QGraphicsItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
|
6498 |
{
|
|
6499 |
event->ignore();
|
|
6500 |
}
|
|
6501 |
|
|
6502 |
/*!
|
|
6503 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6504 |
drag enter events for this item. Drag enter events are generated as the
|
|
6505 |
cursor enters the item's area.
|
|
6506 |
|
|
6507 |
By accepting the event, (i.e., by calling QEvent::accept(),) the item will
|
|
6508 |
accept drop events, in addition to receiving drag move and drag
|
|
6509 |
leave. Otherwise, the event will be ignored and propagate to the item
|
|
6510 |
beneath. If the event is accepted, the item will receive a drag move event
|
|
6511 |
before control goes back to the event loop.
|
|
6512 |
|
|
6513 |
A common implementation of dragEnterEvent accepts or ignores \a event
|
|
6514 |
depending on the associated mime data in \a event. Example:
|
|
6515 |
|
|
6516 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 14
|
|
6517 |
|
|
6518 |
Items do not receive drag and drop events by default; to enable this
|
|
6519 |
feature, call \c setAcceptDrops(true).
|
|
6520 |
|
|
6521 |
The default implementation does nothing.
|
|
6522 |
|
|
6523 |
\sa dropEvent(), dragMoveEvent(), dragLeaveEvent()
|
|
6524 |
*/
|
|
6525 |
void QGraphicsItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
|
|
6526 |
{
|
|
6527 |
Q_D(QGraphicsItem);
|
|
6528 |
// binary compatibility workaround between 4.4 and 4.5
|
|
6529 |
if (d->isProxyWidget())
|
|
6530 |
static_cast<QGraphicsProxyWidget*>(this)->dragEnterEvent(event);
|
|
6531 |
}
|
|
6532 |
|
|
6533 |
/*!
|
|
6534 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6535 |
drag leave events for this item. Drag leave events are generated as the
|
|
6536 |
cursor leaves the item's area. Most often you will not need to reimplement
|
|
6537 |
this function, but it can be useful for resetting state in your item
|
|
6538 |
(e.g., highlighting).
|
|
6539 |
|
|
6540 |
Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
|
|
6541 |
|
|
6542 |
Items do not receive drag and drop events by default; to enable this
|
|
6543 |
feature, call \c setAcceptDrops(true).
|
|
6544 |
|
|
6545 |
The default implementation does nothing.
|
|
6546 |
|
|
6547 |
\sa dragEnterEvent(), dropEvent(), dragMoveEvent()
|
|
6548 |
*/
|
|
6549 |
void QGraphicsItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
|
|
6550 |
{
|
|
6551 |
Q_D(QGraphicsItem);
|
|
6552 |
// binary compatibility workaround between 4.4 and 4.5
|
|
6553 |
if (d->isProxyWidget())
|
|
6554 |
static_cast<QGraphicsProxyWidget*>(this)->dragLeaveEvent(event);
|
|
6555 |
}
|
|
6556 |
|
|
6557 |
/*!
|
|
6558 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6559 |
drag move events for this item. Drag move events are generated as the
|
|
6560 |
cursor moves around inside the item's area. Most often you will not need
|
|
6561 |
to reimplement this function; it is used to indicate that only parts of
|
|
6562 |
the item can accept drops.
|
|
6563 |
|
|
6564 |
Calling QEvent::ignore() or QEvent::accept() on \a event toggles whether
|
|
6565 |
or not the item will accept drops at the position from the event. By
|
|
6566 |
default, \a event is accepted, indicating that the item allows drops at
|
|
6567 |
the specified position.
|
|
6568 |
|
|
6569 |
Items do not receive drag and drop events by default; to enable this
|
|
6570 |
feature, call \c setAcceptDrops(true).
|
|
6571 |
|
|
6572 |
The default implementation does nothing.
|
|
6573 |
|
|
6574 |
\sa dropEvent(), dragEnterEvent(), dragLeaveEvent()
|
|
6575 |
*/
|
|
6576 |
void QGraphicsItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
|
|
6577 |
{
|
|
6578 |
Q_D(QGraphicsItem);
|
|
6579 |
// binary compatibility workaround between 4.4 and 4.5
|
|
6580 |
if (d->isProxyWidget())
|
|
6581 |
static_cast<QGraphicsProxyWidget*>(this)->dragMoveEvent(event);
|
|
6582 |
}
|
|
6583 |
|
|
6584 |
/*!
|
|
6585 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6586 |
drop events for this item. Items can only receive drop events if the last
|
|
6587 |
drag move event was accepted.
|
|
6588 |
|
|
6589 |
Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
|
|
6590 |
|
|
6591 |
Items do not receive drag and drop events by default; to enable this
|
|
6592 |
feature, call \c setAcceptDrops(true).
|
|
6593 |
|
|
6594 |
The default implementation does nothing.
|
|
6595 |
|
|
6596 |
\sa dragEnterEvent(), dragMoveEvent(), dragLeaveEvent()
|
|
6597 |
*/
|
|
6598 |
void QGraphicsItem::dropEvent(QGraphicsSceneDragDropEvent *event)
|
|
6599 |
{
|
|
6600 |
Q_D(QGraphicsItem);
|
|
6601 |
// binary compatibility workaround between 4.4 and 4.5
|
|
6602 |
if (d->isProxyWidget())
|
|
6603 |
static_cast<QGraphicsProxyWidget*>(this)->dropEvent(event);
|
|
6604 |
}
|
|
6605 |
|
|
6606 |
/*!
|
|
6607 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6608 |
focus in events for this item. The default implementation calls
|
|
6609 |
ensureVisible().
|
|
6610 |
|
|
6611 |
\sa focusOutEvent(), sceneEvent(), setFocus()
|
|
6612 |
*/
|
|
6613 |
void QGraphicsItem::focusInEvent(QFocusEvent *event)
|
|
6614 |
{
|
|
6615 |
Q_UNUSED(event);
|
|
6616 |
update();
|
|
6617 |
}
|
|
6618 |
|
|
6619 |
/*!
|
|
6620 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6621 |
focus out events for this item. The default implementation does nothing.
|
|
6622 |
|
|
6623 |
\sa focusInEvent(), sceneEvent(), setFocus()
|
|
6624 |
*/
|
|
6625 |
void QGraphicsItem::focusOutEvent(QFocusEvent *event)
|
|
6626 |
{
|
|
6627 |
Q_UNUSED(event);
|
|
6628 |
update();
|
|
6629 |
}
|
|
6630 |
|
|
6631 |
/*!
|
|
6632 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6633 |
hover enter events for this item. The default implementation calls
|
|
6634 |
update(); otherwise it does nothing.
|
|
6635 |
|
|
6636 |
Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
|
|
6637 |
|
|
6638 |
\sa hoverMoveEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
|
|
6639 |
*/
|
|
6640 |
void QGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
|
6641 |
{
|
|
6642 |
Q_UNUSED(event);
|
|
6643 |
update();
|
|
6644 |
}
|
|
6645 |
|
|
6646 |
/*!
|
|
6647 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6648 |
hover move events for this item. The default implementation does nothing.
|
|
6649 |
|
|
6650 |
Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
|
|
6651 |
|
|
6652 |
\sa hoverEnterEvent(), hoverLeaveEvent(), sceneEvent(), setAcceptHoverEvents()
|
|
6653 |
*/
|
|
6654 |
void QGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
|
6655 |
{
|
|
6656 |
Q_UNUSED(event);
|
|
6657 |
}
|
|
6658 |
|
|
6659 |
/*!
|
|
6660 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6661 |
hover leave events for this item. The default implementation calls
|
|
6662 |
update(); otherwise it does nothing.
|
|
6663 |
|
|
6664 |
Calling QEvent::ignore() or QEvent::accept() on \a event has no effect.
|
|
6665 |
|
|
6666 |
\sa hoverEnterEvent(), hoverMoveEvent(), sceneEvent(), setAcceptHoverEvents()
|
|
6667 |
*/
|
|
6668 |
void QGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
|
6669 |
{
|
|
6670 |
Q_UNUSED(event);
|
|
6671 |
update();
|
|
6672 |
}
|
|
6673 |
|
|
6674 |
/*!
|
|
6675 |
This event handler, for event \a event, can be reimplemented to
|
|
6676 |
receive key press events for this item. The default implementation
|
|
6677 |
ignores the event. If you reimplement this handler, the event will by
|
|
6678 |
default be accepted.
|
|
6679 |
|
|
6680 |
Note that key events are only received for items that set the
|
|
6681 |
ItemIsFocusable flag, and that have keyboard input focus.
|
|
6682 |
|
|
6683 |
\sa keyReleaseEvent(), setFocus(), QGraphicsScene::setFocusItem(),
|
|
6684 |
sceneEvent()
|
|
6685 |
*/
|
|
6686 |
void QGraphicsItem::keyPressEvent(QKeyEvent *event)
|
|
6687 |
{
|
|
6688 |
event->ignore();
|
|
6689 |
}
|
|
6690 |
|
|
6691 |
/*!
|
|
6692 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6693 |
key release events for this item. The default implementation
|
|
6694 |
ignores the event. If you reimplement this handler, the event will by
|
|
6695 |
default be accepted.
|
|
6696 |
|
|
6697 |
Note that key events are only received for items that set the
|
|
6698 |
ItemIsFocusable flag, and that have keyboard input focus.
|
|
6699 |
|
|
6700 |
\sa keyPressEvent(), setFocus(), QGraphicsScene::setFocusItem(),
|
|
6701 |
sceneEvent()
|
|
6702 |
*/
|
|
6703 |
void QGraphicsItem::keyReleaseEvent(QKeyEvent *event)
|
|
6704 |
{
|
|
6705 |
event->ignore();
|
|
6706 |
}
|
|
6707 |
|
|
6708 |
/*!
|
|
6709 |
This event handler, for event \a event, can be reimplemented to
|
|
6710 |
receive mouse press events for this item. Mouse press events are
|
|
6711 |
only delivered to items that accept the mouse button that is
|
|
6712 |
pressed. By default, an item accepts all mouse buttons, but you
|
|
6713 |
can change this by calling setAcceptedMouseButtons().
|
|
6714 |
|
|
6715 |
The mouse press event decides which item should become the mouse
|
|
6716 |
grabber (see QGraphicsScene::mouseGrabberItem()). If you do not
|
|
6717 |
reimplement this function, the press event will propagate to any
|
|
6718 |
topmost item beneath this item, and no other mouse events will be
|
|
6719 |
delivered to this item.
|
|
6720 |
|
|
6721 |
If you do reimplement this function, \a event will by default be
|
|
6722 |
accepted (see QEvent::accept()), and this item is then the mouse
|
|
6723 |
grabber. This allows the item to receive future move, release and
|
|
6724 |
doubleclick events. If you call QEvent::ignore() on \a event, this
|
|
6725 |
item will lose the mouse grab, and \a event will propagate to any
|
|
6726 |
topmost item beneath. No further mouse events will be delivered to
|
|
6727 |
this item unless a new mouse press event is received.
|
|
6728 |
|
|
6729 |
The default implementation handles basic item interaction, such as
|
|
6730 |
selection and moving. If you want to keep the base implementation
|
|
6731 |
when reimplementing this function, call
|
|
6732 |
QGraphicsItem::mousePressEvent() in your reimplementation.
|
|
6733 |
|
|
6734 |
The event is \l{QEvent::ignore()}d for items that are neither
|
|
6735 |
\l{QGraphicsItem::ItemIsMovable}{movable} nor
|
|
6736 |
\l{QGraphicsItem::ItemIsSelectable}{selectable}.
|
|
6737 |
|
|
6738 |
\sa mouseMoveEvent(), mouseReleaseEvent(),
|
|
6739 |
mouseDoubleClickEvent(), sceneEvent()
|
|
6740 |
*/
|
|
6741 |
void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|
6742 |
{
|
|
6743 |
if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
|
|
6744 |
bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
|
|
6745 |
if (!multiSelect) {
|
|
6746 |
if (!d_ptr->selected) {
|
|
6747 |
if (QGraphicsScene *scene = d_ptr->scene) {
|
|
6748 |
++scene->d_func()->selectionChanging;
|
|
6749 |
scene->clearSelection();
|
|
6750 |
--scene->d_func()->selectionChanging;
|
|
6751 |
}
|
|
6752 |
setSelected(true);
|
|
6753 |
}
|
|
6754 |
}
|
|
6755 |
} else if (!(flags() & ItemIsMovable)) {
|
|
6756 |
event->ignore();
|
|
6757 |
}
|
|
6758 |
if (d_ptr->isWidget) {
|
|
6759 |
// Qt::Popup closes when you click outside.
|
|
6760 |
QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
|
|
6761 |
if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
|
|
6762 |
event->accept();
|
|
6763 |
if (!w->rect().contains(event->pos()))
|
|
6764 |
w->close();
|
|
6765 |
}
|
|
6766 |
}
|
|
6767 |
}
|
|
6768 |
|
|
6769 |
/*!
|
|
6770 |
obsolete
|
|
6771 |
*/
|
|
6772 |
bool _qt_movableAncestorIsSelected(const QGraphicsItem *item)
|
|
6773 |
{
|
|
6774 |
const QGraphicsItem *parent = item->parentItem();
|
|
6775 |
return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
|
|
6776 |
}
|
|
6777 |
|
|
6778 |
bool QGraphicsItemPrivate::movableAncestorIsSelected(const QGraphicsItem *item)
|
|
6779 |
{
|
|
6780 |
const QGraphicsItem *parent = item->d_ptr->parent;
|
|
6781 |
return parent && (((parent->flags() & QGraphicsItem::ItemIsMovable) && parent->isSelected()) || _qt_movableAncestorIsSelected(parent));
|
|
6782 |
}
|
|
6783 |
|
|
6784 |
/*!
|
|
6785 |
This event handler, for event \a event, can be reimplemented to
|
|
6786 |
receive mouse move events for this item. If you do receive this
|
|
6787 |
event, you can be certain that this item also received a mouse
|
|
6788 |
press event, and that this item is the current mouse grabber.
|
|
6789 |
|
|
6790 |
Calling QEvent::ignore() or QEvent::accept() on \a event has no
|
|
6791 |
effect.
|
|
6792 |
|
|
6793 |
The default implementation handles basic item interaction, such as
|
|
6794 |
selection and moving. If you want to keep the base implementation
|
|
6795 |
when reimplementing this function, call
|
|
6796 |
QGraphicsItem::mouseMoveEvent() in your reimplementation.
|
|
6797 |
|
|
6798 |
Please note that mousePressEvent() decides which graphics item it
|
|
6799 |
is that receives mouse events. See the mousePressEvent()
|
|
6800 |
description for details.
|
|
6801 |
|
|
6802 |
\sa mousePressEvent(), mouseReleaseEvent(),
|
|
6803 |
mouseDoubleClickEvent(), sceneEvent()
|
|
6804 |
*/
|
|
6805 |
void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|
6806 |
{
|
|
6807 |
if ((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) {
|
|
6808 |
// Determine the list of items that need to be moved.
|
|
6809 |
QList<QGraphicsItem *> selectedItems;
|
|
6810 |
QMap<QGraphicsItem *, QPointF> initialPositions;
|
|
6811 |
if (d_ptr->scene) {
|
|
6812 |
selectedItems = d_ptr->scene->selectedItems();
|
|
6813 |
initialPositions = d_ptr->scene->d_func()->movingItemsInitialPositions;
|
|
6814 |
if (initialPositions.isEmpty()) {
|
|
6815 |
foreach (QGraphicsItem *item, selectedItems)
|
|
6816 |
initialPositions[item] = item->pos();
|
|
6817 |
initialPositions[this] = pos();
|
|
6818 |
}
|
|
6819 |
d_ptr->scene->d_func()->movingItemsInitialPositions = initialPositions;
|
|
6820 |
}
|
|
6821 |
|
|
6822 |
// Find the active view.
|
|
6823 |
QGraphicsView *view = 0;
|
|
6824 |
if (event->widget())
|
|
6825 |
view = qobject_cast<QGraphicsView *>(event->widget()->parentWidget());
|
|
6826 |
|
|
6827 |
// Move all selected items
|
|
6828 |
int i = 0;
|
|
6829 |
bool movedMe = false;
|
|
6830 |
while (i <= selectedItems.size()) {
|
|
6831 |
QGraphicsItem *item = 0;
|
|
6832 |
if (i < selectedItems.size())
|
|
6833 |
item = selectedItems.at(i);
|
|
6834 |
else
|
|
6835 |
item = this;
|
|
6836 |
if (item == this) {
|
|
6837 |
// Slightly clumsy-looking way to ensure that "this" is part
|
|
6838 |
// of the list of items to move, this is to avoid allocations
|
|
6839 |
// (appending this item to the list of selected items causes a
|
|
6840 |
// detach).
|
|
6841 |
if (movedMe)
|
|
6842 |
break;
|
|
6843 |
movedMe = true;
|
|
6844 |
}
|
|
6845 |
|
|
6846 |
if ((item->flags() & ItemIsMovable) && !QGraphicsItemPrivate::movableAncestorIsSelected(item)) {
|
|
6847 |
QPointF currentParentPos;
|
|
6848 |
QPointF buttonDownParentPos;
|
|
6849 |
if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorIgnoresTransformations) {
|
|
6850 |
// Items whose ancestors ignore transformations need to
|
|
6851 |
// map screen coordinates to local coordinates, then map
|
|
6852 |
// those to the parent.
|
|
6853 |
QTransform viewToItemTransform = (item->deviceTransform(view->viewportTransform())).inverted();
|
|
6854 |
currentParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))));
|
|
6855 |
buttonDownParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))));
|
|
6856 |
} else if (item->flags() & ItemIgnoresTransformations) {
|
|
6857 |
// Root items that ignore transformations need to
|
|
6858 |
// calculate their diff by mapping viewport coordinates
|
|
6859 |
// directly to parent coordinates.
|
|
6860 |
QTransform viewToParentTransform = (item->transform().translate(item->d_ptr->pos.x(), item->d_ptr->pos.y()))
|
|
6861 |
* (item->sceneTransform() * view->viewportTransform()).inverted();
|
|
6862 |
currentParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->screenPos())));
|
|
6863 |
buttonDownParentPos = viewToParentTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton))));
|
|
6864 |
} else {
|
|
6865 |
// All other items simply map from the scene.
|
|
6866 |
currentParentPos = item->mapToParent(item->mapFromScene(event->scenePos()));
|
|
6867 |
buttonDownParentPos = item->mapToParent(item->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)));
|
|
6868 |
}
|
|
6869 |
|
|
6870 |
item->setPos(initialPositions.value(item) + currentParentPos - buttonDownParentPos);
|
|
6871 |
|
|
6872 |
if (item->flags() & ItemIsSelectable)
|
|
6873 |
item->setSelected(true);
|
|
6874 |
}
|
|
6875 |
++i;
|
|
6876 |
}
|
|
6877 |
|
|
6878 |
} else {
|
|
6879 |
event->ignore();
|
|
6880 |
}
|
|
6881 |
}
|
|
6882 |
|
|
6883 |
/*!
|
|
6884 |
This event handler, for event \a event, can be reimplemented to
|
|
6885 |
receive mouse release events for this item.
|
|
6886 |
|
|
6887 |
Calling QEvent::ignore() or QEvent::accept() on \a event has no
|
|
6888 |
effect.
|
|
6889 |
|
|
6890 |
The default implementation handles basic item interaction, such as
|
|
6891 |
selection and moving. If you want to keep the base implementation
|
|
6892 |
when reimplementing this function, call
|
|
6893 |
QGraphicsItem::mouseReleaseEvent() in your reimplementation.
|
|
6894 |
|
|
6895 |
Please note that mousePressEvent() decides which graphics item it
|
|
6896 |
is that receives mouse events. See the mousePressEvent()
|
|
6897 |
description for details.
|
|
6898 |
|
|
6899 |
\sa mousePressEvent(), mouseMoveEvent(), mouseDoubleClickEvent(),
|
|
6900 |
sceneEvent()
|
|
6901 |
*/
|
|
6902 |
void QGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|
6903 |
{
|
|
6904 |
if (flags() & ItemIsSelectable) {
|
|
6905 |
bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
|
|
6906 |
if (event->scenePos() == event->buttonDownScenePos(Qt::LeftButton)) {
|
|
6907 |
// The item didn't move
|
|
6908 |
if (multiSelect) {
|
|
6909 |
setSelected(!isSelected());
|
|
6910 |
} else {
|
|
6911 |
bool selectionChanged = false;
|
|
6912 |
if (QGraphicsScene *scene = d_ptr->scene) {
|
|
6913 |
++scene->d_func()->selectionChanging;
|
|
6914 |
// Clear everything but this item. Bypass
|
|
6915 |
// QGraphicsScene::clearSelection()'s default behavior by
|
|
6916 |
// temporarily removing this item from the selection list.
|
|
6917 |
if (d_ptr->selected) {
|
|
6918 |
scene->d_func()->selectedItems.remove(this);
|
|
6919 |
foreach (QGraphicsItem *item, scene->d_func()->selectedItems) {
|
|
6920 |
if (item->isSelected()) {
|
|
6921 |
selectionChanged = true;
|
|
6922 |
break;
|
|
6923 |
}
|
|
6924 |
}
|
|
6925 |
}
|
|
6926 |
scene->clearSelection();
|
|
6927 |
if (d_ptr->selected)
|
|
6928 |
scene->d_func()->selectedItems.insert(this);
|
|
6929 |
--scene->d_func()->selectionChanging;
|
|
6930 |
if (selectionChanged)
|
|
6931 |
emit d_ptr->scene->selectionChanged();
|
|
6932 |
}
|
|
6933 |
setSelected(true);
|
|
6934 |
}
|
|
6935 |
}
|
|
6936 |
}
|
|
6937 |
if (d_ptr->scene && !event->buttons())
|
|
6938 |
d_ptr->scene->d_func()->movingItemsInitialPositions.clear();
|
|
6939 |
}
|
|
6940 |
|
|
6941 |
/*!
|
|
6942 |
This event handler, for event \a event, can be reimplemented to
|
|
6943 |
receive mouse doubleclick events for this item.
|
|
6944 |
|
|
6945 |
When doubleclicking an item, the item will first receive a mouse
|
|
6946 |
press event, followed by a release event (i.e., a click), then a
|
|
6947 |
doubleclick event, and finally a release event.
|
|
6948 |
|
|
6949 |
Calling QEvent::ignore() or QEvent::accept() on \a event has no
|
|
6950 |
effect.
|
|
6951 |
|
|
6952 |
The default implementation calls mousePressEvent(). If you want to
|
|
6953 |
keep the base implementation when reimplementing this function,
|
|
6954 |
call QGraphicsItem::mouseDoubleClickEvent() in your
|
|
6955 |
reimplementation.
|
|
6956 |
|
|
6957 |
Note that an item will not receive double click events if it is
|
|
6958 |
neither \l {QGraphicsItem::ItemIsSelectable}{selectable} nor
|
|
6959 |
\l{QGraphicsItem::ItemIsMovable}{movable} (single mouse clicks are
|
|
6960 |
ignored in this case, and that stops the generation of double
|
|
6961 |
clicks).
|
|
6962 |
|
|
6963 |
\sa mousePressEvent(), mouseMoveEvent(), mouseReleaseEvent(), sceneEvent()
|
|
6964 |
*/
|
|
6965 |
void QGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
|
6966 |
{
|
|
6967 |
mousePressEvent(event);
|
|
6968 |
}
|
|
6969 |
|
|
6970 |
/*!
|
|
6971 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6972 |
wheel events for this item. If you reimplement this function, \a event
|
|
6973 |
will be accepted by default.
|
|
6974 |
|
|
6975 |
If you ignore the event, (i.e., by calling QEvent::ignore(),) it will
|
|
6976 |
propagate to any item beneath this item. If no items accept the event, it
|
|
6977 |
will be ignored by the scene, and propagate to the view (e.g., the view's
|
|
6978 |
vertical scroll bar).
|
|
6979 |
|
|
6980 |
The default implementation ignores the event.
|
|
6981 |
|
|
6982 |
\sa sceneEvent()
|
|
6983 |
*/
|
|
6984 |
void QGraphicsItem::wheelEvent(QGraphicsSceneWheelEvent *event)
|
|
6985 |
{
|
|
6986 |
event->ignore();
|
|
6987 |
}
|
|
6988 |
|
|
6989 |
/*!
|
|
6990 |
This event handler, for event \a event, can be reimplemented to receive
|
|
6991 |
input method events for this item. The default implementation ignores the
|
|
6992 |
event.
|
|
6993 |
|
|
6994 |
\sa inputMethodQuery(), sceneEvent()
|
|
6995 |
*/
|
|
6996 |
void QGraphicsItem::inputMethodEvent(QInputMethodEvent *event)
|
|
6997 |
{
|
|
6998 |
event->ignore();
|
|
6999 |
}
|
|
7000 |
|
|
7001 |
/*!
|
|
7002 |
This method is only relevant for input items. It is used by the
|
|
7003 |
input method to query a set of properties of the item to be able
|
|
7004 |
to support complex input method operations, such as support for
|
|
7005 |
surrounding text and reconversions. \a query specifies which
|
|
7006 |
property is queried.
|
|
7007 |
|
|
7008 |
\sa inputMethodEvent(), QInputMethodEvent, QInputContext
|
|
7009 |
*/
|
|
7010 |
QVariant QGraphicsItem::inputMethodQuery(Qt::InputMethodQuery query) const
|
|
7011 |
{
|
|
7012 |
if (isWidget()) {
|
|
7013 |
// ### Qt 5: Remove. The reimplementation in
|
|
7014 |
// QGraphicsProxyWidget solves this problem (but requires a
|
|
7015 |
// recompile to take effect).
|
|
7016 |
return d_ptr->inputMethodQueryHelper(query);
|
|
7017 |
}
|
|
7018 |
|
|
7019 |
Q_UNUSED(query);
|
|
7020 |
return QVariant();
|
|
7021 |
}
|
|
7022 |
|
|
7023 |
/*!
|
|
7024 |
Returns the current input method hints of this item.
|
|
7025 |
|
|
7026 |
Input method hints are only relevant for input items.
|
|
7027 |
The hints are used by the input method to indicate how it should operate.
|
|
7028 |
For example, if the Qt::ImhNumbersOnly flag is set, the input method may change
|
|
7029 |
its visual components to reflect that only numbers can be entered.
|
|
7030 |
|
|
7031 |
The effect may vary between input method implementations.
|
|
7032 |
|
|
7033 |
\since 4.6
|
|
7034 |
|
|
7035 |
\sa setInputMethodHints(), inputMethodQuery(), QInputContext
|
|
7036 |
*/
|
|
7037 |
Qt::InputMethodHints QGraphicsItem::inputMethodHints() const
|
|
7038 |
{
|
|
7039 |
Q_D(const QGraphicsItem);
|
|
7040 |
return d->imHints;
|
|
7041 |
}
|
|
7042 |
|
|
7043 |
/*!
|
|
7044 |
Sets the current input method hints of this item to \a hints.
|
|
7045 |
|
|
7046 |
\since 4.6
|
|
7047 |
|
|
7048 |
\sa inputMethodHints(), inputMethodQuery(), QInputContext
|
|
7049 |
*/
|
|
7050 |
void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
|
|
7051 |
{
|
|
7052 |
Q_D(QGraphicsItem);
|
|
7053 |
d->imHints = hints;
|
|
7054 |
}
|
|
7055 |
|
|
7056 |
/*!
|
|
7057 |
This virtual function is called by QGraphicsItem to notify custom items
|
|
7058 |
that some part of the item's state changes. By reimplementing this
|
|
7059 |
function, your can react to a change, and in some cases, (depending on \a
|
|
7060 |
change,) adjustments can be made.
|
|
7061 |
|
|
7062 |
\a change is the parameter of the item that is changing. \a value is the
|
|
7063 |
new value; the type of the value depends on \a change.
|
|
7064 |
|
|
7065 |
Example:
|
|
7066 |
|
|
7067 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 15
|
|
7068 |
|
|
7069 |
The default implementation does nothing, and returns \a value.
|
|
7070 |
|
|
7071 |
Note: Certain QGraphicsItem functions cannot be called in a
|
|
7072 |
reimplementation of this function; see the GraphicsItemChange
|
|
7073 |
documentation for details.
|
|
7074 |
|
|
7075 |
\sa GraphicsItemChange
|
|
7076 |
*/
|
|
7077 |
QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value)
|
|
7078 |
{
|
|
7079 |
Q_UNUSED(change);
|
|
7080 |
return value;
|
|
7081 |
}
|
|
7082 |
|
|
7083 |
/*!
|
|
7084 |
\internal
|
|
7085 |
|
|
7086 |
Note: This is provided as a hook to avoid future problems related
|
|
7087 |
to adding virtual functions.
|
|
7088 |
*/
|
|
7089 |
bool QGraphicsItem::supportsExtension(Extension extension) const
|
|
7090 |
{
|
|
7091 |
Q_UNUSED(extension);
|
|
7092 |
return false;
|
|
7093 |
}
|
|
7094 |
|
|
7095 |
/*!
|
|
7096 |
\internal
|
|
7097 |
|
|
7098 |
Note: This is provided as a hook to avoid future problems related
|
|
7099 |
to adding virtual functions.
|
|
7100 |
*/
|
|
7101 |
void QGraphicsItem::setExtension(Extension extension, const QVariant &variant)
|
|
7102 |
{
|
|
7103 |
Q_UNUSED(extension);
|
|
7104 |
Q_UNUSED(variant);
|
|
7105 |
}
|
|
7106 |
|
|
7107 |
/*!
|
|
7108 |
\internal
|
|
7109 |
|
|
7110 |
Note: This is provided as a hook to avoid future problems related
|
|
7111 |
to adding virtual functions.
|
|
7112 |
*/
|
|
7113 |
QVariant QGraphicsItem::extension(const QVariant &variant) const
|
|
7114 |
{
|
|
7115 |
Q_UNUSED(variant);
|
|
7116 |
return QVariant();
|
|
7117 |
}
|
|
7118 |
|
|
7119 |
/*!
|
|
7120 |
\internal
|
|
7121 |
|
|
7122 |
Adds this item to the scene's index. Called in conjunction with
|
|
7123 |
removeFromIndex() to ensure the index bookkeeping is correct when
|
|
7124 |
the item's position, transformation or shape changes.
|
|
7125 |
*/
|
|
7126 |
void QGraphicsItem::addToIndex()
|
|
7127 |
{
|
|
7128 |
if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
|
|
7129 |
// ### add to child index only if applicable
|
|
7130 |
return;
|
|
7131 |
}
|
|
7132 |
if (d_ptr->scene)
|
|
7133 |
d_ptr->scene->d_func()->index->addItem(this);
|
|
7134 |
}
|
|
7135 |
|
|
7136 |
/*!
|
|
7137 |
\internal
|
|
7138 |
|
|
7139 |
Removes this item from the scene's index. Called in conjunction
|
|
7140 |
with addToIndex() to ensure the index bookkeeping is correct when
|
|
7141 |
the item's position, transformation or shape changes.
|
|
7142 |
*/
|
|
7143 |
void QGraphicsItem::removeFromIndex()
|
|
7144 |
{
|
|
7145 |
if (d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
|
|
7146 |
// ### remove from child index only if applicable
|
|
7147 |
return;
|
|
7148 |
}
|
|
7149 |
if (d_ptr->scene)
|
|
7150 |
d_ptr->scene->d_func()->index->removeItem(this);
|
|
7151 |
}
|
|
7152 |
|
|
7153 |
/*!
|
|
7154 |
Prepares the item for a geometry change. Call this function before
|
|
7155 |
changing the bounding rect of an item to keep QGraphicsScene's index up to
|
|
7156 |
date.
|
|
7157 |
|
|
7158 |
prepareGeometryChange() will call update() if this is necessary.
|
|
7159 |
|
|
7160 |
Example:
|
|
7161 |
|
|
7162 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 16
|
|
7163 |
|
|
7164 |
\sa boundingRect()
|
|
7165 |
*/
|
|
7166 |
void QGraphicsItem::prepareGeometryChange()
|
|
7167 |
{
|
|
7168 |
if (d_ptr->inDestructor)
|
|
7169 |
return;
|
|
7170 |
if (d_ptr->scene) {
|
|
7171 |
d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true;
|
|
7172 |
d_ptr->geometryChanged = 1;
|
|
7173 |
d_ptr->paintedViewBoundingRectsNeedRepaint = 1;
|
|
7174 |
d_ptr->notifyBoundingRectChanged = !d_ptr->inSetPosHelper;
|
|
7175 |
|
|
7176 |
QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func();
|
|
7177 |
scenePrivate->index->prepareBoundingRectChange(this);
|
|
7178 |
scenePrivate->markDirty(this, QRectF(),
|
|
7179 |
/*invalidateChildren=*/true,
|
|
7180 |
/*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper);
|
|
7181 |
|
|
7182 |
// For compatibility reasons, we have to update the item's old geometry
|
|
7183 |
// if someone is connected to the changed signal or the scene has no views.
|
|
7184 |
// Note that this has to be done *after* markDirty to ensure that
|
|
7185 |
// _q_processDirtyItems is called before _q_emitUpdated.
|
|
7186 |
if (scenePrivate->isSignalConnected(scenePrivate->changedSignalIndex)
|
|
7187 |
|| scenePrivate->views.isEmpty()) {
|
|
7188 |
if (d_ptr->hasTranslateOnlySceneTransform()) {
|
|
7189 |
d_ptr->scene->update(boundingRect().translated(d_ptr->sceneTransform.dx(),
|
|
7190 |
d_ptr->sceneTransform.dy()));
|
|
7191 |
} else {
|
|
7192 |
d_ptr->scene->update(d_ptr->sceneTransform.mapRect(boundingRect()));
|
|
7193 |
}
|
|
7194 |
}
|
|
7195 |
}
|
|
7196 |
|
|
7197 |
QGraphicsItem *parent = this;
|
|
7198 |
while ((parent = parent->d_ptr->parent)) {
|
|
7199 |
parent->d_ptr->dirtyChildrenBoundingRect = 1;
|
|
7200 |
// ### Only do this if the parent's effect applies to the entire subtree.
|
|
7201 |
parent->d_ptr->notifyBoundingRectChanged = 1;
|
|
7202 |
}
|
|
7203 |
|
|
7204 |
if (d_ptr->inSetPosHelper)
|
|
7205 |
return;
|
|
7206 |
|
|
7207 |
if (d_ptr->flags & ItemClipsChildrenToShape
|
|
7208 |
|| d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) {
|
|
7209 |
d_ptr->invalidateCachedClipPathRecursively();
|
|
7210 |
} else {
|
|
7211 |
d_ptr->invalidateCachedClipPath();
|
|
7212 |
}
|
|
7213 |
}
|
|
7214 |
|
|
7215 |
/*!
|
|
7216 |
\internal
|
|
7217 |
|
|
7218 |
Highlights \a item as selected.
|
|
7219 |
|
|
7220 |
NOTE: This function is a duplicate of qt_graphicsItem_highlightSelected() in
|
|
7221 |
qgraphicssvgitem.cpp!
|
|
7222 |
*/
|
|
7223 |
static void qt_graphicsItem_highlightSelected(
|
|
7224 |
QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option)
|
|
7225 |
{
|
|
7226 |
const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1));
|
|
7227 |
if (qFuzzyIsNull(qMax(murect.width(), murect.height())))
|
|
7228 |
return;
|
|
7229 |
|
|
7230 |
const QRectF mbrect = painter->transform().mapRect(item->boundingRect());
|
|
7231 |
if (qMin(mbrect.width(), mbrect.height()) < qreal(1.0))
|
|
7232 |
return;
|
|
7233 |
|
|
7234 |
qreal itemPenWidth;
|
|
7235 |
switch (item->type()) {
|
|
7236 |
case QGraphicsEllipseItem::Type:
|
|
7237 |
itemPenWidth = static_cast<QGraphicsEllipseItem *>(item)->pen().widthF();
|
|
7238 |
break;
|
|
7239 |
case QGraphicsPathItem::Type:
|
|
7240 |
itemPenWidth = static_cast<QGraphicsPathItem *>(item)->pen().widthF();
|
|
7241 |
break;
|
|
7242 |
case QGraphicsPolygonItem::Type:
|
|
7243 |
itemPenWidth = static_cast<QGraphicsPolygonItem *>(item)->pen().widthF();
|
|
7244 |
break;
|
|
7245 |
case QGraphicsRectItem::Type:
|
|
7246 |
itemPenWidth = static_cast<QGraphicsRectItem *>(item)->pen().widthF();
|
|
7247 |
break;
|
|
7248 |
case QGraphicsSimpleTextItem::Type:
|
|
7249 |
itemPenWidth = static_cast<QGraphicsSimpleTextItem *>(item)->pen().widthF();
|
|
7250 |
break;
|
|
7251 |
case QGraphicsLineItem::Type:
|
|
7252 |
itemPenWidth = static_cast<QGraphicsLineItem *>(item)->pen().widthF();
|
|
7253 |
break;
|
|
7254 |
default:
|
|
7255 |
itemPenWidth = 1.0;
|
|
7256 |
}
|
|
7257 |
const qreal pad = itemPenWidth / 2;
|
|
7258 |
|
|
7259 |
const qreal penWidth = 0; // cosmetic pen
|
|
7260 |
|
|
7261 |
const QColor fgcolor = option->palette.windowText().color();
|
|
7262 |
const QColor bgcolor( // ensure good contrast against fgcolor
|
|
7263 |
fgcolor.red() > 127 ? 0 : 255,
|
|
7264 |
fgcolor.green() > 127 ? 0 : 255,
|
|
7265 |
fgcolor.blue() > 127 ? 0 : 255);
|
|
7266 |
|
|
7267 |
painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
|
|
7268 |
painter->setBrush(Qt::NoBrush);
|
|
7269 |
painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
|
|
7270 |
|
|
7271 |
painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
|
|
7272 |
painter->setBrush(Qt::NoBrush);
|
|
7273 |
painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
|
|
7274 |
}
|
|
7275 |
|
|
7276 |
/*!
|
|
7277 |
\class QGraphicsObject
|
|
7278 |
\brief The QGraphicsObject class provides a base class for all graphics items that
|
|
7279 |
require signals, slots and properties.
|
|
7280 |
\since 4.6
|
|
7281 |
\ingroup graphicsview-api
|
|
7282 |
|
|
7283 |
The class extends a QGraphicsItem with QObject's signal/slot and property mechanisms.
|
|
7284 |
It maps many of QGraphicsItem's basic setters and getters to properties and adds notification
|
|
7285 |
signals for many of them.
|
|
7286 |
*/
|
|
7287 |
|
|
7288 |
/*!
|
|
7289 |
Constructs a QGraphicsObject with \a parent.
|
|
7290 |
*/
|
|
7291 |
QGraphicsObject::QGraphicsObject(QGraphicsItem *parent)
|
|
7292 |
: QGraphicsItem(parent)
|
|
7293 |
{
|
|
7294 |
QGraphicsItem::d_ptr->isObject = true;
|
|
7295 |
}
|
|
7296 |
|
|
7297 |
/*!
|
|
7298 |
\internal
|
|
7299 |
*/
|
|
7300 |
QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene)
|
|
7301 |
: QGraphicsItem(dd, parent, scene)
|
|
7302 |
{
|
|
7303 |
QGraphicsItem::d_ptr->isObject = true;
|
|
7304 |
}
|
|
7305 |
|
|
7306 |
/*!
|
|
7307 |
Subscribes the graphics object to the given \a gesture for the specified \a context.
|
|
7308 |
|
|
7309 |
\sa QGestureEvent
|
|
7310 |
*/
|
|
7311 |
|
|
7312 |
void QGraphicsObject::grabGesture(Qt::GestureType gesture, Qt::GestureContext context)
|
|
7313 |
{
|
|
7314 |
QGraphicsItemPrivate * const d = QGraphicsItem::d_func();
|
|
7315 |
d->gestureContext.insert(gesture, context);
|
|
7316 |
(void)QGestureManager::instance(); // create a gesture manager
|
|
7317 |
}
|
|
7318 |
|
|
7319 |
/*!
|
|
7320 |
\property QGraphicsObject::parent
|
|
7321 |
\brief the parent of the item. It is independent from \fn QObject::parent.
|
|
7322 |
|
|
7323 |
\sa QGraphicsItem::setParentItem(), QGraphicsItem::parentObject()
|
|
7324 |
*/
|
|
7325 |
|
|
7326 |
/*!
|
|
7327 |
\property QGraphicsObject::id
|
|
7328 |
\brief the id of of the item
|
|
7329 |
|
|
7330 |
\sa QObject::objectName(), QObject::setObjectName()
|
|
7331 |
*/
|
|
7332 |
|
|
7333 |
/*!
|
|
7334 |
\property QGraphicsObject::opacity
|
|
7335 |
\brief the opacity of the item
|
|
7336 |
|
|
7337 |
\sa QGraphicsItem::setOpacity(), QGraphicsItem::opacity()
|
|
7338 |
*/
|
|
7339 |
|
|
7340 |
/*!
|
|
7341 |
\fn QGraphicsObject::opacityChanged()
|
|
7342 |
|
|
7343 |
This signal gets emitted whenever the opacity of the item changes
|
|
7344 |
|
|
7345 |
\sa QGraphicsItem::opacity()
|
|
7346 |
*/
|
|
7347 |
|
|
7348 |
/*!
|
|
7349 |
\fn QGraphicsObject::parentChanged()
|
|
7350 |
|
|
7351 |
This signal gets emitted whenever the parent of the item changes
|
|
7352 |
*/
|
|
7353 |
|
|
7354 |
/*!
|
|
7355 |
\property QGraphicsObject::pos
|
|
7356 |
\brief the position of the item
|
|
7357 |
|
|
7358 |
Describes the items position.
|
|
7359 |
|
|
7360 |
\sa QGraphicsItem::setPos(), QGraphicsItem::pos()
|
|
7361 |
*/
|
|
7362 |
|
|
7363 |
/*!
|
|
7364 |
\property QGraphicsObject::x
|
|
7365 |
\brief the x position of the item
|
|
7366 |
|
|
7367 |
Describes the items x position.
|
|
7368 |
|
|
7369 |
\sa QGraphicsItem::setX(), setPos(), xChanged()
|
|
7370 |
*/
|
|
7371 |
|
|
7372 |
/*!
|
|
7373 |
\fn QGraphicsObject::xChanged()
|
|
7374 |
|
|
7375 |
This signal gets emitted whenever the x position of the item changes
|
|
7376 |
|
|
7377 |
\sa pos()
|
|
7378 |
*/
|
|
7379 |
|
|
7380 |
/*!
|
|
7381 |
\property QGraphicsObject::y
|
|
7382 |
\brief the y position of the item
|
|
7383 |
|
|
7384 |
Describes the items y position.
|
|
7385 |
|
|
7386 |
\sa QGraphicsItem::setY(), setPos(), yChanged()
|
|
7387 |
*/
|
|
7388 |
|
|
7389 |
/*!
|
|
7390 |
\fn QGraphicsObject::yChanged()
|
|
7391 |
|
|
7392 |
This signal gets emitted whenever the y position of the item changes.
|
|
7393 |
|
|
7394 |
\sa pos()
|
|
7395 |
*/
|
|
7396 |
|
|
7397 |
/*!
|
|
7398 |
\property QGraphicsObject::z
|
|
7399 |
\brief the z value of the item
|
|
7400 |
|
|
7401 |
Describes the items z value.
|
|
7402 |
|
|
7403 |
\sa QGraphicsItem::setZValue(), zValue(), zChanged()
|
|
7404 |
*/
|
|
7405 |
|
|
7406 |
/*!
|
|
7407 |
\fn QGraphicsObject::zChanged()
|
|
7408 |
|
|
7409 |
This signal gets emitted whenever the z value of the item changes.
|
|
7410 |
|
|
7411 |
\sa pos()
|
|
7412 |
*/
|
|
7413 |
|
|
7414 |
/*!
|
|
7415 |
\property QGraphicsObject::rotation
|
|
7416 |
This property holds the rotation of the item in degrees.
|
|
7417 |
|
|
7418 |
This specifies how many degrees to rotate the item around its transformOrigin.
|
|
7419 |
The default rotation is 0 degrees (i.e. not rotated at all).
|
|
7420 |
*/
|
|
7421 |
|
|
7422 |
/*!
|
|
7423 |
\fn QGraphicsObject::rotationChanged()
|
|
7424 |
|
|
7425 |
This signal gets emitted whenever the roation of the item changes.
|
|
7426 |
*/
|
|
7427 |
|
|
7428 |
/*!
|
|
7429 |
\property QGraphicsObject::scale
|
|
7430 |
This property holds the scale of the item.
|
|
7431 |
|
|
7432 |
A scale of less than 1 means the item will be displayed smaller than
|
|
7433 |
normal, and a scale of greater than 1 means the item will be
|
|
7434 |
displayed larger than normal. A negative scale means the item will
|
|
7435 |
be mirrored.
|
|
7436 |
|
|
7437 |
By default, items are displayed at a scale of 1 (i.e. at their
|
|
7438 |
normal size).
|
|
7439 |
|
|
7440 |
Scaling is from the item's transformOrigin.
|
|
7441 |
*/
|
|
7442 |
|
|
7443 |
/*!
|
|
7444 |
\fn void QGraphicsObject::scaleChanged()
|
|
7445 |
|
|
7446 |
This signal is emitted when the scale of the item changes.
|
|
7447 |
*/
|
|
7448 |
|
|
7449 |
|
|
7450 |
/*!
|
|
7451 |
\property QGraphicsObject::enabled
|
|
7452 |
\brief whether the item is enabled or not
|
|
7453 |
|
|
7454 |
This property is declared in QGraphicsItem.
|
|
7455 |
|
|
7456 |
By default, this property is true.
|
|
7457 |
|
|
7458 |
\sa QGraphicsItem::isEnabled(), QGraphicsItem::setEnabled()
|
|
7459 |
\sa QGraphicsObject::enabledChanged()
|
|
7460 |
*/
|
|
7461 |
|
|
7462 |
/*!
|
|
7463 |
\fn void QGraphicsObject::enabledChanged()
|
|
7464 |
|
|
7465 |
This signal gets emitted whenever the item get's enabled or disabled.
|
|
7466 |
|
|
7467 |
\sa isEnabled()
|
|
7468 |
*/
|
|
7469 |
|
|
7470 |
/*!
|
|
7471 |
\property QGraphicsObject::visible
|
|
7472 |
\brief whether the item is visible or not
|
|
7473 |
|
|
7474 |
This property is declared in QGraphicsItem.
|
|
7475 |
|
|
7476 |
By default, this property is true.
|
|
7477 |
|
|
7478 |
\sa QGraphicsItem::isVisible(), QGraphicsItem::setVisible(), visibleChanged()
|
|
7479 |
*/
|
|
7480 |
|
|
7481 |
/*!
|
|
7482 |
\fn QGraphicsObject::visibleChanged()
|
|
7483 |
|
|
7484 |
This signal gets emitted whenever the visibility of the item changes
|
|
7485 |
|
|
7486 |
\sa visible
|
|
7487 |
*/
|
|
7488 |
|
|
7489 |
/*!
|
|
7490 |
\fn const QObjectList &QGraphicsObject::children() const
|
|
7491 |
\internal
|
|
7492 |
|
|
7493 |
This function returns the same value as QObject::children(). It's
|
|
7494 |
provided to differentiate between the obsolete member
|
|
7495 |
QGraphicsItem::children() and QObject::children(). QGraphicsItem now
|
|
7496 |
provides childItems() instead.
|
|
7497 |
*/
|
|
7498 |
|
|
7499 |
/*!
|
|
7500 |
\property QGraphicsObject::transformOriginPoint
|
|
7501 |
\brief the transformation origin
|
|
7502 |
|
|
7503 |
This property sets a specific point in the items coordiante system as the
|
|
7504 |
origin for scale and rotation.
|
|
7505 |
|
|
7506 |
\sa scale, rotation, QGraphicsItem::transformOriginPoint()
|
|
7507 |
*/
|
|
7508 |
|
|
7509 |
|
|
7510 |
/*!
|
|
7511 |
\class QAbstractGraphicsShapeItem
|
|
7512 |
\brief The QAbstractGraphicsShapeItem class provides a common base for
|
|
7513 |
all path items.
|
|
7514 |
\since 4.2
|
|
7515 |
\ingroup graphicsview-api
|
|
7516 |
|
|
7517 |
This class does not fully implement an item by itself; in particular, it
|
|
7518 |
does not implement boundingRect() and paint(), which are inherited by
|
|
7519 |
QGraphicsItem.
|
|
7520 |
|
|
7521 |
You can subclass this item to provide a simple base implementation of
|
|
7522 |
accessors for the item's pen and brush.
|
|
7523 |
|
|
7524 |
\sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPathItem,
|
|
7525 |
QGraphicsPolygonItem, QGraphicsTextItem, QGraphicsLineItem,
|
|
7526 |
QGraphicsPixmapItem, {The Graphics View Framework}
|
|
7527 |
*/
|
|
7528 |
|
|
7529 |
class QAbstractGraphicsShapeItemPrivate : public QGraphicsItemPrivate
|
|
7530 |
{
|
|
7531 |
Q_DECLARE_PUBLIC(QAbstractGraphicsShapeItem)
|
|
7532 |
public:
|
|
7533 |
|
|
7534 |
QBrush brush;
|
|
7535 |
QPen pen;
|
|
7536 |
|
|
7537 |
// Cached bounding rectangle
|
|
7538 |
mutable QRectF boundingRect;
|
|
7539 |
};
|
|
7540 |
|
|
7541 |
/*!
|
|
7542 |
Constructs a QAbstractGraphicsShapeItem. \a parent is passed to
|
|
7543 |
QGraphicsItem's constructor.
|
|
7544 |
*/
|
|
7545 |
QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QGraphicsItem *parent
|
|
7546 |
#ifndef Q_QDOC
|
|
7547 |
// obsolete argument
|
|
7548 |
, QGraphicsScene *scene
|
|
7549 |
#endif
|
|
7550 |
)
|
|
7551 |
: QGraphicsItem(*new QAbstractGraphicsShapeItemPrivate, parent, scene)
|
|
7552 |
{
|
|
7553 |
}
|
|
7554 |
|
|
7555 |
/*!
|
|
7556 |
\internal
|
|
7557 |
*/
|
|
7558 |
QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem(QAbstractGraphicsShapeItemPrivate &dd,
|
|
7559 |
QGraphicsItem *parent,
|
|
7560 |
QGraphicsScene *scene)
|
|
7561 |
: QGraphicsItem(dd, parent, scene)
|
|
7562 |
{
|
|
7563 |
}
|
|
7564 |
|
|
7565 |
/*!
|
|
7566 |
Destroys a QAbstractGraphicsShapeItem.
|
|
7567 |
*/
|
|
7568 |
QAbstractGraphicsShapeItem::~QAbstractGraphicsShapeItem()
|
|
7569 |
{
|
|
7570 |
}
|
|
7571 |
|
|
7572 |
/*!
|
|
7573 |
Returns the item's pen. If no pen has been set, this function returns
|
|
7574 |
QPen(), a default black solid line pen with 0 width.
|
|
7575 |
*/
|
|
7576 |
QPen QAbstractGraphicsShapeItem::pen() const
|
|
7577 |
{
|
|
7578 |
Q_D(const QAbstractGraphicsShapeItem);
|
|
7579 |
return d->pen;
|
|
7580 |
}
|
|
7581 |
|
|
7582 |
/*!
|
|
7583 |
Sets the pen for this item to \a pen.
|
|
7584 |
|
|
7585 |
The pen is used to draw the item's outline.
|
|
7586 |
|
|
7587 |
\sa pen()
|
|
7588 |
*/
|
|
7589 |
void QAbstractGraphicsShapeItem::setPen(const QPen &pen)
|
|
7590 |
{
|
|
7591 |
Q_D(QAbstractGraphicsShapeItem);
|
|
7592 |
prepareGeometryChange();
|
|
7593 |
d->pen = pen;
|
|
7594 |
d->boundingRect = QRectF();
|
|
7595 |
update();
|
|
7596 |
}
|
|
7597 |
|
|
7598 |
/*!
|
|
7599 |
Returns the item's brush, or an empty brush if no brush has been set.
|
|
7600 |
|
|
7601 |
\sa setBrush()
|
|
7602 |
*/
|
|
7603 |
QBrush QAbstractGraphicsShapeItem::brush() const
|
|
7604 |
{
|
|
7605 |
Q_D(const QAbstractGraphicsShapeItem);
|
|
7606 |
return d->brush;
|
|
7607 |
}
|
|
7608 |
|
|
7609 |
/*!
|
|
7610 |
Sets the item's brush to \a brush.
|
|
7611 |
|
|
7612 |
The item's brush is used to fill the item.
|
|
7613 |
|
|
7614 |
If you use a brush with a QGradient, the gradient
|
|
7615 |
is relative to the item's coordinate system.
|
|
7616 |
|
|
7617 |
\sa brush()
|
|
7618 |
*/
|
|
7619 |
void QAbstractGraphicsShapeItem::setBrush(const QBrush &brush)
|
|
7620 |
{
|
|
7621 |
Q_D(QAbstractGraphicsShapeItem);
|
|
7622 |
d->brush = brush;
|
|
7623 |
update();
|
|
7624 |
}
|
|
7625 |
|
|
7626 |
/*!
|
|
7627 |
\reimp
|
|
7628 |
*/
|
|
7629 |
bool QAbstractGraphicsShapeItem::isObscuredBy(const QGraphicsItem *item) const
|
|
7630 |
{
|
|
7631 |
return QGraphicsItem::isObscuredBy(item);
|
|
7632 |
}
|
|
7633 |
|
|
7634 |
/*!
|
|
7635 |
\reimp
|
|
7636 |
*/
|
|
7637 |
QPainterPath QAbstractGraphicsShapeItem::opaqueArea() const
|
|
7638 |
{
|
|
7639 |
Q_D(const QAbstractGraphicsShapeItem);
|
|
7640 |
if (d->brush.isOpaque())
|
|
7641 |
return isClipped() ? clipPath() : shape();
|
|
7642 |
return QGraphicsItem::opaqueArea();
|
|
7643 |
}
|
|
7644 |
|
|
7645 |
/*!
|
|
7646 |
\class QGraphicsPathItem
|
|
7647 |
\brief The QGraphicsPathItem class provides a path item that you
|
|
7648 |
can add to a QGraphicsScene.
|
|
7649 |
\since 4.2
|
|
7650 |
\ingroup graphicsview-api
|
|
7651 |
|
|
7652 |
To set the item's path, pass a QPainterPath to QGraphicsPathItem's
|
|
7653 |
constructor, or call the setPath() function. The path() function
|
|
7654 |
returns the current path.
|
|
7655 |
|
|
7656 |
\image graphicsview-pathitem.png
|
|
7657 |
|
|
7658 |
QGraphicsPathItem uses the path to provide a reasonable
|
|
7659 |
implementation of boundingRect(), shape(), and contains(). The
|
|
7660 |
paint() function draws the path using the item's associated pen
|
|
7661 |
and brush, which you can set by calling the setPen() and
|
|
7662 |
setBrush() functions.
|
|
7663 |
|
|
7664 |
\sa QGraphicsRectItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
|
|
7665 |
QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {The Graphics
|
|
7666 |
View Framework}
|
|
7667 |
*/
|
|
7668 |
|
|
7669 |
class QGraphicsPathItemPrivate : public QAbstractGraphicsShapeItemPrivate
|
|
7670 |
{
|
|
7671 |
Q_DECLARE_PUBLIC(QGraphicsPathItem)
|
|
7672 |
public:
|
|
7673 |
QPainterPath path;
|
|
7674 |
};
|
|
7675 |
|
|
7676 |
/*!
|
|
7677 |
Constructs a QGraphicsPath item using \a path as the default path. \a
|
|
7678 |
parent is passed to QAbstractGraphicsShapeItem's constructor.
|
|
7679 |
|
|
7680 |
\sa QGraphicsScene::addItem()
|
|
7681 |
*/
|
|
7682 |
QGraphicsPathItem::QGraphicsPathItem(const QPainterPath &path,
|
|
7683 |
QGraphicsItem *parent
|
|
7684 |
#ifndef Q_QDOC
|
|
7685 |
// obsolete argument
|
|
7686 |
, QGraphicsScene *scene
|
|
7687 |
#endif
|
|
7688 |
)
|
|
7689 |
: QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
|
|
7690 |
{
|
|
7691 |
if (!path.isEmpty())
|
|
7692 |
setPath(path);
|
|
7693 |
}
|
|
7694 |
|
|
7695 |
/*!
|
|
7696 |
Constructs a QGraphicsPath. \a parent is passed to
|
|
7697 |
QAbstractGraphicsShapeItem's constructor.
|
|
7698 |
|
|
7699 |
\sa QGraphicsScene::addItem()
|
|
7700 |
*/
|
|
7701 |
QGraphicsPathItem::QGraphicsPathItem(QGraphicsItem *parent
|
|
7702 |
#ifndef Q_QDOC
|
|
7703 |
// obsolete argument
|
|
7704 |
, QGraphicsScene *scene
|
|
7705 |
#endif
|
|
7706 |
)
|
|
7707 |
: QAbstractGraphicsShapeItem(*new QGraphicsPathItemPrivate, parent, scene)
|
|
7708 |
{
|
|
7709 |
}
|
|
7710 |
|
|
7711 |
/*!
|
|
7712 |
Destroys the QGraphicsPathItem.
|
|
7713 |
*/
|
|
7714 |
QGraphicsPathItem::~QGraphicsPathItem()
|
|
7715 |
{
|
|
7716 |
}
|
|
7717 |
|
|
7718 |
/*!
|
|
7719 |
Returns the item's path as a QPainterPath. If no item has been set, an
|
|
7720 |
empty QPainterPath is returned.
|
|
7721 |
|
|
7722 |
\sa setPath()
|
|
7723 |
*/
|
|
7724 |
QPainterPath QGraphicsPathItem::path() const
|
|
7725 |
{
|
|
7726 |
Q_D(const QGraphicsPathItem);
|
|
7727 |
return d->path;
|
|
7728 |
}
|
|
7729 |
|
|
7730 |
/*!
|
|
7731 |
Sets the item's path to be the given \a path.
|
|
7732 |
|
|
7733 |
\sa path()
|
|
7734 |
*/
|
|
7735 |
void QGraphicsPathItem::setPath(const QPainterPath &path)
|
|
7736 |
{
|
|
7737 |
Q_D(QGraphicsPathItem);
|
|
7738 |
if (d->path == path)
|
|
7739 |
return;
|
|
7740 |
prepareGeometryChange();
|
|
7741 |
d->path = path;
|
|
7742 |
d->boundingRect = QRectF();
|
|
7743 |
update();
|
|
7744 |
}
|
|
7745 |
|
|
7746 |
/*!
|
|
7747 |
\reimp
|
|
7748 |
*/
|
|
7749 |
QRectF QGraphicsPathItem::boundingRect() const
|
|
7750 |
{
|
|
7751 |
Q_D(const QGraphicsPathItem);
|
|
7752 |
if (d->boundingRect.isNull()) {
|
|
7753 |
qreal pw = pen().widthF();
|
|
7754 |
if (pw == 0.0)
|
|
7755 |
d->boundingRect = d->path.controlPointRect();
|
|
7756 |
else {
|
|
7757 |
d->boundingRect = shape().controlPointRect();
|
|
7758 |
}
|
|
7759 |
}
|
|
7760 |
return d->boundingRect;
|
|
7761 |
}
|
|
7762 |
|
|
7763 |
/*!
|
|
7764 |
\reimp
|
|
7765 |
*/
|
|
7766 |
QPainterPath QGraphicsPathItem::shape() const
|
|
7767 |
{
|
|
7768 |
Q_D(const QGraphicsPathItem);
|
|
7769 |
return qt_graphicsItem_shapeFromPath(d->path, d->pen);
|
|
7770 |
}
|
|
7771 |
|
|
7772 |
/*!
|
|
7773 |
\reimp
|
|
7774 |
*/
|
|
7775 |
bool QGraphicsPathItem::contains(const QPointF &point) const
|
|
7776 |
{
|
|
7777 |
return QAbstractGraphicsShapeItem::contains(point);
|
|
7778 |
}
|
|
7779 |
|
|
7780 |
/*!
|
|
7781 |
\reimp
|
|
7782 |
*/
|
|
7783 |
void QGraphicsPathItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|
7784 |
QWidget *widget)
|
|
7785 |
{
|
|
7786 |
Q_D(QGraphicsPathItem);
|
|
7787 |
Q_UNUSED(widget);
|
|
7788 |
painter->setPen(d->pen);
|
|
7789 |
painter->setBrush(d->brush);
|
|
7790 |
painter->drawPath(d->path);
|
|
7791 |
|
|
7792 |
if (option->state & QStyle::State_Selected)
|
|
7793 |
qt_graphicsItem_highlightSelected(this, painter, option);
|
|
7794 |
}
|
|
7795 |
|
|
7796 |
/*!
|
|
7797 |
\reimp
|
|
7798 |
*/
|
|
7799 |
bool QGraphicsPathItem::isObscuredBy(const QGraphicsItem *item) const
|
|
7800 |
{
|
|
7801 |
return QAbstractGraphicsShapeItem::isObscuredBy(item);
|
|
7802 |
}
|
|
7803 |
|
|
7804 |
/*!
|
|
7805 |
\reimp
|
|
7806 |
*/
|
|
7807 |
QPainterPath QGraphicsPathItem::opaqueArea() const
|
|
7808 |
{
|
|
7809 |
return QAbstractGraphicsShapeItem::opaqueArea();
|
|
7810 |
}
|
|
7811 |
|
|
7812 |
/*!
|
|
7813 |
\reimp
|
|
7814 |
*/
|
|
7815 |
int QGraphicsPathItem::type() const
|
|
7816 |
{
|
|
7817 |
return Type;
|
|
7818 |
}
|
|
7819 |
|
|
7820 |
/*!
|
|
7821 |
\internal
|
|
7822 |
*/
|
|
7823 |
bool QGraphicsPathItem::supportsExtension(Extension extension) const
|
|
7824 |
{
|
|
7825 |
Q_UNUSED(extension);
|
|
7826 |
return false;
|
|
7827 |
}
|
|
7828 |
|
|
7829 |
/*!
|
|
7830 |
\internal
|
|
7831 |
*/
|
|
7832 |
void QGraphicsPathItem::setExtension(Extension extension, const QVariant &variant)
|
|
7833 |
{
|
|
7834 |
Q_UNUSED(extension);
|
|
7835 |
Q_UNUSED(variant);
|
|
7836 |
}
|
|
7837 |
|
|
7838 |
/*!
|
|
7839 |
\internal
|
|
7840 |
*/
|
|
7841 |
QVariant QGraphicsPathItem::extension(const QVariant &variant) const
|
|
7842 |
{
|
|
7843 |
Q_UNUSED(variant);
|
|
7844 |
return QVariant();
|
|
7845 |
}
|
|
7846 |
|
|
7847 |
/*!
|
|
7848 |
\class QGraphicsRectItem
|
|
7849 |
\brief The QGraphicsRectItem class provides a rectangle item that you
|
|
7850 |
can add to a QGraphicsScene.
|
|
7851 |
\since 4.2
|
|
7852 |
\ingroup graphicsview-api
|
|
7853 |
|
|
7854 |
To set the item's rectangle, pass a QRectF to QGraphicsRectItem's
|
|
7855 |
constructor, or call the setRect() function. The rect() function
|
|
7856 |
returns the current rectangle.
|
|
7857 |
|
|
7858 |
\image graphicsview-rectitem.png
|
|
7859 |
|
|
7860 |
QGraphicsRectItem uses the rectangle and the pen width to provide
|
|
7861 |
a reasonable implementation of boundingRect(), shape(), and
|
|
7862 |
contains(). The paint() function draws the rectangle using the
|
|
7863 |
item's associated pen and brush, which you can set by calling the
|
|
7864 |
setPen() and setBrush() functions.
|
|
7865 |
|
|
7866 |
\note The rendering of invalid rectangles, such as those with negative
|
|
7867 |
widths or heights, is undefined. If you cannot be sure that you are
|
|
7868 |
using valid rectangles (for example, if you are creating
|
|
7869 |
rectangles using data from an unreliable source) then you should
|
|
7870 |
use QRectF::normalized() to create normalized rectangles, and use
|
|
7871 |
those instead.
|
|
7872 |
|
|
7873 |
\sa QGraphicsPathItem, QGraphicsEllipseItem, QGraphicsPolygonItem,
|
|
7874 |
QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {The Graphics
|
|
7875 |
View Framework}
|
|
7876 |
*/
|
|
7877 |
|
|
7878 |
class QGraphicsRectItemPrivate : public QAbstractGraphicsShapeItemPrivate
|
|
7879 |
{
|
|
7880 |
Q_DECLARE_PUBLIC(QGraphicsRectItem)
|
|
7881 |
public:
|
|
7882 |
QRectF rect;
|
|
7883 |
};
|
|
7884 |
|
|
7885 |
/*!
|
|
7886 |
Constructs a QGraphicsRectItem, using \a rect as the default rectangle.
|
|
7887 |
\a parent is passed to QAbstractGraphicsShapeItem's constructor.
|
|
7888 |
|
|
7889 |
\sa QGraphicsScene::addItem()
|
|
7890 |
*/
|
|
7891 |
QGraphicsRectItem::QGraphicsRectItem(const QRectF &rect, QGraphicsItem *parent
|
|
7892 |
#ifndef Q_QDOC
|
|
7893 |
// obsolete argument
|
|
7894 |
, QGraphicsScene *scene
|
|
7895 |
#endif
|
|
7896 |
)
|
|
7897 |
: QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
|
|
7898 |
{
|
|
7899 |
setRect(rect);
|
|
7900 |
}
|
|
7901 |
|
|
7902 |
/*!
|
|
7903 |
\fn QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal width, qreal height,
|
|
7904 |
QGraphicsItem *parent)
|
|
7905 |
|
|
7906 |
Constructs a QGraphicsRectItem with a default rectangle defined
|
|
7907 |
by (\a x, \a y) and the given \a width and \a height.
|
|
7908 |
|
|
7909 |
\a parent is passed to QAbstractGraphicsShapeItem's constructor.
|
|
7910 |
|
|
7911 |
\sa QGraphicsScene::addItem()
|
|
7912 |
*/
|
|
7913 |
QGraphicsRectItem::QGraphicsRectItem(qreal x, qreal y, qreal w, qreal h,
|
|
7914 |
QGraphicsItem *parent
|
|
7915 |
#ifndef Q_QDOC
|
|
7916 |
// obsolete argument
|
|
7917 |
, QGraphicsScene *scene
|
|
7918 |
#endif
|
|
7919 |
)
|
|
7920 |
: QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
|
|
7921 |
{
|
|
7922 |
setRect(QRectF(x, y, w, h));
|
|
7923 |
}
|
|
7924 |
|
|
7925 |
/*!
|
|
7926 |
Constructs a QGraphicsRectItem. \a parent is passed to
|
|
7927 |
QAbstractGraphicsShapeItem's constructor.
|
|
7928 |
|
|
7929 |
\sa QGraphicsScene::addItem()
|
|
7930 |
*/
|
|
7931 |
QGraphicsRectItem::QGraphicsRectItem(QGraphicsItem *parent
|
|
7932 |
#ifndef Q_QDOC
|
|
7933 |
// obsolete argument
|
|
7934 |
, QGraphicsScene *scene
|
|
7935 |
#endif
|
|
7936 |
)
|
|
7937 |
: QAbstractGraphicsShapeItem(*new QGraphicsRectItemPrivate, parent, scene)
|
|
7938 |
{
|
|
7939 |
}
|
|
7940 |
|
|
7941 |
/*!
|
|
7942 |
Destroys the QGraphicsRectItem.
|
|
7943 |
*/
|
|
7944 |
QGraphicsRectItem::~QGraphicsRectItem()
|
|
7945 |
{
|
|
7946 |
}
|
|
7947 |
|
|
7948 |
/*!
|
|
7949 |
Returns the item's rectangle.
|
|
7950 |
|
|
7951 |
\sa setRect()
|
|
7952 |
*/
|
|
7953 |
QRectF QGraphicsRectItem::rect() const
|
|
7954 |
{
|
|
7955 |
Q_D(const QGraphicsRectItem);
|
|
7956 |
return d->rect;
|
|
7957 |
}
|
|
7958 |
|
|
7959 |
/*!
|
|
7960 |
\fn void QGraphicsRectItem::setRect(const QRectF &rectangle)
|
|
7961 |
|
|
7962 |
Sets the item's rectangle to be the given \a rectangle.
|
|
7963 |
|
|
7964 |
\sa rect()
|
|
7965 |
*/
|
|
7966 |
void QGraphicsRectItem::setRect(const QRectF &rect)
|
|
7967 |
{
|
|
7968 |
Q_D(QGraphicsRectItem);
|
|
7969 |
if (d->rect == rect)
|
|
7970 |
return;
|
|
7971 |
prepareGeometryChange();
|
|
7972 |
d->rect = rect;
|
|
7973 |
d->boundingRect = QRectF();
|
|
7974 |
update();
|
|
7975 |
}
|
|
7976 |
|
|
7977 |
/*!
|
|
7978 |
\fn void QGraphicsRectItem::setRect(qreal x, qreal y, qreal width, qreal height)
|
|
7979 |
\fn void QGraphicsEllipseItem::setRect(qreal x, qreal y, qreal width, qreal height)
|
|
7980 |
|
|
7981 |
Sets the item's rectangle to the rectangle defined by (\a x, \a y)
|
|
7982 |
and the given \a width and \a height.
|
|
7983 |
|
|
7984 |
This convenience function is equivalent to calling \c
|
|
7985 |
{setRect(QRectF(x, y, width, height))}
|
|
7986 |
|
|
7987 |
\sa rect()
|
|
7988 |
*/
|
|
7989 |
|
|
7990 |
/*!
|
|
7991 |
\reimp
|
|
7992 |
*/
|
|
7993 |
QRectF QGraphicsRectItem::boundingRect() const
|
|
7994 |
{
|
|
7995 |
Q_D(const QGraphicsRectItem);
|
|
7996 |
if (d->boundingRect.isNull()) {
|
|
7997 |
qreal halfpw = pen().widthF() / 2;
|
|
7998 |
d->boundingRect = d->rect;
|
|
7999 |
if (halfpw > 0.0)
|
|
8000 |
d->boundingRect.adjust(-halfpw, -halfpw, halfpw, halfpw);
|
|
8001 |
}
|
|
8002 |
return d->boundingRect;
|
|
8003 |
}
|
|
8004 |
|
|
8005 |
/*!
|
|
8006 |
\reimp
|
|
8007 |
*/
|
|
8008 |
QPainterPath QGraphicsRectItem::shape() const
|
|
8009 |
{
|
|
8010 |
Q_D(const QGraphicsRectItem);
|
|
8011 |
QPainterPath path;
|
|
8012 |
path.addRect(d->rect);
|
|
8013 |
return qt_graphicsItem_shapeFromPath(path, d->pen);
|
|
8014 |
}
|
|
8015 |
|
|
8016 |
/*!
|
|
8017 |
\reimp
|
|
8018 |
*/
|
|
8019 |
bool QGraphicsRectItem::contains(const QPointF &point) const
|
|
8020 |
{
|
|
8021 |
return QAbstractGraphicsShapeItem::contains(point);
|
|
8022 |
}
|
|
8023 |
|
|
8024 |
/*!
|
|
8025 |
\reimp
|
|
8026 |
*/
|
|
8027 |
void QGraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|
8028 |
QWidget *widget)
|
|
8029 |
{
|
|
8030 |
Q_D(QGraphicsRectItem);
|
|
8031 |
Q_UNUSED(widget);
|
|
8032 |
painter->setPen(d->pen);
|
|
8033 |
painter->setBrush(d->brush);
|
|
8034 |
painter->drawRect(d->rect);
|
|
8035 |
|
|
8036 |
if (option->state & QStyle::State_Selected)
|
|
8037 |
qt_graphicsItem_highlightSelected(this, painter, option);
|
|
8038 |
}
|
|
8039 |
|
|
8040 |
/*!
|
|
8041 |
\reimp
|
|
8042 |
*/
|
|
8043 |
bool QGraphicsRectItem::isObscuredBy(const QGraphicsItem *item) const
|
|
8044 |
{
|
|
8045 |
return QAbstractGraphicsShapeItem::isObscuredBy(item);
|
|
8046 |
}
|
|
8047 |
|
|
8048 |
/*!
|
|
8049 |
\reimp
|
|
8050 |
*/
|
|
8051 |
QPainterPath QGraphicsRectItem::opaqueArea() const
|
|
8052 |
{
|
|
8053 |
return QAbstractGraphicsShapeItem::opaqueArea();
|
|
8054 |
}
|
|
8055 |
|
|
8056 |
/*!
|
|
8057 |
\reimp
|
|
8058 |
*/
|
|
8059 |
int QGraphicsRectItem::type() const
|
|
8060 |
{
|
|
8061 |
return Type;
|
|
8062 |
}
|
|
8063 |
|
|
8064 |
/*!
|
|
8065 |
\internal
|
|
8066 |
*/
|
|
8067 |
bool QGraphicsRectItem::supportsExtension(Extension extension) const
|
|
8068 |
{
|
|
8069 |
Q_UNUSED(extension);
|
|
8070 |
return false;
|
|
8071 |
}
|
|
8072 |
|
|
8073 |
/*!
|
|
8074 |
\internal
|
|
8075 |
*/
|
|
8076 |
void QGraphicsRectItem::setExtension(Extension extension, const QVariant &variant)
|
|
8077 |
{
|
|
8078 |
Q_UNUSED(extension);
|
|
8079 |
Q_UNUSED(variant);
|
|
8080 |
}
|
|
8081 |
|
|
8082 |
/*!
|
|
8083 |
\internal
|
|
8084 |
*/
|
|
8085 |
QVariant QGraphicsRectItem::extension(const QVariant &variant) const
|
|
8086 |
{
|
|
8087 |
Q_UNUSED(variant);
|
|
8088 |
return QVariant();
|
|
8089 |
}
|
|
8090 |
|
|
8091 |
/*!
|
|
8092 |
\class QGraphicsEllipseItem
|
|
8093 |
\brief The QGraphicsEllipseItem class provides an ellipse item that you
|
|
8094 |
can add to a QGraphicsScene.
|
|
8095 |
\since 4.2
|
|
8096 |
\ingroup graphicsview-api
|
|
8097 |
|
|
8098 |
QGraphicsEllipseItem respresents an ellipse with a fill and an outline,
|
|
8099 |
and you can also use it for ellipse segments (see startAngle(),
|
|
8100 |
spanAngle()).
|
|
8101 |
|
|
8102 |
\table
|
|
8103 |
\row
|
|
8104 |
\o \inlineimage graphicsview-ellipseitem.png
|
|
8105 |
\o \inlineimage graphicsview-ellipseitem-pie.png
|
|
8106 |
\endtable
|
|
8107 |
|
|
8108 |
To set the item's ellipse, pass a QRectF to QGraphicsEllipseItem's
|
|
8109 |
constructor, or call setRect(). The rect() function returns the
|
|
8110 |
current ellipse geometry.
|
|
8111 |
|
|
8112 |
QGraphicsEllipseItem uses the rect and the pen width to provide a
|
|
8113 |
reasonable implementation of boundingRect(), shape(), and contains(). The
|
|
8114 |
paint() function draws the ellipse using the item's associated pen and
|
|
8115 |
brush, which you can set by calling setPen() and setBrush().
|
|
8116 |
|
|
8117 |
\sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsPolygonItem,
|
|
8118 |
QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {The Graphics
|
|
8119 |
View Framework}
|
|
8120 |
*/
|
|
8121 |
|
|
8122 |
class QGraphicsEllipseItemPrivate : public QAbstractGraphicsShapeItemPrivate
|
|
8123 |
{
|
|
8124 |
Q_DECLARE_PUBLIC(QGraphicsEllipseItem)
|
|
8125 |
public:
|
|
8126 |
inline QGraphicsEllipseItemPrivate()
|
|
8127 |
: startAngle(0), spanAngle(360 * 16)
|
|
8128 |
{ }
|
|
8129 |
|
|
8130 |
QRectF rect;
|
|
8131 |
int startAngle;
|
|
8132 |
int spanAngle;
|
|
8133 |
};
|
|
8134 |
|
|
8135 |
/*!
|
|
8136 |
Constructs a QGraphicsEllipseItem using \a rect as the default rectangle.
|
|
8137 |
\a parent is passed to QAbstractGraphicsShapeItem's constructor.
|
|
8138 |
|
|
8139 |
\sa QGraphicsScene::addItem()
|
|
8140 |
*/
|
|
8141 |
QGraphicsEllipseItem::QGraphicsEllipseItem(const QRectF &rect, QGraphicsItem *parent
|
|
8142 |
#ifndef Q_QDOC
|
|
8143 |
// obsolete argument
|
|
8144 |
, QGraphicsScene *scene
|
|
8145 |
#endif
|
|
8146 |
)
|
|
8147 |
: QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
|
|
8148 |
{
|
|
8149 |
setRect(rect);
|
|
8150 |
}
|
|
8151 |
|
|
8152 |
/*!
|
|
8153 |
\fn QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent)
|
|
8154 |
\since 4.3
|
|
8155 |
|
|
8156 |
Constructs a QGraphicsEllipseItem using the rectangle defined by (\a x, \a
|
|
8157 |
y) and the given \a width and \a height, as the default rectangle. \a
|
|
8158 |
parent is passed to QAbstractGraphicsShapeItem's constructor.
|
|
8159 |
|
|
8160 |
\sa QGraphicsScene::addItem()
|
|
8161 |
*/
|
|
8162 |
QGraphicsEllipseItem::QGraphicsEllipseItem(qreal x, qreal y, qreal w, qreal h,
|
|
8163 |
QGraphicsItem *parent
|
|
8164 |
#ifndef Q_QDOC
|
|
8165 |
// obsolete argument
|
|
8166 |
, QGraphicsScene *scene
|
|
8167 |
#endif
|
|
8168 |
)
|
|
8169 |
: QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
|
|
8170 |
{
|
|
8171 |
setRect(x,y,w,h);
|
|
8172 |
}
|
|
8173 |
|
|
8174 |
|
|
8175 |
|
|
8176 |
/*!
|
|
8177 |
Constructs a QGraphicsEllipseItem. \a parent is passed to
|
|
8178 |
QAbstractGraphicsShapeItem's constructor.
|
|
8179 |
|
|
8180 |
\sa QGraphicsScene::addItem()
|
|
8181 |
*/
|
|
8182 |
QGraphicsEllipseItem::QGraphicsEllipseItem(QGraphicsItem *parent
|
|
8183 |
#ifndef Q_QDOC
|
|
8184 |
// obsolete argument
|
|
8185 |
, QGraphicsScene *scene
|
|
8186 |
#endif
|
|
8187 |
)
|
|
8188 |
: QAbstractGraphicsShapeItem(*new QGraphicsEllipseItemPrivate, parent, scene)
|
|
8189 |
{
|
|
8190 |
}
|
|
8191 |
|
|
8192 |
/*!
|
|
8193 |
Destroys the QGraphicsEllipseItem.
|
|
8194 |
*/
|
|
8195 |
QGraphicsEllipseItem::~QGraphicsEllipseItem()
|
|
8196 |
{
|
|
8197 |
}
|
|
8198 |
|
|
8199 |
/*!
|
|
8200 |
Returns the item's ellipse geometry as a QRectF.
|
|
8201 |
|
|
8202 |
\sa setRect(), QPainter::drawEllipse()
|
|
8203 |
*/
|
|
8204 |
QRectF QGraphicsEllipseItem::rect() const
|
|
8205 |
{
|
|
8206 |
Q_D(const QGraphicsEllipseItem);
|
|
8207 |
return d->rect;
|
|
8208 |
}
|
|
8209 |
|
|
8210 |
/*!
|
|
8211 |
Sets the item's ellipse geometry to \a rect. The rectangle's left edge
|
|
8212 |
defines the left edge of the ellipse, and the rectangle's top edge
|
|
8213 |
describes the top of the ellipse. The height and width of the rectangle
|
|
8214 |
describe the height and width of the ellipse.
|
|
8215 |
|
|
8216 |
\sa rect(), QPainter::drawEllipse()
|
|
8217 |
*/
|
|
8218 |
void QGraphicsEllipseItem::setRect(const QRectF &rect)
|
|
8219 |
{
|
|
8220 |
Q_D(QGraphicsEllipseItem);
|
|
8221 |
if (d->rect == rect)
|
|
8222 |
return;
|
|
8223 |
prepareGeometryChange();
|
|
8224 |
d->rect = rect;
|
|
8225 |
d->boundingRect = QRectF();
|
|
8226 |
update();
|
|
8227 |
}
|
|
8228 |
|
|
8229 |
/*!
|
|
8230 |
Returns the start angle for an ellipse segment in 16ths of a degree. This
|
|
8231 |
angle is used together with spanAngle() for representing an ellipse
|
|
8232 |
segment (a pie). By default, the start angle is 0.
|
|
8233 |
|
|
8234 |
\sa setStartAngle(), spanAngle()
|
|
8235 |
*/
|
|
8236 |
int QGraphicsEllipseItem::startAngle() const
|
|
8237 |
{
|
|
8238 |
Q_D(const QGraphicsEllipseItem);
|
|
8239 |
return d->startAngle;
|
|
8240 |
}
|
|
8241 |
|
|
8242 |
/*!
|
|
8243 |
Sets the start angle for an ellipse segment to \a angle, which is in 16ths
|
|
8244 |
of a degree. This angle is used together with spanAngle() for representing
|
|
8245 |
an ellipse segment (a pie). By default, the start angle is 0.
|
|
8246 |
|
|
8247 |
\sa startAngle(), setSpanAngle(), QPainter::drawPie()
|
|
8248 |
*/
|
|
8249 |
void QGraphicsEllipseItem::setStartAngle(int angle)
|
|
8250 |
{
|
|
8251 |
Q_D(QGraphicsEllipseItem);
|
|
8252 |
if (angle != d->startAngle) {
|
|
8253 |
prepareGeometryChange();
|
|
8254 |
d->boundingRect = QRectF();
|
|
8255 |
d->startAngle = angle;
|
|
8256 |
update();
|
|
8257 |
}
|
|
8258 |
}
|
|
8259 |
|
|
8260 |
/*!
|
|
8261 |
Returns the span angle of an ellipse segment in 16ths of a degree. This
|
|
8262 |
angle is used together with startAngle() for representing an ellipse
|
|
8263 |
segment (a pie). By default, this function returns 5760 (360 * 16, a full
|
|
8264 |
ellipse).
|
|
8265 |
|
|
8266 |
\sa setSpanAngle(), startAngle()
|
|
8267 |
*/
|
|
8268 |
int QGraphicsEllipseItem::spanAngle() const
|
|
8269 |
{
|
|
8270 |
Q_D(const QGraphicsEllipseItem);
|
|
8271 |
return d->spanAngle;
|
|
8272 |
}
|
|
8273 |
|
|
8274 |
/*!
|
|
8275 |
Sets the span angle for an ellipse segment to \a angle, which is in 16ths
|
|
8276 |
of a degree. This angle is used together with startAngle() to represent an
|
|
8277 |
ellipse segment (a pie). By default, the span angle is 5760 (360 * 16, a
|
|
8278 |
full ellipse).
|
|
8279 |
|
|
8280 |
\sa spanAngle(), setStartAngle(), QPainter::drawPie()
|
|
8281 |
*/
|
|
8282 |
void QGraphicsEllipseItem::setSpanAngle(int angle)
|
|
8283 |
{
|
|
8284 |
Q_D(QGraphicsEllipseItem);
|
|
8285 |
if (angle != d->spanAngle) {
|
|
8286 |
prepareGeometryChange();
|
|
8287 |
d->boundingRect = QRectF();
|
|
8288 |
d->spanAngle = angle;
|
|
8289 |
update();
|
|
8290 |
}
|
|
8291 |
}
|
|
8292 |
|
|
8293 |
/*!
|
|
8294 |
\reimp
|
|
8295 |
*/
|
|
8296 |
QRectF QGraphicsEllipseItem::boundingRect() const
|
|
8297 |
{
|
|
8298 |
Q_D(const QGraphicsEllipseItem);
|
|
8299 |
if (d->boundingRect.isNull()) {
|
|
8300 |
qreal pw = pen().widthF();
|
|
8301 |
if (pw == 0.0 && d->spanAngle == 360 * 16)
|
|
8302 |
d->boundingRect = d->rect;
|
|
8303 |
else
|
|
8304 |
d->boundingRect = shape().controlPointRect();
|
|
8305 |
}
|
|
8306 |
return d->boundingRect;
|
|
8307 |
}
|
|
8308 |
|
|
8309 |
/*!
|
|
8310 |
\reimp
|
|
8311 |
*/
|
|
8312 |
QPainterPath QGraphicsEllipseItem::shape() const
|
|
8313 |
{
|
|
8314 |
Q_D(const QGraphicsEllipseItem);
|
|
8315 |
QPainterPath path;
|
|
8316 |
if (d->rect.isNull())
|
|
8317 |
return path;
|
|
8318 |
if (d->spanAngle != 360 * 16) {
|
|
8319 |
path.moveTo(d->rect.center());
|
|
8320 |
path.arcTo(d->rect, d->startAngle / 16.0, d->spanAngle / 16.0);
|
|
8321 |
} else {
|
|
8322 |
path.addEllipse(d->rect);
|
|
8323 |
}
|
|
8324 |
|
|
8325 |
return qt_graphicsItem_shapeFromPath(path, d->pen);
|
|
8326 |
}
|
|
8327 |
|
|
8328 |
/*!
|
|
8329 |
\reimp
|
|
8330 |
*/
|
|
8331 |
bool QGraphicsEllipseItem::contains(const QPointF &point) const
|
|
8332 |
{
|
|
8333 |
return QAbstractGraphicsShapeItem::contains(point);
|
|
8334 |
}
|
|
8335 |
|
|
8336 |
/*!
|
|
8337 |
\reimp
|
|
8338 |
*/
|
|
8339 |
void QGraphicsEllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|
8340 |
QWidget *widget)
|
|
8341 |
{
|
|
8342 |
Q_D(QGraphicsEllipseItem);
|
|
8343 |
Q_UNUSED(widget);
|
|
8344 |
painter->setPen(d->pen);
|
|
8345 |
painter->setBrush(d->brush);
|
|
8346 |
if ((d->spanAngle != 0) && (qAbs(d->spanAngle) % (360 * 16) == 0))
|
|
8347 |
painter->drawEllipse(d->rect);
|
|
8348 |
else
|
|
8349 |
painter->drawPie(d->rect, d->startAngle, d->spanAngle);
|
|
8350 |
|
|
8351 |
if (option->state & QStyle::State_Selected)
|
|
8352 |
qt_graphicsItem_highlightSelected(this, painter, option);
|
|
8353 |
}
|
|
8354 |
|
|
8355 |
/*!
|
|
8356 |
\reimp
|
|
8357 |
*/
|
|
8358 |
bool QGraphicsEllipseItem::isObscuredBy(const QGraphicsItem *item) const
|
|
8359 |
{
|
|
8360 |
return QAbstractGraphicsShapeItem::isObscuredBy(item);
|
|
8361 |
}
|
|
8362 |
|
|
8363 |
/*!
|
|
8364 |
\reimp
|
|
8365 |
*/
|
|
8366 |
QPainterPath QGraphicsEllipseItem::opaqueArea() const
|
|
8367 |
{
|
|
8368 |
return QAbstractGraphicsShapeItem::opaqueArea();
|
|
8369 |
}
|
|
8370 |
|
|
8371 |
/*!
|
|
8372 |
\reimp
|
|
8373 |
*/
|
|
8374 |
int QGraphicsEllipseItem::type() const
|
|
8375 |
{
|
|
8376 |
return Type;
|
|
8377 |
}
|
|
8378 |
|
|
8379 |
|
|
8380 |
/*!
|
|
8381 |
\internal
|
|
8382 |
*/
|
|
8383 |
bool QGraphicsEllipseItem::supportsExtension(Extension extension) const
|
|
8384 |
{
|
|
8385 |
Q_UNUSED(extension);
|
|
8386 |
return false;
|
|
8387 |
}
|
|
8388 |
|
|
8389 |
/*!
|
|
8390 |
\internal
|
|
8391 |
*/
|
|
8392 |
void QGraphicsEllipseItem::setExtension(Extension extension, const QVariant &variant)
|
|
8393 |
{
|
|
8394 |
Q_UNUSED(extension);
|
|
8395 |
Q_UNUSED(variant);
|
|
8396 |
}
|
|
8397 |
|
|
8398 |
/*!
|
|
8399 |
\internal
|
|
8400 |
*/
|
|
8401 |
QVariant QGraphicsEllipseItem::extension(const QVariant &variant) const
|
|
8402 |
{
|
|
8403 |
Q_UNUSED(variant);
|
|
8404 |
return QVariant();
|
|
8405 |
}
|
|
8406 |
|
|
8407 |
/*!
|
|
8408 |
\class QGraphicsPolygonItem
|
|
8409 |
\brief The QGraphicsPolygonItem class provides a polygon item that you
|
|
8410 |
can add to a QGraphicsScene.
|
|
8411 |
\since 4.2
|
|
8412 |
\ingroup graphicsview-api
|
|
8413 |
|
|
8414 |
To set the item's polygon, pass a QPolygonF to
|
|
8415 |
QGraphicsPolygonItem's constructor, or call the setPolygon()
|
|
8416 |
function. The polygon() function returns the current polygon.
|
|
8417 |
|
|
8418 |
\image graphicsview-polygonitem.png
|
|
8419 |
|
|
8420 |
QGraphicsPolygonItem uses the polygon and the pen width to provide
|
|
8421 |
a reasonable implementation of boundingRect(), shape(), and
|
|
8422 |
contains(). The paint() function draws the polygon using the
|
|
8423 |
item's associated pen and brush, which you can set by calling the
|
|
8424 |
setPen() and setBrush() functions.
|
|
8425 |
|
|
8426 |
\sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
|
|
8427 |
QGraphicsTextItem, QGraphicsLineItem, QGraphicsPixmapItem, {The Graphics
|
|
8428 |
View Framework}
|
|
8429 |
*/
|
|
8430 |
|
|
8431 |
class QGraphicsPolygonItemPrivate : public QAbstractGraphicsShapeItemPrivate
|
|
8432 |
{
|
|
8433 |
Q_DECLARE_PUBLIC(QGraphicsPolygonItem)
|
|
8434 |
public:
|
|
8435 |
inline QGraphicsPolygonItemPrivate()
|
|
8436 |
: fillRule(Qt::OddEvenFill)
|
|
8437 |
{ }
|
|
8438 |
|
|
8439 |
QPolygonF polygon;
|
|
8440 |
Qt::FillRule fillRule;
|
|
8441 |
};
|
|
8442 |
|
|
8443 |
/*!
|
|
8444 |
Constructs a QGraphicsPolygonItem with \a polygon as the default
|
|
8445 |
polygon. \a parent is passed to QAbstractGraphicsShapeItem's constructor.
|
|
8446 |
|
|
8447 |
\sa QGraphicsScene::addItem()
|
|
8448 |
*/
|
|
8449 |
QGraphicsPolygonItem::QGraphicsPolygonItem(const QPolygonF &polygon,
|
|
8450 |
QGraphicsItem *parent
|
|
8451 |
#ifndef Q_QDOC
|
|
8452 |
// obsolete argument
|
|
8453 |
, QGraphicsScene *scene
|
|
8454 |
#endif
|
|
8455 |
)
|
|
8456 |
: QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
|
|
8457 |
{
|
|
8458 |
setPolygon(polygon);
|
|
8459 |
}
|
|
8460 |
|
|
8461 |
/*!
|
|
8462 |
Constructs a QGraphicsPolygonItem. \a parent is passed to
|
|
8463 |
QAbstractGraphicsShapeItem's constructor.
|
|
8464 |
|
|
8465 |
\sa QGraphicsScene::addItem()
|
|
8466 |
*/
|
|
8467 |
QGraphicsPolygonItem::QGraphicsPolygonItem(QGraphicsItem *parent
|
|
8468 |
#ifndef Q_QDOC
|
|
8469 |
// obsolete argument
|
|
8470 |
, QGraphicsScene *scene
|
|
8471 |
#endif
|
|
8472 |
)
|
|
8473 |
: QAbstractGraphicsShapeItem(*new QGraphicsPolygonItemPrivate, parent, scene)
|
|
8474 |
{
|
|
8475 |
}
|
|
8476 |
|
|
8477 |
/*!
|
|
8478 |
Destroys the QGraphicsPolygonItem.
|
|
8479 |
*/
|
|
8480 |
QGraphicsPolygonItem::~QGraphicsPolygonItem()
|
|
8481 |
{
|
|
8482 |
}
|
|
8483 |
|
|
8484 |
/*!
|
|
8485 |
Returns the item's polygon, or an empty polygon if no polygon
|
|
8486 |
has been set.
|
|
8487 |
|
|
8488 |
\sa setPolygon()
|
|
8489 |
*/
|
|
8490 |
QPolygonF QGraphicsPolygonItem::polygon() const
|
|
8491 |
{
|
|
8492 |
Q_D(const QGraphicsPolygonItem);
|
|
8493 |
return d->polygon;
|
|
8494 |
}
|
|
8495 |
|
|
8496 |
/*!
|
|
8497 |
Sets the item's polygon to be the given \a polygon.
|
|
8498 |
|
|
8499 |
\sa polygon()
|
|
8500 |
*/
|
|
8501 |
void QGraphicsPolygonItem::setPolygon(const QPolygonF &polygon)
|
|
8502 |
{
|
|
8503 |
Q_D(QGraphicsPolygonItem);
|
|
8504 |
if (d->polygon == polygon)
|
|
8505 |
return;
|
|
8506 |
prepareGeometryChange();
|
|
8507 |
d->polygon = polygon;
|
|
8508 |
d->boundingRect = QRectF();
|
|
8509 |
update();
|
|
8510 |
}
|
|
8511 |
|
|
8512 |
/*!
|
|
8513 |
Returns the fill rule of the polygon. The default fill rule is
|
|
8514 |
Qt::OddEvenFill.
|
|
8515 |
|
|
8516 |
\sa setFillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
|
|
8517 |
*/
|
|
8518 |
Qt::FillRule QGraphicsPolygonItem::fillRule() const
|
|
8519 |
{
|
|
8520 |
Q_D(const QGraphicsPolygonItem);
|
|
8521 |
return d->fillRule;
|
|
8522 |
}
|
|
8523 |
|
|
8524 |
/*!
|
|
8525 |
Sets the fill rule of the polygon to \a rule. The default fill rule is
|
|
8526 |
Qt::OddEvenFill.
|
|
8527 |
|
|
8528 |
\sa fillRule(), QPainterPath::fillRule(), QPainter::drawPolygon()
|
|
8529 |
*/
|
|
8530 |
void QGraphicsPolygonItem::setFillRule(Qt::FillRule rule)
|
|
8531 |
{
|
|
8532 |
Q_D(QGraphicsPolygonItem);
|
|
8533 |
if (rule != d->fillRule) {
|
|
8534 |
d->fillRule = rule;
|
|
8535 |
update();
|
|
8536 |
}
|
|
8537 |
}
|
|
8538 |
|
|
8539 |
/*!
|
|
8540 |
\reimp
|
|
8541 |
*/
|
|
8542 |
QRectF QGraphicsPolygonItem::boundingRect() const
|
|
8543 |
{
|
|
8544 |
Q_D(const QGraphicsPolygonItem);
|
|
8545 |
if (d->boundingRect.isNull()) {
|
|
8546 |
qreal pw = pen().widthF();
|
|
8547 |
if (pw == 0.0)
|
|
8548 |
d->boundingRect = d->polygon.boundingRect();
|
|
8549 |
else
|
|
8550 |
d->boundingRect = shape().controlPointRect();
|
|
8551 |
}
|
|
8552 |
return d->boundingRect;
|
|
8553 |
}
|
|
8554 |
|
|
8555 |
/*!
|
|
8556 |
\reimp
|
|
8557 |
*/
|
|
8558 |
QPainterPath QGraphicsPolygonItem::shape() const
|
|
8559 |
{
|
|
8560 |
Q_D(const QGraphicsPolygonItem);
|
|
8561 |
QPainterPath path;
|
|
8562 |
path.addPolygon(d->polygon);
|
|
8563 |
return qt_graphicsItem_shapeFromPath(path, d->pen);
|
|
8564 |
}
|
|
8565 |
|
|
8566 |
/*!
|
|
8567 |
\reimp
|
|
8568 |
*/
|
|
8569 |
bool QGraphicsPolygonItem::contains(const QPointF &point) const
|
|
8570 |
{
|
|
8571 |
return QAbstractGraphicsShapeItem::contains(point);
|
|
8572 |
}
|
|
8573 |
|
|
8574 |
/*!
|
|
8575 |
\reimp
|
|
8576 |
*/
|
|
8577 |
void QGraphicsPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
|
8578 |
{
|
|
8579 |
Q_D(QGraphicsPolygonItem);
|
|
8580 |
Q_UNUSED(widget);
|
|
8581 |
painter->setPen(d->pen);
|
|
8582 |
painter->setBrush(d->brush);
|
|
8583 |
painter->drawPolygon(d->polygon, d->fillRule);
|
|
8584 |
|
|
8585 |
if (option->state & QStyle::State_Selected)
|
|
8586 |
qt_graphicsItem_highlightSelected(this, painter, option);
|
|
8587 |
}
|
|
8588 |
|
|
8589 |
/*!
|
|
8590 |
\reimp
|
|
8591 |
*/
|
|
8592 |
bool QGraphicsPolygonItem::isObscuredBy(const QGraphicsItem *item) const
|
|
8593 |
{
|
|
8594 |
return QAbstractGraphicsShapeItem::isObscuredBy(item);
|
|
8595 |
}
|
|
8596 |
|
|
8597 |
/*!
|
|
8598 |
\reimp
|
|
8599 |
*/
|
|
8600 |
QPainterPath QGraphicsPolygonItem::opaqueArea() const
|
|
8601 |
{
|
|
8602 |
return QAbstractGraphicsShapeItem::opaqueArea();
|
|
8603 |
}
|
|
8604 |
|
|
8605 |
/*!
|
|
8606 |
\reimp
|
|
8607 |
*/
|
|
8608 |
int QGraphicsPolygonItem::type() const
|
|
8609 |
{
|
|
8610 |
return Type;
|
|
8611 |
}
|
|
8612 |
|
|
8613 |
/*!
|
|
8614 |
\internal
|
|
8615 |
*/
|
|
8616 |
bool QGraphicsPolygonItem::supportsExtension(Extension extension) const
|
|
8617 |
{
|
|
8618 |
Q_UNUSED(extension);
|
|
8619 |
return false;
|
|
8620 |
}
|
|
8621 |
|
|
8622 |
/*!
|
|
8623 |
\internal
|
|
8624 |
*/
|
|
8625 |
void QGraphicsPolygonItem::setExtension(Extension extension, const QVariant &variant)
|
|
8626 |
{
|
|
8627 |
Q_UNUSED(extension);
|
|
8628 |
Q_UNUSED(variant);
|
|
8629 |
}
|
|
8630 |
|
|
8631 |
/*!
|
|
8632 |
\internal
|
|
8633 |
*/
|
|
8634 |
QVariant QGraphicsPolygonItem::extension(const QVariant &variant) const
|
|
8635 |
{
|
|
8636 |
Q_UNUSED(variant);
|
|
8637 |
return QVariant();
|
|
8638 |
}
|
|
8639 |
|
|
8640 |
/*!
|
|
8641 |
\class QGraphicsLineItem
|
|
8642 |
\brief The QGraphicsLineItem class provides a line item that you can add to a
|
|
8643 |
QGraphicsScene.
|
|
8644 |
\since 4.2
|
|
8645 |
\ingroup graphicsview-api
|
|
8646 |
|
|
8647 |
To set the item's line, pass a QLineF to QGraphicsLineItem's
|
|
8648 |
constructor, or call the setLine() function. The line() function
|
|
8649 |
returns the current line. By default the line is black with a
|
|
8650 |
width of 0, but you can change this by calling setPen().
|
|
8651 |
|
|
8652 |
\img graphicsview-lineitem.png
|
|
8653 |
|
|
8654 |
QGraphicsLineItem uses the line and the pen width to provide a reasonable
|
|
8655 |
implementation of boundingRect(), shape(), and contains(). The paint()
|
|
8656 |
function draws the line using the item's associated pen.
|
|
8657 |
|
|
8658 |
\sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
|
|
8659 |
QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsPixmapItem, {The
|
|
8660 |
Graphics View Framework}
|
|
8661 |
*/
|
|
8662 |
|
|
8663 |
class QGraphicsLineItemPrivate : public QGraphicsItemPrivate
|
|
8664 |
{
|
|
8665 |
Q_DECLARE_PUBLIC(QGraphicsLineItem)
|
|
8666 |
public:
|
|
8667 |
QLineF line;
|
|
8668 |
QPen pen;
|
|
8669 |
};
|
|
8670 |
|
|
8671 |
/*!
|
|
8672 |
Constructs a QGraphicsLineItem, using \a line as the default line. \a
|
|
8673 |
parent is passed to QGraphicsItem's constructor.
|
|
8674 |
|
|
8675 |
\sa QGraphicsScene::addItem()
|
|
8676 |
*/
|
|
8677 |
QGraphicsLineItem::QGraphicsLineItem(const QLineF &line, QGraphicsItem *parent
|
|
8678 |
#ifndef Q_QDOC
|
|
8679 |
// obsolete argument
|
|
8680 |
, QGraphicsScene *scene
|
|
8681 |
#endif
|
|
8682 |
)
|
|
8683 |
: QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
|
|
8684 |
{
|
|
8685 |
setLine(line);
|
|
8686 |
}
|
|
8687 |
|
|
8688 |
/*!
|
|
8689 |
Constructs a QGraphicsLineItem, using the line between (\a x1, \a y1) and
|
|
8690 |
(\a x2, \a y2) as the default line. \a parent is passed to
|
|
8691 |
QGraphicsItem's constructor.
|
|
8692 |
|
|
8693 |
\sa QGraphicsScene::addItem()
|
|
8694 |
*/
|
|
8695 |
QGraphicsLineItem::QGraphicsLineItem(qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent
|
|
8696 |
#ifndef Q_QDOC
|
|
8697 |
// obsolete argument
|
|
8698 |
, QGraphicsScene *scene
|
|
8699 |
#endif
|
|
8700 |
)
|
|
8701 |
: QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
|
|
8702 |
{
|
|
8703 |
setLine(x1, y1, x2, y2);
|
|
8704 |
}
|
|
8705 |
|
|
8706 |
|
|
8707 |
|
|
8708 |
/*!
|
|
8709 |
Constructs a QGraphicsLineItem. \a parent is passed to QGraphicsItem's
|
|
8710 |
constructor.
|
|
8711 |
|
|
8712 |
\sa QGraphicsScene::addItem()
|
|
8713 |
*/
|
|
8714 |
QGraphicsLineItem::QGraphicsLineItem(QGraphicsItem *parent
|
|
8715 |
#ifndef Q_QDOC
|
|
8716 |
// obsolete argument
|
|
8717 |
, QGraphicsScene *scene
|
|
8718 |
#endif
|
|
8719 |
)
|
|
8720 |
: QGraphicsItem(*new QGraphicsLineItemPrivate, parent, scene)
|
|
8721 |
{
|
|
8722 |
}
|
|
8723 |
|
|
8724 |
/*!
|
|
8725 |
Destroys the QGraphicsLineItem.
|
|
8726 |
*/
|
|
8727 |
QGraphicsLineItem::~QGraphicsLineItem()
|
|
8728 |
{
|
|
8729 |
}
|
|
8730 |
|
|
8731 |
/*!
|
|
8732 |
Returns the item's pen, or a black solid 0-width pen if no pen has
|
|
8733 |
been set.
|
|
8734 |
|
|
8735 |
\sa setPen()
|
|
8736 |
*/
|
|
8737 |
QPen QGraphicsLineItem::pen() const
|
|
8738 |
{
|
|
8739 |
Q_D(const QGraphicsLineItem);
|
|
8740 |
return d->pen;
|
|
8741 |
}
|
|
8742 |
|
|
8743 |
/*!
|
|
8744 |
Sets the item's pen to \a pen. If no pen is set, the line will be painted
|
|
8745 |
using a black solid 0-width pen.
|
|
8746 |
|
|
8747 |
\sa pen()
|
|
8748 |
*/
|
|
8749 |
void QGraphicsLineItem::setPen(const QPen &pen)
|
|
8750 |
{
|
|
8751 |
Q_D(QGraphicsLineItem);
|
|
8752 |
prepareGeometryChange();
|
|
8753 |
d->pen = pen;
|
|
8754 |
update();
|
|
8755 |
}
|
|
8756 |
|
|
8757 |
/*!
|
|
8758 |
Returns the item's line, or a null line if no line has been set.
|
|
8759 |
|
|
8760 |
\sa setLine()
|
|
8761 |
*/
|
|
8762 |
QLineF QGraphicsLineItem::line() const
|
|
8763 |
{
|
|
8764 |
Q_D(const QGraphicsLineItem);
|
|
8765 |
return d->line;
|
|
8766 |
}
|
|
8767 |
|
|
8768 |
/*!
|
|
8769 |
Sets the item's line to be the given \a line.
|
|
8770 |
|
|
8771 |
\sa line()
|
|
8772 |
*/
|
|
8773 |
void QGraphicsLineItem::setLine(const QLineF &line)
|
|
8774 |
{
|
|
8775 |
Q_D(QGraphicsLineItem);
|
|
8776 |
if (d->line == line)
|
|
8777 |
return;
|
|
8778 |
prepareGeometryChange();
|
|
8779 |
d->line = line;
|
|
8780 |
update();
|
|
8781 |
}
|
|
8782 |
|
|
8783 |
/*!
|
|
8784 |
\fn void QGraphicsLineItem::setLine(qreal x1, qreal y1, qreal x2, qreal y2)
|
|
8785 |
\overload
|
|
8786 |
|
|
8787 |
Sets the item's line to be the line between (\a x1, \a y1) and (\a
|
|
8788 |
x2, \a y2).
|
|
8789 |
|
|
8790 |
This is the same as calling \c {setLine(QLineF(x1, y1, x2, y2))}.
|
|
8791 |
*/
|
|
8792 |
|
|
8793 |
/*!
|
|
8794 |
\reimp
|
|
8795 |
*/
|
|
8796 |
QRectF QGraphicsLineItem::boundingRect() const
|
|
8797 |
{
|
|
8798 |
Q_D(const QGraphicsLineItem);
|
|
8799 |
if (d->pen.widthF() == 0.0) {
|
|
8800 |
const qreal x1 = d->line.p1().x();
|
|
8801 |
const qreal x2 = d->line.p2().x();
|
|
8802 |
const qreal y1 = d->line.p1().y();
|
|
8803 |
const qreal y2 = d->line.p2().y();
|
|
8804 |
qreal lx = qMin(x1, x2);
|
|
8805 |
qreal rx = qMax(x1, x2);
|
|
8806 |
qreal ty = qMin(y1, y2);
|
|
8807 |
qreal by = qMax(y1, y2);
|
|
8808 |
return QRectF(lx, ty, rx - lx, by - ty);
|
|
8809 |
}
|
|
8810 |
return shape().controlPointRect();
|
|
8811 |
}
|
|
8812 |
|
|
8813 |
/*!
|
|
8814 |
\reimp
|
|
8815 |
*/
|
|
8816 |
QPainterPath QGraphicsLineItem::shape() const
|
|
8817 |
{
|
|
8818 |
Q_D(const QGraphicsLineItem);
|
|
8819 |
QPainterPath path;
|
|
8820 |
if (d->line == QLineF())
|
|
8821 |
return path;
|
|
8822 |
|
|
8823 |
path.moveTo(d->line.p1());
|
|
8824 |
path.lineTo(d->line.p2());
|
|
8825 |
return qt_graphicsItem_shapeFromPath(path, d->pen);
|
|
8826 |
}
|
|
8827 |
|
|
8828 |
/*!
|
|
8829 |
\reimp
|
|
8830 |
*/
|
|
8831 |
bool QGraphicsLineItem::contains(const QPointF &point) const
|
|
8832 |
{
|
|
8833 |
return QGraphicsItem::contains(point);
|
|
8834 |
}
|
|
8835 |
|
|
8836 |
/*!
|
|
8837 |
\reimp
|
|
8838 |
*/
|
|
8839 |
void QGraphicsLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
|
8840 |
{
|
|
8841 |
Q_D(QGraphicsLineItem);
|
|
8842 |
Q_UNUSED(widget);
|
|
8843 |
painter->setPen(d->pen);
|
|
8844 |
painter->drawLine(d->line);
|
|
8845 |
|
|
8846 |
if (option->state & QStyle::State_Selected)
|
|
8847 |
qt_graphicsItem_highlightSelected(this, painter, option);
|
|
8848 |
}
|
|
8849 |
|
|
8850 |
/*!
|
|
8851 |
\reimp
|
|
8852 |
*/
|
|
8853 |
bool QGraphicsLineItem::isObscuredBy(const QGraphicsItem *item) const
|
|
8854 |
{
|
|
8855 |
return QGraphicsItem::isObscuredBy(item);
|
|
8856 |
}
|
|
8857 |
|
|
8858 |
/*!
|
|
8859 |
\reimp
|
|
8860 |
*/
|
|
8861 |
QPainterPath QGraphicsLineItem::opaqueArea() const
|
|
8862 |
{
|
|
8863 |
return QGraphicsItem::opaqueArea();
|
|
8864 |
}
|
|
8865 |
|
|
8866 |
/*!
|
|
8867 |
\reimp
|
|
8868 |
*/
|
|
8869 |
int QGraphicsLineItem::type() const
|
|
8870 |
{
|
|
8871 |
return Type;
|
|
8872 |
}
|
|
8873 |
|
|
8874 |
/*!
|
|
8875 |
\internal
|
|
8876 |
*/
|
|
8877 |
bool QGraphicsLineItem::supportsExtension(Extension extension) const
|
|
8878 |
{
|
|
8879 |
Q_UNUSED(extension);
|
|
8880 |
return false;
|
|
8881 |
}
|
|
8882 |
|
|
8883 |
/*!
|
|
8884 |
\internal
|
|
8885 |
*/
|
|
8886 |
void QGraphicsLineItem::setExtension(Extension extension, const QVariant &variant)
|
|
8887 |
{
|
|
8888 |
Q_UNUSED(extension);
|
|
8889 |
Q_UNUSED(variant);
|
|
8890 |
}
|
|
8891 |
|
|
8892 |
/*!
|
|
8893 |
\internal
|
|
8894 |
*/
|
|
8895 |
QVariant QGraphicsLineItem::extension(const QVariant &variant) const
|
|
8896 |
{
|
|
8897 |
Q_UNUSED(variant);
|
|
8898 |
return QVariant();
|
|
8899 |
}
|
|
8900 |
|
|
8901 |
/*!
|
|
8902 |
\class QGraphicsPixmapItem
|
|
8903 |
\brief The QGraphicsPixmapItem class provides a pixmap item that you can add to
|
|
8904 |
a QGraphicsScene.
|
|
8905 |
\since 4.2
|
|
8906 |
\ingroup graphicsview-api
|
|
8907 |
|
|
8908 |
To set the item's pixmap, pass a QPixmap to QGraphicsPixmapItem's
|
|
8909 |
constructor, or call the setPixmap() function. The pixmap()
|
|
8910 |
function returns the current pixmap.
|
|
8911 |
|
|
8912 |
QGraphicsPixmapItem uses pixmap's optional alpha mask to provide a
|
|
8913 |
reasonable implementation of boundingRect(), shape(), and contains().
|
|
8914 |
|
|
8915 |
\image graphicsview-pixmapitem.png
|
|
8916 |
|
|
8917 |
The pixmap is drawn at the item's (0, 0) coordinate, as returned by
|
|
8918 |
offset(). You can change the drawing offset by calling setOffset().
|
|
8919 |
|
|
8920 |
You can set the pixmap's transformation mode by calling
|
|
8921 |
setTransformationMode(). By default, Qt::FastTransformation is used, which
|
|
8922 |
provides fast, non-smooth scaling. Qt::SmoothTransformation enables
|
|
8923 |
QPainter::SmoothPixmapTransform on the painter, and the quality depends on
|
|
8924 |
the platform and viewport. The result is usually not as good as calling
|
|
8925 |
QPixmap::scale() directly. Call transformationMode() to get the current
|
|
8926 |
transformation mode for the item.
|
|
8927 |
|
|
8928 |
\sa QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
|
|
8929 |
QGraphicsTextItem, QGraphicsPolygonItem, QGraphicsLineItem, {The
|
|
8930 |
Graphics View Framework}
|
|
8931 |
*/
|
|
8932 |
|
|
8933 |
/*!
|
|
8934 |
\enum QGraphicsPixmapItem::ShapeMode
|
|
8935 |
|
|
8936 |
This enum describes how QGraphicsPixmapItem calculates its shape and
|
|
8937 |
opaque area.
|
|
8938 |
|
|
8939 |
The default value is MaskShape.
|
|
8940 |
|
|
8941 |
\value MaskShape The shape is determined by calling QPixmap::mask().
|
|
8942 |
This shape includes only the opaque pixels of the pixmap.
|
|
8943 |
Because the shape is more complex, however, it can be slower than the other modes,
|
|
8944 |
and uses more memory.
|
|
8945 |
|
|
8946 |
\value BoundingRectShape The shape is determined by tracing the outline of
|
|
8947 |
the pixmap. This is the fastest shape mode, but it does not take into account
|
|
8948 |
any transparent areas on the pixmap.
|
|
8949 |
|
|
8950 |
\value HeuristicMaskShape The shape is determine by calling
|
|
8951 |
QPixmap::createHeuristicMask(). The performance and memory consumption
|
|
8952 |
is similar to MaskShape.
|
|
8953 |
*/
|
|
8954 |
extern QPainterPath qt_regionToPath(const QRegion ®ion);
|
|
8955 |
|
|
8956 |
class QGraphicsPixmapItemPrivate : public QGraphicsItemPrivate
|
|
8957 |
{
|
|
8958 |
Q_DECLARE_PUBLIC(QGraphicsPixmapItem)
|
|
8959 |
public:
|
|
8960 |
QGraphicsPixmapItemPrivate()
|
|
8961 |
: transformationMode(Qt::FastTransformation),
|
|
8962 |
shapeMode(QGraphicsPixmapItem::MaskShape),
|
|
8963 |
hasShape(false)
|
|
8964 |
{}
|
|
8965 |
|
|
8966 |
QPixmap pixmap;
|
|
8967 |
Qt::TransformationMode transformationMode;
|
|
8968 |
QPointF offset;
|
|
8969 |
QGraphicsPixmapItem::ShapeMode shapeMode;
|
|
8970 |
QPainterPath shape;
|
|
8971 |
bool hasShape;
|
|
8972 |
|
|
8973 |
void updateShape()
|
|
8974 |
{
|
|
8975 |
shape = QPainterPath();
|
|
8976 |
switch (shapeMode) {
|
|
8977 |
case QGraphicsPixmapItem::MaskShape: {
|
|
8978 |
QBitmap mask = pixmap.mask();
|
|
8979 |
if (!mask.isNull()) {
|
|
8980 |
shape = qt_regionToPath(QRegion(mask).translated(offset.toPoint()));
|
|
8981 |
break;
|
|
8982 |
}
|
|
8983 |
// FALL THROUGH
|
|
8984 |
}
|
|
8985 |
case QGraphicsPixmapItem::BoundingRectShape:
|
|
8986 |
shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
|
|
8987 |
break;
|
|
8988 |
case QGraphicsPixmapItem::HeuristicMaskShape:
|
|
8989 |
#ifndef QT_NO_IMAGE_HEURISTIC_MASK
|
|
8990 |
shape = qt_regionToPath(QRegion(pixmap.createHeuristicMask()).translated(offset.toPoint()));
|
|
8991 |
#else
|
|
8992 |
shape.addRect(QRectF(offset.x(), offset.y(), pixmap.width(), pixmap.height()));
|
|
8993 |
#endif
|
|
8994 |
break;
|
|
8995 |
}
|
|
8996 |
}
|
|
8997 |
};
|
|
8998 |
|
|
8999 |
/*!
|
|
9000 |
Constructs a QGraphicsPixmapItem, using \a pixmap as the default pixmap.
|
|
9001 |
\a parent is passed to QGraphicsItem's constructor.
|
|
9002 |
|
|
9003 |
\sa QGraphicsScene::addItem()
|
|
9004 |
*/
|
|
9005 |
QGraphicsPixmapItem::QGraphicsPixmapItem(const QPixmap &pixmap,
|
|
9006 |
QGraphicsItem *parent
|
|
9007 |
#ifndef Q_QDOC
|
|
9008 |
// obsolete argument
|
|
9009 |
, QGraphicsScene *scene
|
|
9010 |
#endif
|
|
9011 |
)
|
|
9012 |
: QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
|
|
9013 |
{
|
|
9014 |
setPixmap(pixmap);
|
|
9015 |
}
|
|
9016 |
|
|
9017 |
/*!
|
|
9018 |
Constructs a QGraphicsPixmapItem. \a parent is passed to QGraphicsItem's
|
|
9019 |
constructor.
|
|
9020 |
|
|
9021 |
\sa QGraphicsScene::addItem()
|
|
9022 |
*/
|
|
9023 |
QGraphicsPixmapItem::QGraphicsPixmapItem(QGraphicsItem *parent
|
|
9024 |
#ifndef Q_QDOC
|
|
9025 |
// obsolete argument
|
|
9026 |
, QGraphicsScene *scene
|
|
9027 |
#endif
|
|
9028 |
)
|
|
9029 |
: QGraphicsItem(*new QGraphicsPixmapItemPrivate, parent, scene)
|
|
9030 |
{
|
|
9031 |
}
|
|
9032 |
|
|
9033 |
/*!
|
|
9034 |
Destroys the QGraphicsPixmapItem.
|
|
9035 |
*/
|
|
9036 |
QGraphicsPixmapItem::~QGraphicsPixmapItem()
|
|
9037 |
{
|
|
9038 |
}
|
|
9039 |
|
|
9040 |
/*!
|
|
9041 |
Sets the item's pixmap to \a pixmap.
|
|
9042 |
|
|
9043 |
\sa pixmap()
|
|
9044 |
*/
|
|
9045 |
void QGraphicsPixmapItem::setPixmap(const QPixmap &pixmap)
|
|
9046 |
{
|
|
9047 |
Q_D(QGraphicsPixmapItem);
|
|
9048 |
prepareGeometryChange();
|
|
9049 |
d->pixmap = pixmap;
|
|
9050 |
d->hasShape = false;
|
|
9051 |
update();
|
|
9052 |
}
|
|
9053 |
|
|
9054 |
/*!
|
|
9055 |
Returns the item's pixmap, or an invalid QPixmap if no pixmap has been
|
|
9056 |
set.
|
|
9057 |
|
|
9058 |
\sa setPixmap()
|
|
9059 |
*/
|
|
9060 |
QPixmap QGraphicsPixmapItem::pixmap() const
|
|
9061 |
{
|
|
9062 |
Q_D(const QGraphicsPixmapItem);
|
|
9063 |
return d->pixmap;
|
|
9064 |
}
|
|
9065 |
|
|
9066 |
/*!
|
|
9067 |
Returns the transformation mode of the pixmap. The default mode is
|
|
9068 |
Qt::FastTransformation, which provides quick transformation with no
|
|
9069 |
smoothing.
|
|
9070 |
|
|
9071 |
\sa setTransformationMode()
|
|
9072 |
*/
|
|
9073 |
Qt::TransformationMode QGraphicsPixmapItem::transformationMode() const
|
|
9074 |
{
|
|
9075 |
Q_D(const QGraphicsPixmapItem);
|
|
9076 |
return d->transformationMode;
|
|
9077 |
}
|
|
9078 |
|
|
9079 |
/*!
|
|
9080 |
Sets the pixmap item's transformation mode to \a mode, and toggles an
|
|
9081 |
update of the item. The default mode is Qt::FastTransformation, which
|
|
9082 |
provides quick transformation with no smoothing.
|
|
9083 |
|
|
9084 |
Qt::SmoothTransformation enables QPainter::SmoothPixmapTransform on the
|
|
9085 |
painter, and the quality depends on the platform and viewport. The result
|
|
9086 |
is usually not as good as calling QPixmap::scale() directly.
|
|
9087 |
|
|
9088 |
\sa transformationMode()
|
|
9089 |
*/
|
|
9090 |
void QGraphicsPixmapItem::setTransformationMode(Qt::TransformationMode mode)
|
|
9091 |
{
|
|
9092 |
Q_D(QGraphicsPixmapItem);
|
|
9093 |
if (mode != d->transformationMode) {
|
|
9094 |
d->transformationMode = mode;
|
|
9095 |
update();
|
|
9096 |
}
|
|
9097 |
}
|
|
9098 |
|
|
9099 |
/*!
|
|
9100 |
Returns the pixmap item's \e offset, which defines the point of the
|
|
9101 |
top-left corner of the pixmap, in local coordinates.
|
|
9102 |
|
|
9103 |
\sa setOffset()
|
|
9104 |
*/
|
|
9105 |
QPointF QGraphicsPixmapItem::offset() const
|
|
9106 |
{
|
|
9107 |
Q_D(const QGraphicsPixmapItem);
|
|
9108 |
return d->offset;
|
|
9109 |
}
|
|
9110 |
|
|
9111 |
/*!
|
|
9112 |
Sets the pixmap item's offset to \a offset. QGraphicsPixmapItem will draw
|
|
9113 |
its pixmap using \a offset for its top-left corner.
|
|
9114 |
|
|
9115 |
\sa offset()
|
|
9116 |
*/
|
|
9117 |
void QGraphicsPixmapItem::setOffset(const QPointF &offset)
|
|
9118 |
{
|
|
9119 |
Q_D(QGraphicsPixmapItem);
|
|
9120 |
if (d->offset == offset)
|
|
9121 |
return;
|
|
9122 |
prepareGeometryChange();
|
|
9123 |
d->offset = offset;
|
|
9124 |
d->hasShape = false;
|
|
9125 |
update();
|
|
9126 |
}
|
|
9127 |
|
|
9128 |
/*!
|
|
9129 |
\fn void QGraphicsPixmapItem::setOffset(qreal x, qreal y)
|
|
9130 |
\since 4.3
|
|
9131 |
|
|
9132 |
This convenience function is equivalent to calling setOffset(QPointF(\a x, \a y)).
|
|
9133 |
*/
|
|
9134 |
|
|
9135 |
/*!
|
|
9136 |
\reimp
|
|
9137 |
*/
|
|
9138 |
QRectF QGraphicsPixmapItem::boundingRect() const
|
|
9139 |
{
|
|
9140 |
Q_D(const QGraphicsPixmapItem);
|
|
9141 |
qreal pw = 1.0;
|
|
9142 |
if (d->pixmap.isNull())
|
|
9143 |
return QRectF();
|
|
9144 |
return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
|
|
9145 |
}
|
|
9146 |
|
|
9147 |
/*!
|
|
9148 |
\reimp
|
|
9149 |
*/
|
|
9150 |
QPainterPath QGraphicsPixmapItem::shape() const
|
|
9151 |
{
|
|
9152 |
Q_D(const QGraphicsPixmapItem);
|
|
9153 |
if (!d->hasShape) {
|
|
9154 |
QGraphicsPixmapItemPrivate *thatD = const_cast<QGraphicsPixmapItemPrivate *>(d);
|
|
9155 |
thatD->updateShape();
|
|
9156 |
thatD->hasShape = true;
|
|
9157 |
}
|
|
9158 |
return d_func()->shape;
|
|
9159 |
}
|
|
9160 |
|
|
9161 |
/*!
|
|
9162 |
\reimp
|
|
9163 |
*/
|
|
9164 |
bool QGraphicsPixmapItem::contains(const QPointF &point) const
|
|
9165 |
{
|
|
9166 |
return QGraphicsItem::contains(point);
|
|
9167 |
}
|
|
9168 |
|
|
9169 |
/*!
|
|
9170 |
\reimp
|
|
9171 |
*/
|
|
9172 |
void QGraphicsPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|
9173 |
QWidget *widget)
|
|
9174 |
{
|
|
9175 |
Q_D(QGraphicsPixmapItem);
|
|
9176 |
Q_UNUSED(widget);
|
|
9177 |
|
|
9178 |
painter->setRenderHint(QPainter::SmoothPixmapTransform,
|
|
9179 |
(d->transformationMode == Qt::SmoothTransformation));
|
|
9180 |
|
|
9181 |
painter->drawPixmap(d->offset, d->pixmap);
|
|
9182 |
|
|
9183 |
if (option->state & QStyle::State_Selected)
|
|
9184 |
qt_graphicsItem_highlightSelected(this, painter, option);
|
|
9185 |
}
|
|
9186 |
|
|
9187 |
/*!
|
|
9188 |
\reimp
|
|
9189 |
*/
|
|
9190 |
bool QGraphicsPixmapItem::isObscuredBy(const QGraphicsItem *item) const
|
|
9191 |
{
|
|
9192 |
return QGraphicsItem::isObscuredBy(item);
|
|
9193 |
}
|
|
9194 |
|
|
9195 |
/*!
|
|
9196 |
\reimp
|
|
9197 |
*/
|
|
9198 |
QPainterPath QGraphicsPixmapItem::opaqueArea() const
|
|
9199 |
{
|
|
9200 |
return shape();
|
|
9201 |
}
|
|
9202 |
|
|
9203 |
/*!
|
|
9204 |
\reimp
|
|
9205 |
*/
|
|
9206 |
int QGraphicsPixmapItem::type() const
|
|
9207 |
{
|
|
9208 |
return Type;
|
|
9209 |
}
|
|
9210 |
|
|
9211 |
/*!
|
|
9212 |
Returns the item's shape mode. The shape mode describes how
|
|
9213 |
QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
|
|
9214 |
|
|
9215 |
\sa setShapeMode(), ShapeMode
|
|
9216 |
*/
|
|
9217 |
QGraphicsPixmapItem::ShapeMode QGraphicsPixmapItem::shapeMode() const
|
|
9218 |
{
|
|
9219 |
return d_func()->shapeMode;
|
|
9220 |
}
|
|
9221 |
|
|
9222 |
/*!
|
|
9223 |
Sets the item's shape mode to \a mode. The shape mode describes how
|
|
9224 |
QGraphicsPixmapItem calculates its shape. The default mode is MaskShape.
|
|
9225 |
|
|
9226 |
\sa shapeMode(), ShapeMode
|
|
9227 |
*/
|
|
9228 |
void QGraphicsPixmapItem::setShapeMode(ShapeMode mode)
|
|
9229 |
{
|
|
9230 |
Q_D(QGraphicsPixmapItem);
|
|
9231 |
if (d->shapeMode == mode)
|
|
9232 |
return;
|
|
9233 |
d->shapeMode = mode;
|
|
9234 |
d->hasShape = false;
|
|
9235 |
}
|
|
9236 |
|
|
9237 |
/*!
|
|
9238 |
\internal
|
|
9239 |
*/
|
|
9240 |
bool QGraphicsPixmapItem::supportsExtension(Extension extension) const
|
|
9241 |
{
|
|
9242 |
Q_UNUSED(extension);
|
|
9243 |
return false;
|
|
9244 |
}
|
|
9245 |
|
|
9246 |
/*!
|
|
9247 |
\internal
|
|
9248 |
*/
|
|
9249 |
void QGraphicsPixmapItem::setExtension(Extension extension, const QVariant &variant)
|
|
9250 |
{
|
|
9251 |
Q_UNUSED(extension);
|
|
9252 |
Q_UNUSED(variant);
|
|
9253 |
}
|
|
9254 |
|
|
9255 |
/*!
|
|
9256 |
\internal
|
|
9257 |
*/
|
|
9258 |
QVariant QGraphicsPixmapItem::extension(const QVariant &variant) const
|
|
9259 |
{
|
|
9260 |
Q_UNUSED(variant);
|
|
9261 |
return QVariant();
|
|
9262 |
}
|
|
9263 |
|
|
9264 |
/*!
|
|
9265 |
\class QGraphicsTextItem
|
|
9266 |
\brief The QGraphicsTextItem class provides a text item that you can add to
|
|
9267 |
a QGraphicsScene to display formatted text.
|
|
9268 |
\since 4.2
|
|
9269 |
\ingroup graphicsview-api
|
|
9270 |
|
|
9271 |
If you only need to show plain text in an item, consider using QGraphicsSimpleTextItem
|
|
9272 |
instead.
|
|
9273 |
|
|
9274 |
To set the item's text, pass a QString to QGraphicsTextItem's
|
|
9275 |
constructor, or call setHtml()/setPlainText().
|
|
9276 |
|
|
9277 |
QGraphicsTextItem uses the text's formatted size and the associated font
|
|
9278 |
to provide a reasonable implementation of boundingRect(), shape(),
|
|
9279 |
and contains(). You can set the font by calling setFont().
|
|
9280 |
|
|
9281 |
It is possible to make the item editable by setting the Qt::TextEditorInteraction flag
|
|
9282 |
using setTextInteractionFlags().
|
|
9283 |
|
|
9284 |
The item's preferred text width can be set using setTextWidth() and obtained
|
|
9285 |
using textWidth().
|
|
9286 |
|
|
9287 |
\note In order to align HTML text in the center, the item's text width must be set.
|
|
9288 |
|
|
9289 |
\img graphicsview-textitem.png
|
|
9290 |
|
|
9291 |
\note QGraphicsTextItem accepts \l{QGraphicsItem::acceptHoverEvents()}{hover events}
|
|
9292 |
by default. You can change this with \l{QGraphicsItem::}{setAcceptHoverEvents()}.
|
|
9293 |
|
|
9294 |
\sa QGraphicsSimpleTextItem, QGraphicsPathItem, QGraphicsRectItem,
|
|
9295 |
QGraphicsEllipseItem, QGraphicsPixmapItem, QGraphicsPolygonItem,
|
|
9296 |
QGraphicsLineItem, {The Graphics View Framework}
|
|
9297 |
*/
|
|
9298 |
|
|
9299 |
class QGraphicsTextItemPrivate
|
|
9300 |
{
|
|
9301 |
public:
|
|
9302 |
QGraphicsTextItemPrivate()
|
|
9303 |
: control(0), pageNumber(0), useDefaultImpl(false), tabChangesFocus(false), clickCausedFocus(0)
|
|
9304 |
{ }
|
|
9305 |
|
|
9306 |
mutable QTextControl *control;
|
|
9307 |
QTextControl *textControl() const;
|
|
9308 |
|
|
9309 |
inline QPointF controlOffset() const
|
|
9310 |
{ return QPointF(0., pageNumber * control->document()->pageSize().height()); }
|
|
9311 |
inline void sendControlEvent(QEvent *e)
|
|
9312 |
{ if (control) control->processEvent(e, controlOffset()); }
|
|
9313 |
|
|
9314 |
void _q_updateBoundingRect(const QSizeF &);
|
|
9315 |
void _q_update(QRectF);
|
|
9316 |
void _q_ensureVisible(QRectF);
|
|
9317 |
bool _q_mouseOnEdge(QGraphicsSceneMouseEvent *);
|
|
9318 |
|
|
9319 |
QRectF boundingRect;
|
|
9320 |
int pageNumber;
|
|
9321 |
bool useDefaultImpl;
|
|
9322 |
bool tabChangesFocus;
|
|
9323 |
|
|
9324 |
uint clickCausedFocus : 1;
|
|
9325 |
|
|
9326 |
QGraphicsTextItem *qq;
|
|
9327 |
};
|
|
9328 |
|
|
9329 |
|
|
9330 |
/*!
|
|
9331 |
Constructs a QGraphicsTextItem, using \a text as the default plain
|
|
9332 |
text. \a parent is passed to QGraphicsItem's constructor.
|
|
9333 |
|
|
9334 |
\sa QGraphicsScene::addItem()
|
|
9335 |
*/
|
|
9336 |
QGraphicsTextItem::QGraphicsTextItem(const QString &text, QGraphicsItem *parent
|
|
9337 |
#ifndef Q_QDOC
|
|
9338 |
// obsolete argument
|
|
9339 |
, QGraphicsScene *scene
|
|
9340 |
#endif
|
|
9341 |
)
|
|
9342 |
: QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
|
|
9343 |
{
|
|
9344 |
dd->qq = this;
|
|
9345 |
if (!text.isEmpty())
|
|
9346 |
setPlainText(text);
|
|
9347 |
setAcceptDrops(true);
|
|
9348 |
setAcceptHoverEvents(true);
|
|
9349 |
setFlags(ItemUsesExtendedStyleOption);
|
|
9350 |
}
|
|
9351 |
|
|
9352 |
/*!
|
|
9353 |
Constructs a QGraphicsTextItem. \a parent is passed to QGraphicsItem's
|
|
9354 |
constructor.
|
|
9355 |
|
|
9356 |
\sa QGraphicsScene::addItem()
|
|
9357 |
*/
|
|
9358 |
QGraphicsTextItem::QGraphicsTextItem(QGraphicsItem *parent
|
|
9359 |
#ifndef Q_QDOC
|
|
9360 |
// obsolete argument
|
|
9361 |
, QGraphicsScene *scene
|
|
9362 |
#endif
|
|
9363 |
)
|
|
9364 |
: QGraphicsObject(*new QGraphicsItemPrivate, parent, scene), dd(new QGraphicsTextItemPrivate)
|
|
9365 |
{
|
|
9366 |
dd->qq = this;
|
|
9367 |
setAcceptDrops(true);
|
|
9368 |
setAcceptHoverEvents(true);
|
|
9369 |
setFlag(ItemUsesExtendedStyleOption);
|
|
9370 |
}
|
|
9371 |
|
|
9372 |
/*!
|
|
9373 |
Destroys the QGraphicsTextItem.
|
|
9374 |
*/
|
|
9375 |
QGraphicsTextItem::~QGraphicsTextItem()
|
|
9376 |
{
|
|
9377 |
delete dd;
|
|
9378 |
}
|
|
9379 |
|
|
9380 |
/*!
|
|
9381 |
Returns the item's text converted to HTML, or an empty QString if no text has been set.
|
|
9382 |
|
|
9383 |
\sa setHtml()
|
|
9384 |
*/
|
|
9385 |
QString QGraphicsTextItem::toHtml() const
|
|
9386 |
{
|
|
9387 |
#ifndef QT_NO_TEXTHTMLPARSER
|
|
9388 |
if (dd->control)
|
|
9389 |
return dd->control->toHtml();
|
|
9390 |
#endif
|
|
9391 |
return QString();
|
|
9392 |
}
|
|
9393 |
|
|
9394 |
/*!
|
|
9395 |
Sets the item's text to \a text, assuming that text is HTML formatted. If
|
|
9396 |
the item has keyboard input focus, this function will also call
|
|
9397 |
ensureVisible() to ensure that the text is visible in all viewports.
|
|
9398 |
|
|
9399 |
\sa toHtml(), hasFocus(), QGraphicsSimpleTextItem
|
|
9400 |
*/
|
|
9401 |
void QGraphicsTextItem::setHtml(const QString &text)
|
|
9402 |
{
|
|
9403 |
dd->textControl()->setHtml(text);
|
|
9404 |
}
|
|
9405 |
|
|
9406 |
/*!
|
|
9407 |
Returns the item's text converted to plain text, or an empty QString if no text has been set.
|
|
9408 |
|
|
9409 |
\sa setPlainText()
|
|
9410 |
*/
|
|
9411 |
QString QGraphicsTextItem::toPlainText() const
|
|
9412 |
{
|
|
9413 |
if (dd->control)
|
|
9414 |
return dd->control->toPlainText();
|
|
9415 |
return QString();
|
|
9416 |
}
|
|
9417 |
|
|
9418 |
/*!
|
|
9419 |
Sets the item's text to \a text. If the item has keyboard input focus,
|
|
9420 |
this function will also call ensureVisible() to ensure that the text is
|
|
9421 |
visible in all viewports.
|
|
9422 |
|
|
9423 |
\sa toHtml(), hasFocus()
|
|
9424 |
*/
|
|
9425 |
void QGraphicsTextItem::setPlainText(const QString &text)
|
|
9426 |
{
|
|
9427 |
dd->textControl()->setPlainText(text);
|
|
9428 |
}
|
|
9429 |
|
|
9430 |
/*!
|
|
9431 |
Returns the item's font, which is used to render the text.
|
|
9432 |
|
|
9433 |
\sa setFont()
|
|
9434 |
*/
|
|
9435 |
QFont QGraphicsTextItem::font() const
|
|
9436 |
{
|
|
9437 |
if (!dd->control)
|
|
9438 |
return QFont();
|
|
9439 |
return dd->control->document()->defaultFont();
|
|
9440 |
}
|
|
9441 |
|
|
9442 |
/*!
|
|
9443 |
Sets the font used to render the text item to \a font.
|
|
9444 |
|
|
9445 |
\sa font()
|
|
9446 |
*/
|
|
9447 |
void QGraphicsTextItem::setFont(const QFont &font)
|
|
9448 |
{
|
|
9449 |
dd->textControl()->document()->setDefaultFont(font);
|
|
9450 |
}
|
|
9451 |
|
|
9452 |
/*!
|
|
9453 |
Sets the color for unformatted text to \a col.
|
|
9454 |
*/
|
|
9455 |
void QGraphicsTextItem::setDefaultTextColor(const QColor &col)
|
|
9456 |
{
|
|
9457 |
QTextControl *c = dd->textControl();
|
|
9458 |
QPalette pal = c->palette();
|
|
9459 |
pal.setColor(QPalette::Text, col);
|
|
9460 |
c->setPalette(pal);
|
|
9461 |
}
|
|
9462 |
|
|
9463 |
/*!
|
|
9464 |
Returns the default text color that is used to for unformatted text.
|
|
9465 |
*/
|
|
9466 |
QColor QGraphicsTextItem::defaultTextColor() const
|
|
9467 |
{
|
|
9468 |
return dd->textControl()->palette().color(QPalette::Text);
|
|
9469 |
}
|
|
9470 |
|
|
9471 |
/*!
|
|
9472 |
\reimp
|
|
9473 |
*/
|
|
9474 |
QRectF QGraphicsTextItem::boundingRect() const
|
|
9475 |
{
|
|
9476 |
return dd->boundingRect;
|
|
9477 |
}
|
|
9478 |
|
|
9479 |
/*!
|
|
9480 |
\reimp
|
|
9481 |
*/
|
|
9482 |
QPainterPath QGraphicsTextItem::shape() const
|
|
9483 |
{
|
|
9484 |
if (!dd->control)
|
|
9485 |
return QPainterPath();
|
|
9486 |
QPainterPath path;
|
|
9487 |
path.addRect(dd->boundingRect);
|
|
9488 |
return path;
|
|
9489 |
}
|
|
9490 |
|
|
9491 |
/*!
|
|
9492 |
\reimp
|
|
9493 |
*/
|
|
9494 |
bool QGraphicsTextItem::contains(const QPointF &point) const
|
|
9495 |
{
|
|
9496 |
return dd->boundingRect.contains(point);
|
|
9497 |
}
|
|
9498 |
|
|
9499 |
/*!
|
|
9500 |
\reimp
|
|
9501 |
*/
|
|
9502 |
void QGraphicsTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|
9503 |
QWidget *widget)
|
|
9504 |
{
|
|
9505 |
Q_UNUSED(widget);
|
|
9506 |
if (dd->control) {
|
|
9507 |
painter->save();
|
|
9508 |
QRectF r = option->exposedRect;
|
|
9509 |
painter->translate(-dd->controlOffset());
|
|
9510 |
r.translate(dd->controlOffset());
|
|
9511 |
|
|
9512 |
QTextDocument *doc = dd->control->document();
|
|
9513 |
QTextDocumentLayout *layout = qobject_cast<QTextDocumentLayout *>(doc->documentLayout());
|
|
9514 |
|
|
9515 |
// the layout might need to expand the root frame to
|
|
9516 |
// the viewport if NoWrap is set
|
|
9517 |
if (layout)
|
|
9518 |
layout->setViewport(dd->boundingRect);
|
|
9519 |
|
|
9520 |
dd->control->drawContents(painter, r);
|
|
9521 |
|
|
9522 |
if (layout)
|
|
9523 |
layout->setViewport(QRect());
|
|
9524 |
|
|
9525 |
painter->restore();
|
|
9526 |
}
|
|
9527 |
|
|
9528 |
if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
|
|
9529 |
qt_graphicsItem_highlightSelected(this, painter, option);
|
|
9530 |
}
|
|
9531 |
|
|
9532 |
/*!
|
|
9533 |
\reimp
|
|
9534 |
*/
|
|
9535 |
bool QGraphicsTextItem::isObscuredBy(const QGraphicsItem *item) const
|
|
9536 |
{
|
|
9537 |
return QGraphicsItem::isObscuredBy(item);
|
|
9538 |
}
|
|
9539 |
|
|
9540 |
/*!
|
|
9541 |
\reimp
|
|
9542 |
*/
|
|
9543 |
QPainterPath QGraphicsTextItem::opaqueArea() const
|
|
9544 |
{
|
|
9545 |
return QGraphicsItem::opaqueArea();
|
|
9546 |
}
|
|
9547 |
|
|
9548 |
/*!
|
|
9549 |
\reimp
|
|
9550 |
*/
|
|
9551 |
int QGraphicsTextItem::type() const
|
|
9552 |
{
|
|
9553 |
return Type;
|
|
9554 |
}
|
|
9555 |
|
|
9556 |
/*!
|
|
9557 |
Sets the preferred width for the item's text. If the actual text
|
|
9558 |
is wider than the specified width then it will be broken into
|
|
9559 |
multiple lines.
|
|
9560 |
|
|
9561 |
If \a width is set to -1 then the text will not be broken into
|
|
9562 |
multiple lines unless it is enforced through an explicit line
|
|
9563 |
break or a new paragraph.
|
|
9564 |
|
|
9565 |
The default value is -1.
|
|
9566 |
|
|
9567 |
Note that QGraphicsTextItem keeps a QTextDocument internally,
|
|
9568 |
which is used to calculate the text width.
|
|
9569 |
|
|
9570 |
\sa textWidth(), QTextDocument::setTextWidth()
|
|
9571 |
*/
|
|
9572 |
void QGraphicsTextItem::setTextWidth(qreal width)
|
|
9573 |
{
|
|
9574 |
dd->textControl()->setTextWidth(width);
|
|
9575 |
}
|
|
9576 |
|
|
9577 |
/*!
|
|
9578 |
Returns the text width.
|
|
9579 |
|
|
9580 |
The width is calculated with the QTextDocument that
|
|
9581 |
QGraphicsTextItem keeps internally.
|
|
9582 |
|
|
9583 |
\sa setTextWidth(), QTextDocument::textWidth()
|
|
9584 |
*/
|
|
9585 |
qreal QGraphicsTextItem::textWidth() const
|
|
9586 |
{
|
|
9587 |
if (!dd->control)
|
|
9588 |
return -1;
|
|
9589 |
return dd->control->textWidth();
|
|
9590 |
}
|
|
9591 |
|
|
9592 |
/*!
|
|
9593 |
Adjusts the text item to a reasonable size.
|
|
9594 |
*/
|
|
9595 |
void QGraphicsTextItem::adjustSize()
|
|
9596 |
{
|
|
9597 |
if (dd->control)
|
|
9598 |
dd->control->adjustSize();
|
|
9599 |
}
|
|
9600 |
|
|
9601 |
/*!
|
|
9602 |
Sets the text document \a document on the item.
|
|
9603 |
*/
|
|
9604 |
void QGraphicsTextItem::setDocument(QTextDocument *document)
|
|
9605 |
{
|
|
9606 |
dd->textControl()->setDocument(document);
|
|
9607 |
dd->_q_updateBoundingRect(dd->control->size());
|
|
9608 |
}
|
|
9609 |
|
|
9610 |
/*!
|
|
9611 |
Returns the item's text document.
|
|
9612 |
*/
|
|
9613 |
QTextDocument *QGraphicsTextItem::document() const
|
|
9614 |
{
|
|
9615 |
return dd->textControl()->document();
|
|
9616 |
}
|
|
9617 |
|
|
9618 |
/*!
|
|
9619 |
\reimp
|
|
9620 |
*/
|
|
9621 |
bool QGraphicsTextItem::sceneEvent(QEvent *event)
|
|
9622 |
{
|
|
9623 |
QEvent::Type t = event->type();
|
|
9624 |
if (!dd->tabChangesFocus && (t == QEvent::KeyPress || t == QEvent::KeyRelease)) {
|
|
9625 |
int k = ((QKeyEvent *)event)->key();
|
|
9626 |
if (k == Qt::Key_Tab || k == Qt::Key_Backtab) {
|
|
9627 |
dd->sendControlEvent(event);
|
|
9628 |
return true;
|
|
9629 |
}
|
|
9630 |
}
|
|
9631 |
bool result = QGraphicsItem::sceneEvent(event);
|
|
9632 |
|
|
9633 |
// Ensure input context is updated.
|
|
9634 |
switch (event->type()) {
|
|
9635 |
case QEvent::ContextMenu:
|
|
9636 |
case QEvent::FocusIn:
|
|
9637 |
case QEvent::FocusOut:
|
|
9638 |
case QEvent::GraphicsSceneDragEnter:
|
|
9639 |
case QEvent::GraphicsSceneDragLeave:
|
|
9640 |
case QEvent::GraphicsSceneDragMove:
|
|
9641 |
case QEvent::GraphicsSceneDrop:
|
|
9642 |
case QEvent::GraphicsSceneHoverEnter:
|
|
9643 |
case QEvent::GraphicsSceneHoverLeave:
|
|
9644 |
case QEvent::GraphicsSceneHoverMove:
|
|
9645 |
case QEvent::GraphicsSceneMouseDoubleClick:
|
|
9646 |
case QEvent::GraphicsSceneMousePress:
|
|
9647 |
case QEvent::GraphicsSceneMouseMove:
|
|
9648 |
case QEvent::GraphicsSceneMouseRelease:
|
|
9649 |
case QEvent::KeyPress:
|
|
9650 |
case QEvent::KeyRelease:
|
|
9651 |
// Reset the focus widget's input context, regardless
|
|
9652 |
// of how this item gained or lost focus.
|
|
9653 |
if (QWidget *fw = qApp->focusWidget()) {
|
|
9654 |
if (QInputContext *qic = fw->inputContext()) {
|
|
9655 |
if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut)
|
|
9656 |
qic->reset();
|
|
9657 |
else
|
|
9658 |
qic->update();
|
|
9659 |
}
|
|
9660 |
}
|
|
9661 |
break;
|
|
9662 |
default:
|
|
9663 |
break;
|
|
9664 |
}
|
|
9665 |
|
|
9666 |
return result;
|
|
9667 |
}
|
|
9668 |
|
|
9669 |
/*!
|
|
9670 |
\reimp
|
|
9671 |
*/
|
|
9672 |
void QGraphicsTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|
9673 |
{
|
|
9674 |
if ((QGraphicsItem::d_ptr->flags & (ItemIsSelectable | ItemIsMovable))
|
|
9675 |
&& (event->buttons() & Qt::LeftButton) && dd->_q_mouseOnEdge(event)) {
|
|
9676 |
// User left-pressed on edge of selectable/movable item, use
|
|
9677 |
// base impl.
|
|
9678 |
dd->useDefaultImpl = true;
|
|
9679 |
} else if (event->buttons() == event->button()
|
|
9680 |
&& dd->control->textInteractionFlags() == Qt::NoTextInteraction) {
|
|
9681 |
// User pressed first button on non-interactive item.
|
|
9682 |
dd->useDefaultImpl = true;
|
|
9683 |
}
|
|
9684 |
if (dd->useDefaultImpl) {
|
|
9685 |
QGraphicsItem::mousePressEvent(event);
|
|
9686 |
if (!event->isAccepted())
|
|
9687 |
dd->useDefaultImpl = false;
|
|
9688 |
return;
|
|
9689 |
}
|
|
9690 |
|
|
9691 |
dd->sendControlEvent(event);
|
|
9692 |
}
|
|
9693 |
|
|
9694 |
/*!
|
|
9695 |
\reimp
|
|
9696 |
*/
|
|
9697 |
void QGraphicsTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|
9698 |
{
|
|
9699 |
if (dd->useDefaultImpl) {
|
|
9700 |
QGraphicsItem::mouseMoveEvent(event);
|
|
9701 |
return;
|
|
9702 |
}
|
|
9703 |
|
|
9704 |
dd->sendControlEvent(event);
|
|
9705 |
}
|
|
9706 |
|
|
9707 |
/*!
|
|
9708 |
\reimp
|
|
9709 |
*/
|
|
9710 |
void QGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|
9711 |
{
|
|
9712 |
if (dd->useDefaultImpl) {
|
|
9713 |
QGraphicsItem::mouseReleaseEvent(event);
|
|
9714 |
if (dd->control->textInteractionFlags() == Qt::NoTextInteraction
|
|
9715 |
&& !event->buttons()) {
|
|
9716 |
// User released last button on non-interactive item.
|
|
9717 |
dd->useDefaultImpl = false;
|
|
9718 |
} else if ((event->buttons() & Qt::LeftButton) == 0) {
|
|
9719 |
// User released the left button on an interactive item.
|
|
9720 |
dd->useDefaultImpl = false;
|
|
9721 |
}
|
|
9722 |
return;
|
|
9723 |
}
|
|
9724 |
|
|
9725 |
QWidget *widget = event->widget();
|
|
9726 |
if (widget) {
|
|
9727 |
qt_widget_private(widget)->handleSoftwareInputPanel(event->button(), dd->clickCausedFocus);
|
|
9728 |
}
|
|
9729 |
dd->clickCausedFocus = 0;
|
|
9730 |
dd->sendControlEvent(event);
|
|
9731 |
}
|
|
9732 |
|
|
9733 |
/*!
|
|
9734 |
\reimp
|
|
9735 |
*/
|
|
9736 |
void QGraphicsTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
|
|
9737 |
{
|
|
9738 |
if (dd->useDefaultImpl) {
|
|
9739 |
QGraphicsItem::mouseDoubleClickEvent(event);
|
|
9740 |
return;
|
|
9741 |
}
|
|
9742 |
|
|
9743 |
if (!hasFocus()) {
|
|
9744 |
QGraphicsItem::mouseDoubleClickEvent(event);
|
|
9745 |
return;
|
|
9746 |
}
|
|
9747 |
|
|
9748 |
dd->sendControlEvent(event);
|
|
9749 |
}
|
|
9750 |
|
|
9751 |
/*!
|
|
9752 |
\reimp
|
|
9753 |
*/
|
|
9754 |
void QGraphicsTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
|
|
9755 |
{
|
|
9756 |
dd->sendControlEvent(event);
|
|
9757 |
}
|
|
9758 |
|
|
9759 |
/*!
|
|
9760 |
\reimp
|
|
9761 |
*/
|
|
9762 |
void QGraphicsTextItem::keyPressEvent(QKeyEvent *event)
|
|
9763 |
{
|
|
9764 |
dd->sendControlEvent(event);
|
|
9765 |
}
|
|
9766 |
|
|
9767 |
/*!
|
|
9768 |
\reimp
|
|
9769 |
*/
|
|
9770 |
void QGraphicsTextItem::keyReleaseEvent(QKeyEvent *event)
|
|
9771 |
{
|
|
9772 |
dd->sendControlEvent(event);
|
|
9773 |
}
|
|
9774 |
|
|
9775 |
/*!
|
|
9776 |
\reimp
|
|
9777 |
*/
|
|
9778 |
void QGraphicsTextItem::focusInEvent(QFocusEvent *event)
|
|
9779 |
{
|
|
9780 |
dd->sendControlEvent(event);
|
|
9781 |
if (event->reason() == Qt::MouseFocusReason) {
|
|
9782 |
dd->clickCausedFocus = 1;
|
|
9783 |
}
|
|
9784 |
update();
|
|
9785 |
}
|
|
9786 |
|
|
9787 |
/*!
|
|
9788 |
\reimp
|
|
9789 |
*/
|
|
9790 |
void QGraphicsTextItem::focusOutEvent(QFocusEvent *event)
|
|
9791 |
{
|
|
9792 |
dd->sendControlEvent(event);
|
|
9793 |
update();
|
|
9794 |
}
|
|
9795 |
|
|
9796 |
/*!
|
|
9797 |
\reimp
|
|
9798 |
*/
|
|
9799 |
void QGraphicsTextItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
|
|
9800 |
{
|
|
9801 |
dd->sendControlEvent(event);
|
|
9802 |
}
|
|
9803 |
|
|
9804 |
/*!
|
|
9805 |
\reimp
|
|
9806 |
*/
|
|
9807 |
void QGraphicsTextItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
|
|
9808 |
{
|
|
9809 |
dd->sendControlEvent(event);
|
|
9810 |
}
|
|
9811 |
|
|
9812 |
/*!
|
|
9813 |
\reimp
|
|
9814 |
*/
|
|
9815 |
void QGraphicsTextItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
|
|
9816 |
{
|
|
9817 |
dd->sendControlEvent(event);
|
|
9818 |
}
|
|
9819 |
|
|
9820 |
/*!
|
|
9821 |
\reimp
|
|
9822 |
*/
|
|
9823 |
void QGraphicsTextItem::dropEvent(QGraphicsSceneDragDropEvent *event)
|
|
9824 |
{
|
|
9825 |
dd->sendControlEvent(event);
|
|
9826 |
}
|
|
9827 |
|
|
9828 |
/*!
|
|
9829 |
\reimp
|
|
9830 |
*/
|
|
9831 |
void QGraphicsTextItem::inputMethodEvent(QInputMethodEvent *event)
|
|
9832 |
{
|
|
9833 |
dd->sendControlEvent(event);
|
|
9834 |
}
|
|
9835 |
|
|
9836 |
/*!
|
|
9837 |
\reimp
|
|
9838 |
*/
|
|
9839 |
void QGraphicsTextItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
|
9840 |
{
|
|
9841 |
dd->sendControlEvent(event);
|
|
9842 |
}
|
|
9843 |
|
|
9844 |
/*!
|
|
9845 |
\reimp
|
|
9846 |
*/
|
|
9847 |
void QGraphicsTextItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
|
|
9848 |
{
|
|
9849 |
dd->sendControlEvent(event);
|
|
9850 |
}
|
|
9851 |
|
|
9852 |
/*!
|
|
9853 |
\reimp
|
|
9854 |
*/
|
|
9855 |
void QGraphicsTextItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
|
9856 |
{
|
|
9857 |
dd->sendControlEvent(event);
|
|
9858 |
}
|
|
9859 |
|
|
9860 |
/*!
|
|
9861 |
\reimp
|
|
9862 |
*/
|
|
9863 |
QVariant QGraphicsTextItem::inputMethodQuery(Qt::InputMethodQuery query) const
|
|
9864 |
{
|
|
9865 |
QVariant v;
|
|
9866 |
if (dd->control)
|
|
9867 |
v = dd->control->inputMethodQuery(query);
|
|
9868 |
if (v.type() == QVariant::RectF)
|
|
9869 |
v = v.toRectF().translated(-dd->controlOffset());
|
|
9870 |
else if (v.type() == QVariant::PointF)
|
|
9871 |
v = v.toPointF() - dd->controlOffset();
|
|
9872 |
else if (v.type() == QVariant::Rect)
|
|
9873 |
v = v.toRect().translated(-dd->controlOffset().toPoint());
|
|
9874 |
else if (v.type() == QVariant::Point)
|
|
9875 |
v = v.toPoint() - dd->controlOffset().toPoint();
|
|
9876 |
return v;
|
|
9877 |
}
|
|
9878 |
|
|
9879 |
/*!
|
|
9880 |
\internal
|
|
9881 |
*/
|
|
9882 |
bool QGraphicsTextItem::supportsExtension(Extension extension) const
|
|
9883 |
{
|
|
9884 |
Q_UNUSED(extension);
|
|
9885 |
return false;
|
|
9886 |
}
|
|
9887 |
|
|
9888 |
/*!
|
|
9889 |
\internal
|
|
9890 |
*/
|
|
9891 |
void QGraphicsTextItem::setExtension(Extension extension, const QVariant &variant)
|
|
9892 |
{
|
|
9893 |
Q_UNUSED(extension);
|
|
9894 |
Q_UNUSED(variant);
|
|
9895 |
}
|
|
9896 |
|
|
9897 |
/*!
|
|
9898 |
\internal
|
|
9899 |
*/
|
|
9900 |
QVariant QGraphicsTextItem::extension(const QVariant &variant) const
|
|
9901 |
{
|
|
9902 |
Q_UNUSED(variant);
|
|
9903 |
return QVariant();
|
|
9904 |
}
|
|
9905 |
|
|
9906 |
/*!
|
|
9907 |
\internal
|
|
9908 |
*/
|
|
9909 |
void QGraphicsTextItemPrivate::_q_update(QRectF rect)
|
|
9910 |
{
|
|
9911 |
if (rect.isValid()) {
|
|
9912 |
rect.translate(-controlOffset());
|
|
9913 |
} else {
|
|
9914 |
rect = boundingRect;
|
|
9915 |
}
|
|
9916 |
if (rect.intersects(boundingRect))
|
|
9917 |
qq->update(rect);
|
|
9918 |
}
|
|
9919 |
|
|
9920 |
/*!
|
|
9921 |
\internal
|
|
9922 |
*/
|
|
9923 |
void QGraphicsTextItemPrivate::_q_updateBoundingRect(const QSizeF &size)
|
|
9924 |
{
|
|
9925 |
if (!control) return; // can't happen
|
|
9926 |
const QSizeF pageSize = control->document()->pageSize();
|
|
9927 |
// paged items have a constant (page) size
|
|
9928 |
if (size == boundingRect.size() || pageSize.height() != -1)
|
|
9929 |
return;
|
|
9930 |
qq->prepareGeometryChange();
|
|
9931 |
boundingRect.setSize(size);
|
|
9932 |
qq->update();
|
|
9933 |
}
|
|
9934 |
|
|
9935 |
/*!
|
|
9936 |
\internal
|
|
9937 |
*/
|
|
9938 |
void QGraphicsTextItemPrivate::_q_ensureVisible(QRectF rect)
|
|
9939 |
{
|
|
9940 |
if (qq->hasFocus()) {
|
|
9941 |
rect.translate(-controlOffset());
|
|
9942 |
qq->ensureVisible(rect, /*xmargin=*/0, /*ymargin=*/0);
|
|
9943 |
}
|
|
9944 |
}
|
|
9945 |
|
|
9946 |
QTextControl *QGraphicsTextItemPrivate::textControl() const
|
|
9947 |
{
|
|
9948 |
if (!control) {
|
|
9949 |
QGraphicsTextItem *that = const_cast<QGraphicsTextItem *>(qq);
|
|
9950 |
control = new QTextControl(that);
|
|
9951 |
control->setTextInteractionFlags(Qt::NoTextInteraction);
|
|
9952 |
|
|
9953 |
QObject::connect(control, SIGNAL(updateRequest(QRectF)),
|
|
9954 |
qq, SLOT(_q_update(QRectF)));
|
|
9955 |
QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)),
|
|
9956 |
qq, SLOT(_q_updateBoundingRect(QSizeF)));
|
|
9957 |
QObject::connect(control, SIGNAL(visibilityRequest(QRectF)),
|
|
9958 |
qq, SLOT(_q_ensureVisible(QRectF)));
|
|
9959 |
QObject::connect(control, SIGNAL(linkActivated(QString)),
|
|
9960 |
qq, SIGNAL(linkActivated(QString)));
|
|
9961 |
QObject::connect(control, SIGNAL(linkHovered(QString)),
|
|
9962 |
qq, SIGNAL(linkHovered(QString)));
|
|
9963 |
|
|
9964 |
const QSizeF pgSize = control->document()->pageSize();
|
|
9965 |
if (pgSize.height() != -1) {
|
|
9966 |
qq->prepareGeometryChange();
|
|
9967 |
that->dd->boundingRect.setSize(pgSize);
|
|
9968 |
qq->update();
|
|
9969 |
} else {
|
|
9970 |
that->dd->_q_updateBoundingRect(control->size());
|
|
9971 |
}
|
|
9972 |
}
|
|
9973 |
return control;
|
|
9974 |
}
|
|
9975 |
|
|
9976 |
/*!
|
|
9977 |
\internal
|
|
9978 |
*/
|
|
9979 |
bool QGraphicsTextItemPrivate::_q_mouseOnEdge(QGraphicsSceneMouseEvent *event)
|
|
9980 |
{
|
|
9981 |
QPainterPath path;
|
|
9982 |
path.addRect(qq->boundingRect());
|
|
9983 |
|
|
9984 |
QPainterPath docPath;
|
|
9985 |
const QTextFrameFormat format = control->document()->rootFrame()->frameFormat();
|
|
9986 |
docPath.addRect(
|
|
9987 |
qq->boundingRect().adjusted(
|
|
9988 |
format.leftMargin(),
|
|
9989 |
format.topMargin(),
|
|
9990 |
-format.rightMargin(),
|
|
9991 |
-format.bottomMargin()));
|
|
9992 |
|
|
9993 |
return path.subtracted(docPath).contains(event->pos());
|
|
9994 |
}
|
|
9995 |
|
|
9996 |
/*!
|
|
9997 |
\fn QGraphicsTextItem::linkActivated(const QString &link)
|
|
9998 |
|
|
9999 |
This signal is emitted when the user clicks on a link on a text item
|
|
10000 |
that enables Qt::LinksAccessibleByMouse or Qt::LinksAccessibleByKeyboard.
|
|
10001 |
\a link is the link that was clicked.
|
|
10002 |
|
|
10003 |
\sa setTextInteractionFlags()
|
|
10004 |
*/
|
|
10005 |
|
|
10006 |
/*!
|
|
10007 |
\fn QGraphicsTextItem::linkHovered(const QString &link)
|
|
10008 |
|
|
10009 |
This signal is emitted when the user hovers over a link on a text item
|
|
10010 |
that enables Qt::LinksAccessibleByMouse. \a link is
|
|
10011 |
the link that was hovered over.
|
|
10012 |
|
|
10013 |
\sa setTextInteractionFlags()
|
|
10014 |
*/
|
|
10015 |
|
|
10016 |
/*!
|
|
10017 |
Sets the flags \a flags to specify how the text item should react to user
|
|
10018 |
input.
|
|
10019 |
|
|
10020 |
The default for a QGraphicsTextItem is Qt::NoTextInteraction. This function
|
|
10021 |
also affects the ItemIsFocusable QGraphicsItem flag by setting it if \a flags
|
|
10022 |
is different from Qt::NoTextInteraction and clearing it otherwise.
|
|
10023 |
|
|
10024 |
By default, the text is read-only. To transform the item into an editor,
|
|
10025 |
set the Qt::TextEditable flag.
|
|
10026 |
*/
|
|
10027 |
void QGraphicsTextItem::setTextInteractionFlags(Qt::TextInteractionFlags flags)
|
|
10028 |
{
|
|
10029 |
if (flags == Qt::NoTextInteraction)
|
|
10030 |
setFlags(this->flags() & ~QGraphicsItem::ItemIsFocusable);
|
|
10031 |
else
|
|
10032 |
setFlags(this->flags() | QGraphicsItem::ItemIsFocusable);
|
|
10033 |
dd->textControl()->setTextInteractionFlags(flags);
|
|
10034 |
}
|
|
10035 |
|
|
10036 |
/*!
|
|
10037 |
Returns the current text interaction flags.
|
|
10038 |
|
|
10039 |
\sa setTextInteractionFlags()
|
|
10040 |
*/
|
|
10041 |
Qt::TextInteractionFlags QGraphicsTextItem::textInteractionFlags() const
|
|
10042 |
{
|
|
10043 |
if (!dd->control)
|
|
10044 |
return Qt::NoTextInteraction;
|
|
10045 |
return dd->control->textInteractionFlags();
|
|
10046 |
}
|
|
10047 |
|
|
10048 |
/*!
|
|
10049 |
\since 4.5
|
|
10050 |
|
|
10051 |
If \a b is true, the \gui Tab key will cause the widget to change focus;
|
|
10052 |
otherwise, the tab key will insert a tab into the document.
|
|
10053 |
|
|
10054 |
In some occasions text edits should not allow the user to input tabulators
|
|
10055 |
or change indentation using the \gui Tab key, as this breaks the focus
|
|
10056 |
chain. The default is false.
|
|
10057 |
|
|
10058 |
\sa tabChangesFocus(), ItemIsFocusable, textInteractionFlags()
|
|
10059 |
*/
|
|
10060 |
void QGraphicsTextItem::setTabChangesFocus(bool b)
|
|
10061 |
{
|
|
10062 |
dd->tabChangesFocus = b;
|
|
10063 |
}
|
|
10064 |
|
|
10065 |
/*!
|
|
10066 |
\since 4.5
|
|
10067 |
|
|
10068 |
Returns true if the \gui Tab key will cause the widget to change focus;
|
|
10069 |
otherwise, false is returned.
|
|
10070 |
|
|
10071 |
By default, this behavior is disabled, and this function will return false.
|
|
10072 |
|
|
10073 |
\sa setTabChangesFocus()
|
|
10074 |
*/
|
|
10075 |
bool QGraphicsTextItem::tabChangesFocus() const
|
|
10076 |
{
|
|
10077 |
return dd->tabChangesFocus;
|
|
10078 |
}
|
|
10079 |
|
|
10080 |
/*!
|
|
10081 |
\property QGraphicsTextItem::openExternalLinks
|
|
10082 |
|
|
10083 |
Specifies whether QGraphicsTextItem should automatically open links using
|
|
10084 |
QDesktopServices::openUrl() instead of emitting the
|
|
10085 |
linkActivated signal.
|
|
10086 |
|
|
10087 |
The default value is false.
|
|
10088 |
*/
|
|
10089 |
void QGraphicsTextItem::setOpenExternalLinks(bool open)
|
|
10090 |
{
|
|
10091 |
dd->textControl()->setOpenExternalLinks(open);
|
|
10092 |
}
|
|
10093 |
|
|
10094 |
bool QGraphicsTextItem::openExternalLinks() const
|
|
10095 |
{
|
|
10096 |
if (!dd->control)
|
|
10097 |
return false;
|
|
10098 |
return dd->control->openExternalLinks();
|
|
10099 |
}
|
|
10100 |
|
|
10101 |
/*!
|
|
10102 |
\property QGraphicsTextItem::textCursor
|
|
10103 |
|
|
10104 |
This property represents the visible text cursor in an editable
|
|
10105 |
text item.
|
|
10106 |
|
|
10107 |
By default, if the item's text has not been set, this property
|
|
10108 |
contains a null text cursor; otherwise it contains a text cursor
|
|
10109 |
placed at the start of the item's document.
|
|
10110 |
*/
|
|
10111 |
void QGraphicsTextItem::setTextCursor(const QTextCursor &cursor)
|
|
10112 |
{
|
|
10113 |
dd->textControl()->setTextCursor(cursor);
|
|
10114 |
}
|
|
10115 |
|
|
10116 |
QTextCursor QGraphicsTextItem::textCursor() const
|
|
10117 |
{
|
|
10118 |
if (!dd->control)
|
|
10119 |
return QTextCursor();
|
|
10120 |
return dd->control->textCursor();
|
|
10121 |
}
|
|
10122 |
|
|
10123 |
class QGraphicsSimpleTextItemPrivate : public QAbstractGraphicsShapeItemPrivate
|
|
10124 |
{
|
|
10125 |
Q_DECLARE_PUBLIC(QGraphicsSimpleTextItem)
|
|
10126 |
public:
|
|
10127 |
inline QGraphicsSimpleTextItemPrivate() {
|
|
10128 |
pen.setStyle(Qt::NoPen);
|
|
10129 |
brush.setStyle(Qt::SolidPattern);
|
|
10130 |
}
|
|
10131 |
QString text;
|
|
10132 |
QFont font;
|
|
10133 |
QRectF boundingRect;
|
|
10134 |
|
|
10135 |
void updateBoundingRect();
|
|
10136 |
};
|
|
10137 |
|
|
10138 |
static QRectF setupTextLayout(QTextLayout *layout)
|
|
10139 |
{
|
|
10140 |
layout->setCacheEnabled(true);
|
|
10141 |
layout->beginLayout();
|
|
10142 |
while (layout->createLine().isValid())
|
|
10143 |
;
|
|
10144 |
layout->endLayout();
|
|
10145 |
qreal maxWidth = 0;
|
|
10146 |
qreal y = 0;
|
|
10147 |
for (int i = 0; i < layout->lineCount(); ++i) {
|
|
10148 |
QTextLine line = layout->lineAt(i);
|
|
10149 |
maxWidth = qMax(maxWidth, line.naturalTextWidth());
|
|
10150 |
line.setPosition(QPointF(0, y));
|
|
10151 |
y += line.height();
|
|
10152 |
}
|
|
10153 |
return QRectF(0, 0, maxWidth, y);
|
|
10154 |
}
|
|
10155 |
|
|
10156 |
void QGraphicsSimpleTextItemPrivate::updateBoundingRect()
|
|
10157 |
{
|
|
10158 |
Q_Q(QGraphicsSimpleTextItem);
|
|
10159 |
QRectF br;
|
|
10160 |
if (text.isEmpty()) {
|
|
10161 |
br = QRectF();
|
|
10162 |
} else {
|
|
10163 |
QString tmp = text;
|
|
10164 |
tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
|
|
10165 |
QStackTextEngine engine(tmp, font);
|
|
10166 |
QTextLayout layout(&engine);
|
|
10167 |
br = setupTextLayout(&layout);
|
|
10168 |
}
|
|
10169 |
if (br != boundingRect) {
|
|
10170 |
q->prepareGeometryChange();
|
|
10171 |
boundingRect = br;
|
|
10172 |
q->update();
|
|
10173 |
}
|
|
10174 |
}
|
|
10175 |
|
|
10176 |
/*!
|
|
10177 |
\class QGraphicsSimpleTextItem
|
|
10178 |
\brief The QGraphicsSimpleTextItem class provides a simple text path item
|
|
10179 |
that you can add to a QGraphicsScene.
|
|
10180 |
\since 4.2
|
|
10181 |
\ingroup graphicsview-api
|
|
10182 |
|
|
10183 |
To set the item's text, you can either pass a QString to
|
|
10184 |
QGraphicsSimpleTextItem's constructor, or call setText() to change the
|
|
10185 |
text later. To set the text fill color, call setBrush().
|
|
10186 |
|
|
10187 |
The simple text item can have both a fill and an outline; setBrush() will
|
|
10188 |
set the text fill (i.e., text color), and setPen() sets the pen that will
|
|
10189 |
be used to draw the text outline. (The latter can be slow, especially for
|
|
10190 |
complex pens, and items with long text content.) If all you want is to
|
|
10191 |
draw a simple line of text, you should call setBrush() only, and leave the
|
|
10192 |
pen unset; QGraphicsSimpleTextItem's pen is by default Qt::NoPen.
|
|
10193 |
|
|
10194 |
QGraphicsSimpleTextItem uses the text's formatted size and the associated
|
|
10195 |
font to provide a reasonable implementation of boundingRect(), shape(),
|
|
10196 |
and contains(). You can set the font by calling setFont().
|
|
10197 |
|
|
10198 |
QGraphicsSimpleText does not display rich text; instead, you can use
|
|
10199 |
QGraphicsTextItem, which provides full text control capabilities.
|
|
10200 |
|
|
10201 |
\img graphicsview-simpletextitem.png
|
|
10202 |
|
|
10203 |
\sa QGraphicsTextItem, QGraphicsPathItem, QGraphicsRectItem, QGraphicsEllipseItem,
|
|
10204 |
QGraphicsPixmapItem, QGraphicsPolygonItem, QGraphicsLineItem, {The
|
|
10205 |
Graphics View Framework}
|
|
10206 |
*/
|
|
10207 |
|
|
10208 |
/*!
|
|
10209 |
Constructs a QGraphicsSimpleTextItem.
|
|
10210 |
|
|
10211 |
\a parent is passed to QGraphicsItem's constructor.
|
|
10212 |
|
|
10213 |
\sa QGraphicsScene::addItem()
|
|
10214 |
*/
|
|
10215 |
QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(QGraphicsItem *parent
|
|
10216 |
#ifndef Q_QDOC
|
|
10217 |
// obsolete argument
|
|
10218 |
, QGraphicsScene *scene
|
|
10219 |
#endif
|
|
10220 |
)
|
|
10221 |
: QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
|
|
10222 |
{
|
|
10223 |
}
|
|
10224 |
|
|
10225 |
/*!
|
|
10226 |
Constructs a QGraphicsSimpleTextItem, using \a text as the default plain text.
|
|
10227 |
|
|
10228 |
\a parent is passed to QGraphicsItem's constructor.
|
|
10229 |
|
|
10230 |
\sa QGraphicsScene::addItem()
|
|
10231 |
*/
|
|
10232 |
QGraphicsSimpleTextItem::QGraphicsSimpleTextItem(const QString &text, QGraphicsItem *parent
|
|
10233 |
#ifndef Q_QDOC
|
|
10234 |
// obsolete argument
|
|
10235 |
, QGraphicsScene *scene
|
|
10236 |
#endif
|
|
10237 |
)
|
|
10238 |
: QAbstractGraphicsShapeItem(*new QGraphicsSimpleTextItemPrivate, parent, scene)
|
|
10239 |
{
|
|
10240 |
setText(text);
|
|
10241 |
}
|
|
10242 |
|
|
10243 |
/*!
|
|
10244 |
Destroys the QGraphicsSimpleTextItem.
|
|
10245 |
*/
|
|
10246 |
QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem()
|
|
10247 |
{
|
|
10248 |
}
|
|
10249 |
|
|
10250 |
/*!
|
|
10251 |
Sets the item's text to \a text. The text will be displayed as
|
|
10252 |
plain text. Newline characters ('\n') as well as characters of
|
|
10253 |
type QChar::LineSeparator will cause item to break the text into
|
|
10254 |
multiple lines.
|
|
10255 |
*/
|
|
10256 |
void QGraphicsSimpleTextItem::setText(const QString &text)
|
|
10257 |
{
|
|
10258 |
Q_D(QGraphicsSimpleTextItem);
|
|
10259 |
if (d->text == text)
|
|
10260 |
return;
|
|
10261 |
d->text = text;
|
|
10262 |
d->updateBoundingRect();
|
|
10263 |
update();
|
|
10264 |
}
|
|
10265 |
|
|
10266 |
/*!
|
|
10267 |
Returns the item's text.
|
|
10268 |
*/
|
|
10269 |
QString QGraphicsSimpleTextItem::text() const
|
|
10270 |
{
|
|
10271 |
Q_D(const QGraphicsSimpleTextItem);
|
|
10272 |
return d->text;
|
|
10273 |
}
|
|
10274 |
|
|
10275 |
/*!
|
|
10276 |
Sets the font that is used to draw the item's text to \a font.
|
|
10277 |
*/
|
|
10278 |
void QGraphicsSimpleTextItem::setFont(const QFont &font)
|
|
10279 |
{
|
|
10280 |
Q_D(QGraphicsSimpleTextItem);
|
|
10281 |
d->font = font;
|
|
10282 |
d->updateBoundingRect();
|
|
10283 |
}
|
|
10284 |
|
|
10285 |
/*!
|
|
10286 |
Returns the font that is used to draw the item's text.
|
|
10287 |
*/
|
|
10288 |
QFont QGraphicsSimpleTextItem::font() const
|
|
10289 |
{
|
|
10290 |
Q_D(const QGraphicsSimpleTextItem);
|
|
10291 |
return d->font;
|
|
10292 |
}
|
|
10293 |
|
|
10294 |
/*!
|
|
10295 |
\reimp
|
|
10296 |
*/
|
|
10297 |
QRectF QGraphicsSimpleTextItem::boundingRect() const
|
|
10298 |
{
|
|
10299 |
Q_D(const QGraphicsSimpleTextItem);
|
|
10300 |
return d->boundingRect;
|
|
10301 |
}
|
|
10302 |
|
|
10303 |
/*!
|
|
10304 |
\reimp
|
|
10305 |
*/
|
|
10306 |
QPainterPath QGraphicsSimpleTextItem::shape() const
|
|
10307 |
{
|
|
10308 |
Q_D(const QGraphicsSimpleTextItem);
|
|
10309 |
QPainterPath path;
|
|
10310 |
path.addRect(d->boundingRect);
|
|
10311 |
return path;
|
|
10312 |
}
|
|
10313 |
|
|
10314 |
/*!
|
|
10315 |
\reimp
|
|
10316 |
*/
|
|
10317 |
bool QGraphicsSimpleTextItem::contains(const QPointF &point) const
|
|
10318 |
{
|
|
10319 |
Q_D(const QGraphicsSimpleTextItem);
|
|
10320 |
return d->boundingRect.contains(point);
|
|
10321 |
}
|
|
10322 |
|
|
10323 |
/*!
|
|
10324 |
\reimp
|
|
10325 |
*/
|
|
10326 |
void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
|
10327 |
{
|
|
10328 |
Q_UNUSED(widget);
|
|
10329 |
Q_D(QGraphicsSimpleTextItem);
|
|
10330 |
|
|
10331 |
painter->setFont(d->font);
|
|
10332 |
|
|
10333 |
QString tmp = d->text;
|
|
10334 |
tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
|
|
10335 |
QStackTextEngine engine(tmp, d->font);
|
|
10336 |
QTextLayout layout(&engine);
|
|
10337 |
setupTextLayout(&layout);
|
|
10338 |
|
|
10339 |
QPen p;
|
|
10340 |
p.setBrush(d->brush);
|
|
10341 |
painter->setPen(p);
|
|
10342 |
if (d->pen.style() == Qt::NoPen && d->brush.style() == Qt::SolidPattern) {
|
|
10343 |
painter->setBrush(Qt::NoBrush);
|
|
10344 |
} else {
|
|
10345 |
QTextLayout::FormatRange range;
|
|
10346 |
range.start = 0;
|
|
10347 |
range.length = layout.text().length();
|
|
10348 |
range.format.setTextOutline(d->pen);
|
|
10349 |
QList<QTextLayout::FormatRange> formats;
|
|
10350 |
formats.append(range);
|
|
10351 |
layout.setAdditionalFormats(formats);
|
|
10352 |
}
|
|
10353 |
|
|
10354 |
layout.draw(painter, QPointF(0, 0));
|
|
10355 |
|
|
10356 |
if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
|
|
10357 |
qt_graphicsItem_highlightSelected(this, painter, option);
|
|
10358 |
}
|
|
10359 |
|
|
10360 |
/*!
|
|
10361 |
\reimp
|
|
10362 |
*/
|
|
10363 |
bool QGraphicsSimpleTextItem::isObscuredBy(const QGraphicsItem *item) const
|
|
10364 |
{
|
|
10365 |
return QAbstractGraphicsShapeItem::isObscuredBy(item);
|
|
10366 |
}
|
|
10367 |
|
|
10368 |
/*!
|
|
10369 |
\reimp
|
|
10370 |
*/
|
|
10371 |
QPainterPath QGraphicsSimpleTextItem::opaqueArea() const
|
|
10372 |
{
|
|
10373 |
return QAbstractGraphicsShapeItem::opaqueArea();
|
|
10374 |
}
|
|
10375 |
|
|
10376 |
/*!
|
|
10377 |
\reimp
|
|
10378 |
*/
|
|
10379 |
int QGraphicsSimpleTextItem::type() const
|
|
10380 |
{
|
|
10381 |
return Type;
|
|
10382 |
}
|
|
10383 |
|
|
10384 |
/*!
|
|
10385 |
\internal
|
|
10386 |
*/
|
|
10387 |
bool QGraphicsSimpleTextItem::supportsExtension(Extension extension) const
|
|
10388 |
{
|
|
10389 |
Q_UNUSED(extension);
|
|
10390 |
return false;
|
|
10391 |
}
|
|
10392 |
|
|
10393 |
/*!
|
|
10394 |
\internal
|
|
10395 |
*/
|
|
10396 |
void QGraphicsSimpleTextItem::setExtension(Extension extension, const QVariant &variant)
|
|
10397 |
{
|
|
10398 |
Q_UNUSED(extension);
|
|
10399 |
Q_UNUSED(variant);
|
|
10400 |
}
|
|
10401 |
|
|
10402 |
/*!
|
|
10403 |
\internal
|
|
10404 |
*/
|
|
10405 |
QVariant QGraphicsSimpleTextItem::extension(const QVariant &variant) const
|
|
10406 |
{
|
|
10407 |
Q_UNUSED(variant);
|
|
10408 |
return QVariant();
|
|
10409 |
}
|
|
10410 |
|
|
10411 |
/*!
|
|
10412 |
\class QGraphicsItemGroup
|
|
10413 |
\brief The QGraphicsItemGroup class provides treating a group of items as
|
|
10414 |
one.
|
|
10415 |
\since 4.2
|
|
10416 |
\ingroup graphicsview-api
|
|
10417 |
|
|
10418 |
A QGraphicsItemGroup is a special type of compound item that
|
|
10419 |
treats itself and all its children as one item (i.e., all events
|
|
10420 |
and geometries for all children are merged together). It's common
|
|
10421 |
to use item groups in presentation tools, when the user wants to
|
|
10422 |
group several smaller items into one big item in order to simplify
|
|
10423 |
moving and copying of items.
|
|
10424 |
|
|
10425 |
If all you want is to store items inside other items, you can use
|
|
10426 |
any QGraphicsItem directly by passing a suitable parent to
|
|
10427 |
setParentItem().
|
|
10428 |
|
|
10429 |
The boundingRect() function of QGraphicsItemGroup returns the
|
|
10430 |
bounding rectangle of all items in the item group.
|
|
10431 |
QGraphicsItemGroup ignores the ItemIgnoresTransformations flag on
|
|
10432 |
its children (i.e., with respect to the geometry of the group
|
|
10433 |
item, the children are treated as if they were transformable).
|
|
10434 |
|
|
10435 |
There are two ways to construct an item group. The easiest and
|
|
10436 |
most common approach is to pass a list of items (e.g., all
|
|
10437 |
selected items) to QGraphicsScene::createItemGroup(), which
|
|
10438 |
returns a new QGraphicsItemGroup item. The other approach is to
|
|
10439 |
manually construct a QGraphicsItemGroup item, add it to the scene
|
|
10440 |
calling QGraphicsScene::addItem(), and then add items to the group
|
|
10441 |
manually, one at a time by calling addToGroup(). To dismantle
|
|
10442 |
("ungroup") an item group, you can either call
|
|
10443 |
QGraphicsScene::destroyItemGroup(), or you can manually remove all
|
|
10444 |
items from the group by calling removeFromGroup().
|
|
10445 |
|
|
10446 |
\snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 17
|
|
10447 |
|
|
10448 |
The operation of adding and removing items preserves the items'
|
|
10449 |
scene-relative position and transformation, as opposed to calling
|
|
10450 |
setParentItem(), where only the child item's parent-relative
|
|
10451 |
position and transformation are kept.
|
|
10452 |
|
|
10453 |
The addtoGroup() function reparents the target item to this item
|
|
10454 |
group, keeping the item's position and transformation intact
|
|
10455 |
relative to the scene. Visually, this means that items added via
|
|
10456 |
addToGroup() will remain completely unchanged as a result of this
|
|
10457 |
operation, regardless of the item or the group's current position
|
|
10458 |
or transformation; although the item's position and matrix are
|
|
10459 |
likely to change.
|
|
10460 |
|
|
10461 |
The removeFromGroup() function has similar semantics to
|
|
10462 |
setParentItem(); it reparents the item to the parent item of the
|
|
10463 |
item group. As with addToGroup(), the item's scene-relative
|
|
10464 |
position and transformation remain intact.
|
|
10465 |
|
|
10466 |
\sa QGraphicsItem, {The Graphics View Framework}
|
|
10467 |
*/
|
|
10468 |
|
|
10469 |
class QGraphicsItemGroupPrivate : public QGraphicsItemPrivate
|
|
10470 |
{
|
|
10471 |
public:
|
|
10472 |
QRectF itemsBoundingRect;
|
|
10473 |
};
|
|
10474 |
|
|
10475 |
/*!
|
|
10476 |
Constructs a QGraphicsItemGroup. \a parent is passed to QGraphicsItem's
|
|
10477 |
constructor.
|
|
10478 |
|
|
10479 |
\sa QGraphicsScene::addItem()
|
|
10480 |
*/
|
|
10481 |
QGraphicsItemGroup::QGraphicsItemGroup(QGraphicsItem *parent
|
|
10482 |
#ifndef Q_QDOC
|
|
10483 |
// obsolete argument
|
|
10484 |
, QGraphicsScene *scene
|
|
10485 |
#endif
|
|
10486 |
)
|
|
10487 |
: QGraphicsItem(*new QGraphicsItemGroupPrivate, parent, scene)
|
|
10488 |
{
|
|
10489 |
setHandlesChildEvents(true);
|
|
10490 |
}
|
|
10491 |
|
|
10492 |
/*!
|
|
10493 |
Destroys the QGraphicsItemGroup.
|
|
10494 |
*/
|
|
10495 |
QGraphicsItemGroup::~QGraphicsItemGroup()
|
|
10496 |
{
|
|
10497 |
}
|
|
10498 |
|
|
10499 |
/*!
|
|
10500 |
Adds the given \a item to this item group. The item will be
|
|
10501 |
reparented to this group, but its position and transformation
|
|
10502 |
relative to the scene will stay intact.
|
|
10503 |
|
|
10504 |
\sa removeFromGroup(), QGraphicsScene::createItemGroup()
|
|
10505 |
*/
|
|
10506 |
void QGraphicsItemGroup::addToGroup(QGraphicsItem *item)
|
|
10507 |
{
|
|
10508 |
Q_D(QGraphicsItemGroup);
|
|
10509 |
if (!item) {
|
|
10510 |
qWarning("QGraphicsItemGroup::addToGroup: cannot add null item");
|
|
10511 |
return;
|
|
10512 |
}
|
|
10513 |
if (item == this) {
|
|
10514 |
qWarning("QGraphicsItemGroup::addToGroup: cannot add a group to itself");
|
|
10515 |
return;
|
|
10516 |
}
|
|
10517 |
|
|
10518 |
// COMBINE
|
|
10519 |
bool ok;
|
|
10520 |
QTransform itemTransform = item->itemTransform(this, &ok);
|
|
10521 |
|
|
10522 |
if (!ok) {
|
|
10523 |
qWarning("QGraphicsItemGroup::addToGroup: could not find a valid transformation from item to group coordinates");
|
|
10524 |
return;
|
|
10525 |
}
|
|
10526 |
|
|
10527 |
QTransform newItemTransform(itemTransform);
|
|
10528 |
item->setPos(mapFromItem(item, 0, 0));
|
|
10529 |
item->setParentItem(this);
|
|
10530 |
|
|
10531 |
// removing position from translation component of the new transform
|
|
10532 |
if (!item->pos().isNull())
|
|
10533 |
newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
|
|
10534 |
|
|
10535 |
item->setTransform(newItemTransform);
|
|
10536 |
item->d_func()->setIsMemberOfGroup(true);
|
|
10537 |
prepareGeometryChange();
|
|
10538 |
d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect());
|
|
10539 |
update();
|
|
10540 |
}
|
|
10541 |
|
|
10542 |
/*!
|
|
10543 |
Removes the specified \a item from this group. The item will be
|
|
10544 |
reparented to this group's parent item, or to 0 if this group has
|
|
10545 |
no parent. Its position and transformation relative to the scene
|
|
10546 |
will stay intact.
|
|
10547 |
|
|
10548 |
\sa addToGroup(), QGraphicsScene::destroyItemGroup()
|
|
10549 |
*/
|
|
10550 |
void QGraphicsItemGroup::removeFromGroup(QGraphicsItem *item)
|
|
10551 |
{
|
|
10552 |
Q_D(QGraphicsItemGroup);
|
|
10553 |
if (!item) {
|
|
10554 |
qWarning("QGraphicsItemGroup::removeFromGroup: cannot remove null item");
|
|
10555 |
return;
|
|
10556 |
}
|
|
10557 |
|
|
10558 |
QGraphicsItem *newParent = d_ptr->parent;
|
|
10559 |
QPointF oldPos = item->mapToItem(newParent, 0, 0);
|
|
10560 |
item->setParentItem(newParent);
|
|
10561 |
// ### This function should remap the item's matrix to keep the item's
|
|
10562 |
// transformation unchanged relative to the scene.
|
|
10563 |
item->setPos(oldPos);
|
|
10564 |
item->d_func()->setIsMemberOfGroup(item->group() != 0);
|
|
10565 |
|
|
10566 |
// ### Quite expensive. But removeFromGroup() isn't called very often.
|
|
10567 |
prepareGeometryChange();
|
|
10568 |
d->itemsBoundingRect = childrenBoundingRect();
|
|
10569 |
}
|
|
10570 |
|
|
10571 |
/*!
|
|
10572 |
\reimp
|
|
10573 |
|
|
10574 |
Returns the bounding rect of this group item, and all its children.
|
|
10575 |
*/
|
|
10576 |
QRectF QGraphicsItemGroup::boundingRect() const
|
|
10577 |
{
|
|
10578 |
Q_D(const QGraphicsItemGroup);
|
|
10579 |
return d->itemsBoundingRect;
|
|
10580 |
}
|
|
10581 |
|
|
10582 |
/*!
|
|
10583 |
\reimp
|
|
10584 |
*/
|
|
10585 |
void QGraphicsItemGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
|
10586 |
QWidget *widget)
|
|
10587 |
{
|
|
10588 |
Q_UNUSED(widget);
|
|
10589 |
if (option->state & QStyle::State_Selected) {
|
|
10590 |
Q_D(QGraphicsItemGroup);
|
|
10591 |
painter->setBrush(Qt::NoBrush);
|
|
10592 |
painter->drawRect(d->itemsBoundingRect);
|
|
10593 |
}
|
|
10594 |
}
|
|
10595 |
|
|
10596 |
/*!
|
|
10597 |
\reimp
|
|
10598 |
*/
|
|
10599 |
bool QGraphicsItemGroup::isObscuredBy(const QGraphicsItem *item) const
|
|
10600 |
{
|
|
10601 |
return QGraphicsItem::isObscuredBy(item);
|
|
10602 |
}
|
|
10603 |
|
|
10604 |
/*!
|
|
10605 |
\reimp
|
|
10606 |
*/
|
|
10607 |
QPainterPath QGraphicsItemGroup::opaqueArea() const
|
|
10608 |
{
|
|
10609 |
return QGraphicsItem::opaqueArea();
|
|
10610 |
}
|
|
10611 |
|
|
10612 |
/*!
|
|
10613 |
\reimp
|
|
10614 |
*/
|
|
10615 |
int QGraphicsItemGroup::type() const
|
|
10616 |
{
|
|
10617 |
return Type;
|
|
10618 |
}
|
|
10619 |
|
|
10620 |
QRectF QGraphicsItemEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
|
|
10621 |
{
|
|
10622 |
const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
|
|
10623 |
if (!info && deviceCoordinates) {
|
|
10624 |
// Device coordinates without info not yet supported.
|
|
10625 |
qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
|
|
10626 |
return QRectF();
|
|
10627 |
}
|
|
10628 |
|
|
10629 |
QRectF rect = item->boundingRect();
|
|
10630 |
if (!item->d_ptr->children.isEmpty())
|
|
10631 |
rect |= item->childrenBoundingRect();
|
|
10632 |
|
|
10633 |
if (deviceCoordinates) {
|
|
10634 |
Q_ASSERT(info->painter);
|
|
10635 |
rect = info->painter->worldTransform().mapRect(rect);
|
|
10636 |
}
|
|
10637 |
|
|
10638 |
return rect;
|
|
10639 |
}
|
|
10640 |
|
|
10641 |
void QGraphicsItemEffectSourcePrivate::draw(QPainter *painter)
|
|
10642 |
{
|
|
10643 |
if (!info) {
|
|
10644 |
qWarning("QGraphicsEffectSource::draw: Can only begin as a result of QGraphicsEffect::draw");
|
|
10645 |
return;
|
|
10646 |
}
|
|
10647 |
|
|
10648 |
Q_ASSERT(item->d_ptr->scene);
|
|
10649 |
QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
|
|
10650 |
if (painter == info->painter) {
|
|
10651 |
scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
|
|
10652 |
info->widget, info->opacity, info->effectTransform, info->wasDirtySceneTransform,
|
|
10653 |
info->drawItem);
|
|
10654 |
} else {
|
|
10655 |
QTransform effectTransform = info->painter->worldTransform().inverted();
|
|
10656 |
effectTransform *= painter->worldTransform();
|
|
10657 |
scened->draw(item, painter, info->viewTransform, info->transformPtr, info->exposedRegion,
|
|
10658 |
info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
|
|
10659 |
info->drawItem);
|
|
10660 |
}
|
|
10661 |
}
|
|
10662 |
|
|
10663 |
QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset) const
|
|
10664 |
{
|
|
10665 |
const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
|
|
10666 |
if (!info && deviceCoordinates) {
|
|
10667 |
// Device coordinates without info not yet supported.
|
|
10668 |
qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
|
|
10669 |
return QPixmap();
|
|
10670 |
}
|
|
10671 |
|
|
10672 |
if (!item->d_ptr->scene)
|
|
10673 |
return QPixmap();
|
|
10674 |
QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
|
|
10675 |
|
|
10676 |
const QRectF sourceRect = boundingRect(system);
|
|
10677 |
QRect effectRect = item->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
|
|
10678 |
if (offset)
|
|
10679 |
*offset = effectRect.topLeft();
|
|
10680 |
|
|
10681 |
if (deviceCoordinates) {
|
|
10682 |
// Clip to viewport rect.
|
|
10683 |
int left, top, right, bottom;
|
|
10684 |
effectRect.getCoords(&left, &top, &right, &bottom);
|
|
10685 |
if (left < 0) {
|
|
10686 |
if (offset)
|
|
10687 |
offset->rx() += -left;
|
|
10688 |
effectRect.setX(0);
|
|
10689 |
}
|
|
10690 |
if (top < 0) {
|
|
10691 |
if (offset)
|
|
10692 |
offset->ry() += -top;
|
|
10693 |
effectRect.setY(0);
|
|
10694 |
}
|
|
10695 |
// NB! We use +-1 for historical reasons (see QRect documentation).
|
|
10696 |
QPaintDevice *device = info->painter->device();
|
|
10697 |
const int deviceWidth = device->width();
|
|
10698 |
const int deviceHeight = device->height();
|
|
10699 |
if (right + 1 > deviceWidth)
|
|
10700 |
effectRect.setRight(deviceWidth - 1);
|
|
10701 |
if (bottom + 1 > deviceHeight)
|
|
10702 |
effectRect.setBottom(deviceHeight -1);
|
|
10703 |
|
|
10704 |
}
|
|
10705 |
|
|
10706 |
if (effectRect.isEmpty())
|
|
10707 |
return QPixmap();
|
|
10708 |
|
|
10709 |
QPixmap pixmap(effectRect.size());
|
|
10710 |
pixmap.fill(Qt::transparent);
|
|
10711 |
QPainter pixmapPainter(&pixmap);
|
|
10712 |
pixmapPainter.setRenderHints(info ? info->painter->renderHints() : QPainter::TextAntialiasing);
|
|
10713 |
|
|
10714 |
QTransform effectTransform = QTransform::fromTranslate(-effectRect.x(), -effectRect.y());
|
|
10715 |
if (deviceCoordinates && info->effectTransform)
|
|
10716 |
effectTransform *= *info->effectTransform;
|
|
10717 |
|
|
10718 |
if (!info) {
|
|
10719 |
// Logical coordinates without info.
|
|
10720 |
QTransform sceneTransform = item->sceneTransform();
|
|
10721 |
QTransform newEffectTransform = sceneTransform.inverted();
|
|
10722 |
newEffectTransform *= effectTransform;
|
|
10723 |
scened->draw(item, &pixmapPainter, 0, &sceneTransform, 0, 0, qreal(1.0),
|
|
10724 |
&newEffectTransform, false, true);
|
|
10725 |
} else if (deviceCoordinates) {
|
|
10726 |
// Device coordinates with info.
|
|
10727 |
scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, info->exposedRegion,
|
|
10728 |
info->widget, info->opacity, &effectTransform, info->wasDirtySceneTransform,
|
|
10729 |
info->drawItem);
|
|
10730 |
} else {
|
|
10731 |
// Item coordinates with info.
|
|
10732 |
QTransform newEffectTransform = info->transformPtr->inverted();
|
|
10733 |
newEffectTransform *= effectTransform;
|
|
10734 |
scened->draw(item, &pixmapPainter, info->viewTransform, info->transformPtr, info->exposedRegion,
|
|
10735 |
info->widget, info->opacity, &newEffectTransform, info->wasDirtySceneTransform,
|
|
10736 |
info->drawItem);
|
|
10737 |
}
|
|
10738 |
|
|
10739 |
pixmapPainter.end();
|
|
10740 |
|
|
10741 |
return pixmap;
|
|
10742 |
}
|
|
10743 |
|
|
10744 |
#ifndef QT_NO_DEBUG_STREAM
|
|
10745 |
QDebug operator<<(QDebug debug, QGraphicsItem *item)
|
|
10746 |
{
|
|
10747 |
if (!item) {
|
|
10748 |
debug << "QGraphicsItem(0)";
|
|
10749 |
return debug;
|
|
10750 |
}
|
|
10751 |
|
|
10752 |
debug << "QGraphicsItem(this =" << ((void*)item)
|
|
10753 |
<< ", parent =" << ((void*)item->parentItem())
|
|
10754 |
<< ", pos =" << item->pos()
|
|
10755 |
<< ", z =" << item->zValue() << ", flags = "
|
|
10756 |
<< item->flags() << ")";
|
|
10757 |
return debug;
|
|
10758 |
}
|
|
10759 |
|
|
10760 |
QDebug operator<<(QDebug debug, QGraphicsObject *item)
|
|
10761 |
{
|
|
10762 |
if (!item) {
|
|
10763 |
debug << "QGraphicsObject(0)";
|
|
10764 |
return debug;
|
|
10765 |
}
|
|
10766 |
|
|
10767 |
debug.nospace() << item->metaObject()->className() << '(' << (void*)item;
|
|
10768 |
if (!item->objectName().isEmpty())
|
|
10769 |
debug << ", name = " << item->objectName();
|
|
10770 |
debug.nospace() << ", parent = " << ((void*)item->parentItem())
|
|
10771 |
<< ", pos = " << item->pos()
|
|
10772 |
<< ", z = " << item->zValue() << ", flags = "
|
|
10773 |
<< item->flags() << ')';
|
|
10774 |
return debug.space();
|
|
10775 |
}
|
|
10776 |
|
|
10777 |
QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemChange change)
|
|
10778 |
{
|
|
10779 |
const char *str = "UnknownChange";
|
|
10780 |
switch (change) {
|
|
10781 |
case QGraphicsItem::ItemChildAddedChange:
|
|
10782 |
str = "ItemChildAddedChange";
|
|
10783 |
break;
|
|
10784 |
case QGraphicsItem::ItemChildRemovedChange:
|
|
10785 |
str = "ItemChildRemovedChange";
|
|
10786 |
break;
|
|
10787 |
case QGraphicsItem::ItemCursorChange:
|
|
10788 |
str = "ItemCursorChange";
|
|
10789 |
break;
|
|
10790 |
case QGraphicsItem::ItemCursorHasChanged:
|
|
10791 |
str = "ItemCursorHasChanged";
|
|
10792 |
break;
|
|
10793 |
case QGraphicsItem::ItemEnabledChange:
|
|
10794 |
str = "ItemEnabledChange";
|
|
10795 |
break;
|
|
10796 |
case QGraphicsItem::ItemEnabledHasChanged:
|
|
10797 |
str = "ItemEnabledHasChanged";
|
|
10798 |
break;
|
|
10799 |
case QGraphicsItem::ItemFlagsChange:
|
|
10800 |
str = "ItemFlagsChange";
|
|
10801 |
break;
|
|
10802 |
case QGraphicsItem::ItemFlagsHaveChanged:
|
|
10803 |
str = "ItemFlagsHaveChanged";
|
|
10804 |
break;
|
|
10805 |
case QGraphicsItem::ItemMatrixChange:
|
|
10806 |
str = "ItemMatrixChange";
|
|
10807 |
break;
|
|
10808 |
case QGraphicsItem::ItemParentChange:
|
|
10809 |
str = "ItemParentChange";
|
|
10810 |
break;
|
|
10811 |
case QGraphicsItem::ItemParentHasChanged:
|
|
10812 |
str = "ItemParentHasChanged";
|
|
10813 |
break;
|
|
10814 |
case QGraphicsItem::ItemPositionChange:
|
|
10815 |
str = "ItemPositionChange";
|
|
10816 |
break;
|
|
10817 |
case QGraphicsItem::ItemPositionHasChanged:
|
|
10818 |
str = "ItemPositionHasChanged";
|
|
10819 |
break;
|
|
10820 |
case QGraphicsItem::ItemSceneChange:
|
|
10821 |
str = "ItemSceneChange";
|
|
10822 |
break;
|
|
10823 |
case QGraphicsItem::ItemSceneHasChanged:
|
|
10824 |
str = "ItemSceneHasChanged";
|
|
10825 |
break;
|
|
10826 |
case QGraphicsItem::ItemSelectedChange:
|
|
10827 |
str = "ItemSelectedChange";
|
|
10828 |
break;
|
|
10829 |
case QGraphicsItem::ItemSelectedHasChanged:
|
|
10830 |
str = "ItemSelectedHasChanged";
|
|
10831 |
break;
|
|
10832 |
case QGraphicsItem::ItemToolTipChange:
|
|
10833 |
str = "ItemToolTipChange";
|
|
10834 |
break;
|
|
10835 |
case QGraphicsItem::ItemToolTipHasChanged:
|
|
10836 |
str = "ItemToolTipHasChanged";
|
|
10837 |
break;
|
|
10838 |
case QGraphicsItem::ItemTransformChange:
|
|
10839 |
str = "ItemTransformChange";
|
|
10840 |
break;
|
|
10841 |
case QGraphicsItem::ItemTransformHasChanged:
|
|
10842 |
str = "ItemTransformHasChanged";
|
|
10843 |
break;
|
|
10844 |
case QGraphicsItem::ItemVisibleChange:
|
|
10845 |
str = "ItemVisibleChange";
|
|
10846 |
break;
|
|
10847 |
case QGraphicsItem::ItemVisibleHasChanged:
|
|
10848 |
str = "ItemVisibleHasChanged";
|
|
10849 |
break;
|
|
10850 |
case QGraphicsItem::ItemZValueChange:
|
|
10851 |
str = "ItemZValueChange";
|
|
10852 |
break;
|
|
10853 |
case QGraphicsItem::ItemZValueHasChanged:
|
|
10854 |
str = "ItemZValueHasChanged";
|
|
10855 |
break;
|
|
10856 |
case QGraphicsItem::ItemOpacityChange:
|
|
10857 |
str = "ItemOpacityChange";
|
|
10858 |
break;
|
|
10859 |
case QGraphicsItem::ItemOpacityHasChanged:
|
|
10860 |
str = "ItemOpacityHasChanged";
|
|
10861 |
break;
|
|
10862 |
}
|
|
10863 |
debug << str;
|
|
10864 |
return debug;
|
|
10865 |
}
|
|
10866 |
|
|
10867 |
QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
|
|
10868 |
{
|
|
10869 |
const char *str = "UnknownFlag";
|
|
10870 |
switch (flag) {
|
|
10871 |
case QGraphicsItem::ItemIsMovable:
|
|
10872 |
str = "ItemIsMovable";
|
|
10873 |
break;
|
|
10874 |
case QGraphicsItem::ItemIsSelectable:
|
|
10875 |
str = "ItemIsSelectable";
|
|
10876 |
break;
|
|
10877 |
case QGraphicsItem::ItemIsFocusable:
|
|
10878 |
str = "ItemIsFocusable";
|
|
10879 |
break;
|
|
10880 |
case QGraphicsItem::ItemClipsToShape:
|
|
10881 |
str = "ItemClipsToShape";
|
|
10882 |
break;
|
|
10883 |
case QGraphicsItem::ItemClipsChildrenToShape:
|
|
10884 |
str = "ItemClipsChildrenToShape";
|
|
10885 |
break;
|
|
10886 |
case QGraphicsItem::ItemIgnoresTransformations:
|
|
10887 |
str = "ItemIgnoresTransformations";
|
|
10888 |
break;
|
|
10889 |
case QGraphicsItem::ItemIgnoresParentOpacity:
|
|
10890 |
str = "ItemIgnoresParentOpacity";
|
|
10891 |
break;
|
|
10892 |
case QGraphicsItem::ItemDoesntPropagateOpacityToChildren:
|
|
10893 |
str = "ItemDoesntPropagateOpacityToChildren";
|
|
10894 |
break;
|
|
10895 |
case QGraphicsItem::ItemStacksBehindParent:
|
|
10896 |
str = "ItemStacksBehindParent";
|
|
10897 |
break;
|
|
10898 |
case QGraphicsItem::ItemUsesExtendedStyleOption:
|
|
10899 |
str = "ItemUsesExtendedStyleOption";
|
|
10900 |
break;
|
|
10901 |
case QGraphicsItem::ItemHasNoContents:
|
|
10902 |
str = "ItemHasNoContents";
|
|
10903 |
break;
|
|
10904 |
case QGraphicsItem::ItemSendsGeometryChanges:
|
|
10905 |
str = "ItemSendsGeometryChanges";
|
|
10906 |
break;
|
|
10907 |
case QGraphicsItem::ItemAcceptsInputMethod:
|
|
10908 |
str = "ItemAcceptsInputMethod";
|
|
10909 |
break;
|
|
10910 |
case QGraphicsItem::ItemNegativeZStacksBehindParent:
|
|
10911 |
str = "ItemNegativeZStacksBehindParent";
|
|
10912 |
break;
|
|
10913 |
case QGraphicsItem::ItemIsPanel:
|
|
10914 |
str = "ItemIsPanel";
|
|
10915 |
break;
|
|
10916 |
case QGraphicsItem::ItemIsFocusScope:
|
|
10917 |
str = "ItemIsFocusScope";
|
|
10918 |
break;
|
|
10919 |
}
|
|
10920 |
debug << str;
|
|
10921 |
return debug;
|
|
10922 |
}
|
|
10923 |
|
|
10924 |
QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlags flags)
|
|
10925 |
{
|
|
10926 |
debug << '(';
|
|
10927 |
bool f = false;
|
|
10928 |
for (int i = 0; i < 16; ++i) {
|
|
10929 |
if (flags & (1 << i)) {
|
|
10930 |
if (f)
|
|
10931 |
debug << '|';
|
|
10932 |
f = true;
|
|
10933 |
debug << QGraphicsItem::GraphicsItemFlag(int(flags & (1 << i)));
|
|
10934 |
}
|
|
10935 |
}
|
|
10936 |
debug << ')';
|
|
10937 |
return debug;
|
|
10938 |
}
|
|
10939 |
|
|
10940 |
#endif
|
|
10941 |
|
|
10942 |
QT_END_NAMESPACE
|
|
10943 |
|
|
10944 |
#include "moc_qgraphicsitem.cpp"
|
|
10945 |
|
|
10946 |
#endif // QT_NO_GRAPHICSVIEW
|