Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qgraphicssceneindex.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5/*!
6 \class QGraphicsSceneIndex
7 \brief The QGraphicsSceneIndex class provides a base class to implement
8 a custom indexing algorithm for discovering items in QGraphicsScene.
9 \since 4.6
10 \ingroup graphicsview-api
11
12 \internal
13
14 The QGraphicsSceneIndex class provides a base class to implement
15 a custom indexing algorithm for discovering items in QGraphicsScene. You
16 need to subclass it and reimplement addItem, removeItem, estimateItems
17 and items in order to have an functional indexing.
18
19 \sa QGraphicsScene, QGraphicsView
20*/
21
22#include "qdebug.h"
23#include "qgraphicsscene.h"
29#include <QtGui/qpainterpath.h>
30
32
33namespace QtPrivate { // just to keep indentation of the following functions at the same level
34
35 static bool intersect_rect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
36 const QTransform &deviceTransform, const void *intersectData)
37 {
38 const QRectF sceneRect = *static_cast<const QRectF *>(intersectData);
39
40 QRectF brect = item->boundingRect();
41 _q_adjustRect(&brect);
42
43 // ### Add test for this (without making things slower?)
44 Q_UNUSED(exposeRect);
45
46 bool keep = true;
47 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
48 if (itemd->itemIsUntransformable()) {
49 // Untransformable items; map the scene rect to item coordinates.
50 const QTransform transform = item->deviceTransform(deviceTransform);
51 QRectF itemRect = (deviceTransform * transform.inverted()).mapRect(sceneRect);
52 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
53 keep = itemRect.contains(brect) && itemRect != brect;
54 else
55 keep = itemRect.intersects(brect);
56 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
57 QPainterPath itemPath;
58 itemPath.addRect(itemRect);
59 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
60 }
61 } else {
62 Q_ASSERT(!itemd->dirtySceneTransform);
63 const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly
64 ? brect.translated(itemd->sceneTransform.dx(),
65 itemd->sceneTransform.dy())
66 : itemd->sceneTransform.mapRect(brect);
67 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
68 keep = sceneRect != brect && sceneRect.contains(itemSceneBoundingRect);
69 else
70 keep = sceneRect.intersects(itemSceneBoundingRect);
71 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
72 QPainterPath rectPath;
73 rectPath.addRect(sceneRect);
74 if (itemd->sceneTransformTranslateOnly)
75 rectPath.translate(-itemd->sceneTransform.dx(), -itemd->sceneTransform.dy());
76 else
77 rectPath = itemd->sceneTransform.inverted().map(rectPath);
78 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, rectPath, mode);
79 }
80 }
81 return keep;
82 }
83
84 static bool intersect_point(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
85 const QTransform &deviceTransform, const void *intersectData)
86 {
87 const QPointF scenePoint = *static_cast<const QPointF *>(intersectData);
88
89 QRectF brect = item->boundingRect();
90 _q_adjustRect(&brect);
91
92 // ### Add test for this (without making things slower?)
93 Q_UNUSED(exposeRect);
94
95 bool keep = false;
96 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
97 if (itemd->itemIsUntransformable()) {
98 // Untransformable items; map the scene point to item coordinates.
99 const QTransform transform = item->deviceTransform(deviceTransform);
100 QPointF itemPoint = (deviceTransform * transform.inverted()).map(scenePoint);
101 keep = brect.contains(itemPoint);
102 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
103 QPainterPath pointPath;
104 pointPath.addRect(QRectF(itemPoint, QSizeF(1, 1)));
105 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, pointPath, mode);
106 }
107 } else {
108 Q_ASSERT(!itemd->dirtySceneTransform);
109 QRectF sceneBoundingRect = itemd->sceneTransformTranslateOnly
110 ? brect.translated(itemd->sceneTransform.dx(),
111 itemd->sceneTransform.dy())
112 : itemd->sceneTransform.mapRect(brect);
113 keep = sceneBoundingRect.intersects(QRectF(scenePoint, QSizeF(1, 1)));
114 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
115 QPointF p = itemd->sceneTransformTranslateOnly
116 ? QPointF(scenePoint.x() - itemd->sceneTransform.dx(),
117 scenePoint.y() - itemd->sceneTransform.dy())
118 : itemd->sceneTransform.inverted().map(scenePoint);
119 keep = item->contains(p);
120 }
121 }
122
123 return keep;
124 }
125
126 static bool intersect_path(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
127 const QTransform &deviceTransform, const void *intersectData)
128 {
129 const QPainterPath scenePath = *static_cast<const QPainterPath *>(intersectData);
130
131 QRectF brect = item->boundingRect();
132 _q_adjustRect(&brect);
133
134 // ### Add test for this (without making things slower?)
135 Q_UNUSED(exposeRect);
136
137 bool keep = true;
138 const QGraphicsItemPrivate *itemd = QGraphicsItemPrivate::get(item);
139 if (itemd->itemIsUntransformable()) {
140 // Untransformable items; map the scene rect to item coordinates.
141 const QTransform transform = item->deviceTransform(deviceTransform);
142 QPainterPath itemPath = (deviceTransform * transform.inverted()).map(scenePath);
143 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
144 keep = itemPath.contains(brect);
145 else
146 keep = itemPath.intersects(brect);
147 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape))
148 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
149 } else {
150 Q_ASSERT(!itemd->dirtySceneTransform);
151 const QRectF itemSceneBoundingRect = itemd->sceneTransformTranslateOnly
152 ? brect.translated(itemd->sceneTransform.dx(),
153 itemd->sceneTransform.dy())
154 : itemd->sceneTransform.mapRect(brect);
155 if (mode == Qt::ContainsItemShape || mode == Qt::ContainsItemBoundingRect)
156 keep = scenePath.contains(itemSceneBoundingRect);
157 else
158 keep = scenePath.intersects(itemSceneBoundingRect);
159 if (keep && (mode == Qt::ContainsItemShape || mode == Qt::IntersectsItemShape)) {
160 QPainterPath itemPath = itemd->sceneTransformTranslateOnly
161 ? scenePath.translated(-itemd->sceneTransform.dx(),
162 -itemd->sceneTransform.dy())
163 : itemd->sceneTransform.inverted().map(scenePath);
164 keep = QGraphicsSceneIndexPrivate::itemCollidesWithPath(item, itemPath, mode);
165 }
166 }
167 return keep;
168 }
169
170} // namespace QtPrivate
171
172/*!
173 Constructs a private scene index.
174*/
175QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : scene(scene)
176{
177}
178
179/*!
180 Destructor of private scene index.
181*/
185
186/*!
187 \internal
188
189 Checks if item collides with the path and mode, but also checks that if it
190 doesn't collide, maybe its frame rect will.
191*/
192bool QGraphicsSceneIndexPrivate::itemCollidesWithPath(const QGraphicsItem *item,
193 const QPainterPath &path,
194 Qt::ItemSelectionMode mode)
195{
196 if (item->collidesWithPath(path, mode))
197 return true;
198 if (item->isWidget()) {
199 // Check if this is a window, and if its frame rect collides.
200 const QGraphicsWidget *widget = static_cast<const QGraphicsWidget *>(item);
201 if (widget->isWindow()) {
202 QRectF frameRect = widget->windowFrameRect();
203 QPainterPath framePath;
204 framePath.addRect(frameRect);
205 bool intersects = path.intersects(frameRect);
206 if (mode == Qt::IntersectsItemShape || mode == Qt::IntersectsItemBoundingRect)
207 return intersects || path.contains(frameRect.topLeft())
208 || framePath.contains(path.elementAt(0));
209 return !intersects && path.contains(frameRect.topLeft());
210 }
211 }
212 return false;
213}
214
215/*!
216 \internal
217 This function returns the items in ascending order.
218*/
219void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF exposeRect,
221 QList<QGraphicsItem *> *items,
222 const QTransform &viewTransform,
223 Qt::ItemSelectionMode mode,
224 qreal parentOpacity, const void *intersectData) const
225{
226 Q_ASSERT(item);
227 if (!item->d_ptr->visible)
228 return;
229
230 const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity);
231 const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity);
232 const bool itemHasChildren = !item->d_ptr->children.isEmpty();
233 if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity()))
234 return;
235
236 // Update the item's scene transform if dirty.
237 const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable();
238 const bool wasDirtyParentSceneTransform = item->d_ptr->dirtySceneTransform && !itemIsUntransformable;
239 if (wasDirtyParentSceneTransform) {
240 item->d_ptr->updateSceneTransformFromParent();
241 Q_ASSERT(!item->d_ptr->dirtySceneTransform);
242 }
243
244 const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape
245 || item->d_ptr->flags & QGraphicsItem::ItemContainsChildrenInShape);
246 bool processItem = !itemIsFullyTransparent;
247 if (processItem) {
248 processItem = intersect(item, exposeRect, mode, viewTransform, intersectData);
249 if (!processItem && (!itemHasChildren || itemClipsChildrenToShape)) {
250 if (wasDirtyParentSceneTransform)
251 item->d_ptr->invalidateChildrenSceneTransform();
252 return;
253 }
254 } // else we know for sure this item has children we must process.
255
256 int i = 0;
257 if (itemHasChildren) {
258 // Sort children.
259 item->d_ptr->ensureSortedChildren();
260
261 // Clip to shape.
262 if (itemClipsChildrenToShape && !itemIsUntransformable) {
263 QPainterPath mappedShape = item->d_ptr->sceneTransformTranslateOnly
264 ? item->shape().translated(item->d_ptr->sceneTransform.dx(),
265 item->d_ptr->sceneTransform.dy())
266 : item->d_ptr->sceneTransform.map(item->shape());
267 exposeRect &= mappedShape.controlPointRect();
268 }
269
270 // Process children behind
271 for (i = 0; i < item->d_ptr->children.size(); ++i) {
272 QGraphicsItem *child = item->d_ptr->children.at(i);
273 if (wasDirtyParentSceneTransform)
274 child->d_ptr->dirtySceneTransform = 1;
275 if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent))
276 break;
277 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
278 continue;
279 recursive_items_helper(child, exposeRect, intersect, items, viewTransform,
280 mode, opacity, intersectData);
281 }
282 }
283
284 // Process item
285 if (processItem)
286 items->append(item);
287
288 // Process children in front
289 if (itemHasChildren) {
290 for (; i < item->d_ptr->children.size(); ++i) {
291 QGraphicsItem *child = item->d_ptr->children.at(i);
292 if (wasDirtyParentSceneTransform)
293 child->d_ptr->dirtySceneTransform = 1;
294 if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
295 continue;
296 recursive_items_helper(child, exposeRect, intersect, items, viewTransform,
297 mode, opacity, intersectData);
298 }
299 }
300}
301
303{
304 if (!scene)
305 return;
306
307 QObject::connect(scene, SIGNAL(sceneRectChanged(QRectF)),
308 q_func(), SLOT(updateSceneRect(QRectF)));
309}
310
311/*!
312 Constructs an abstract scene index for a given \a scene.
313*/
314QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsScene *scene)
315: QObject(*new QGraphicsSceneIndexPrivate(scene), scene)
316{
317 d_func()->init();
318}
319
320/*!
321 \internal
322*/
323QGraphicsSceneIndex::QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene)
324 : QObject(dd, scene)
325{
326 d_func()->init();
327}
328
329/*!
330 Destroys the scene index.
331*/
332QGraphicsSceneIndex::~QGraphicsSceneIndex()
333{
334
335}
336
337/*!
338 Returns the scene of this index.
339*/
340QGraphicsScene* QGraphicsSceneIndex::scene() const
341{
342 Q_D(const QGraphicsSceneIndex);
343 return d->scene;
344}
345
346/*!
347 \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPointF &pos,
348 Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform
349 &deviceTransform) const
350
351 Returns all visible items that, depending on \a mode, are at the specified
352 \a pos and return a list sorted using \a order.
353
354 The default value for \a mode is Qt::IntersectsItemShape; all items whose
355 exact shape intersects with \a pos are returned.
356
357 \a deviceTransform is the transformation apply to the view.
358
359 This method use the estimation of the index (estimateItems) and refine the
360 list to get an exact result. If you want to implement your own refinement
361 algorithm you can reimplement this method.
362
363 \sa estimateItems()
364
365*/
366QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSelectionMode mode,
367 Qt::SortOrder order, const QTransform &deviceTransform) const
368{
369
370 Q_D(const QGraphicsSceneIndex);
371 QList<QGraphicsItem *> itemList;
372 d->items_helper(QRectF(pos, QSizeF(1, 1)), &QtPrivate::intersect_point, &itemList, deviceTransform, mode, order, &pos);
373 return itemList;
374}
375
376/*!
377 \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QRectF &rect,
378 Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform
379 &deviceTransform) const
380
381 \overload
382
383 Returns all visible items that, depending on \a mode, are either inside or
384 intersect with the specified \a rect and return a list sorted using \a order.
385
386 The default value for \a mode is Qt::IntersectsItemShape; all items whose
387 exact shape intersects with or is contained by \a rect are returned.
388
389 \a deviceTransform is the transformation apply to the view.
390
391 This method use the estimation of the index (estimateItems) and refine
392 the list to get an exact result. If you want to implement your own
393 refinement algorithm you can reimplement this method.
394
395 \sa estimateItems()
396
397*/
398QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSelectionMode mode,
399 Qt::SortOrder order, const QTransform &deviceTransform) const
400{
401 Q_D(const QGraphicsSceneIndex);
402 QRectF exposeRect = rect;
403 _q_adjustRect(&exposeRect);
404 QList<QGraphicsItem *> itemList;
405 d->items_helper(exposeRect, &QtPrivate::intersect_rect, &itemList, deviceTransform, mode, order, &rect);
406 return itemList;
407}
408
409/*!
410 \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPolygonF
411 &polygon, Qt::ItemSelectionMode mode, Qt::SortOrder order, const
412 QTransform &deviceTransform) const
413
414 \overload
415
416 Returns all visible items that, depending on \a mode, are either inside or
417 intersect with the specified \a polygon and return a list sorted using \a order.
418
419 The default value for \a mode is Qt::IntersectsItemShape; all items whose
420 exact shape intersects with or is contained by \a polygon are returned.
421
422 \a deviceTransform is the transformation apply to the view.
423
424 This method use the estimation of the index (estimateItems) and refine
425 the list to get an exact result. If you want to implement your own
426 refinement algorithm you can reimplement this method.
427
428 \sa estimateItems()
429
430*/
431QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::ItemSelectionMode mode,
432 Qt::SortOrder order, const QTransform &deviceTransform) const
433{
434 Q_D(const QGraphicsSceneIndex);
435 QList<QGraphicsItem *> itemList;
436 QRectF exposeRect = polygon.boundingRect();
437 _q_adjustRect(&exposeRect);
438 QPainterPath path;
439 path.addPolygon(polygon);
440 d->items_helper(exposeRect, &QtPrivate::intersect_path, &itemList, deviceTransform, mode, order, &path);
441 return itemList;
442}
443
444/*!
445 \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPainterPath
446 &path, Qt::ItemSelectionMode mode, Qt::SortOrder order, const QTransform
447 &deviceTransform) const
448
449 \overload
450
451 Returns all visible items that, depending on \a mode, are either inside or
452 intersect with the specified \a path and return a list sorted using \a order.
453
454 The default value for \a mode is Qt::IntersectsItemShape; all items whose
455 exact shape intersects with or is contained by \a path are returned.
456
457 \a deviceTransform is the transformation apply to the view.
458
459 This method use the estimation of the index (estimateItems) and refine
460 the list to get an exact result. If you want to implement your own
461 refinement algorithm you can reimplement this method.
462
463 \sa estimateItems()
464
465*/
466QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPainterPath &path, Qt::ItemSelectionMode mode,
467 Qt::SortOrder order, const QTransform &deviceTransform) const
468{
469 Q_D(const QGraphicsSceneIndex);
470 QList<QGraphicsItem *> itemList;
471 QRectF exposeRect = path.controlPointRect();
472 _q_adjustRect(&exposeRect);
473 d->items_helper(exposeRect, &QtPrivate::intersect_path, &itemList, deviceTransform, mode, order, &path);
474 return itemList;
475}
476
477/*!
478 This virtual function return an estimation of items at position \a point.
479 This method return a list sorted using \a order.
480*/
481QList<QGraphicsItem *> QGraphicsSceneIndex::estimateItems(const QPointF &point, Qt::SortOrder order) const
482{
483 return estimateItems(QRectF(point, QSize(1, 1)), order);
484}
485
486QList<QGraphicsItem *> QGraphicsSceneIndex::estimateTopLevelItems(const QRectF &rect, Qt::SortOrder order) const
487{
488 Q_D(const QGraphicsSceneIndex);
489 Q_UNUSED(rect);
490 QGraphicsScenePrivate *scened = d->scene->d_func();
491 scened->ensureSortedTopLevelItems();
492 if (order == Qt::DescendingOrder) {
493 QList<QGraphicsItem *> sorted;
494 const int numTopLevelItems = scened->topLevelItems.size();
495 sorted.reserve(numTopLevelItems);
496 for (int i = numTopLevelItems - 1; i >= 0; --i)
497 sorted << scened->topLevelItems.at(i);
498 return sorted;
499 }
500 return scened->topLevelItems;
501}
502
503/*!
504 \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::DescendingOrder) const
505
506 This pure virtual function all items in the index and sort them using
507 \a order.
508*/
509
510
511/*!
512 Notifies the index that the scene's scene rect has changed. \a rect
513 is thew new scene rect.
514
515 \sa QGraphicsScene::sceneRect()
516*/
517void QGraphicsSceneIndex::updateSceneRect(const QRectF &rect)
518{
519 Q_UNUSED(rect);
520}
521
522/*!
523 This virtual function removes all items in the scene index.
524*/
525void QGraphicsSceneIndex::clear()
526{
527 const QList<QGraphicsItem *> allItems = items();
528 for (int i = 0 ; i < allItems.size(); ++i)
529 removeItem(allItems.at(i));
530}
531
532/*!
533 \fn virtual void QGraphicsSceneIndex::addItem(QGraphicsItem *item) = 0
534
535 This pure virtual function inserts an \a item to the scene index.
536
537 \sa removeItem(), deleteItem()
538*/
539
540/*!
541 \fn virtual void QGraphicsSceneIndex::removeItem(QGraphicsItem *item) = 0
542
543 This pure virtual function removes an \a item to the scene index.
544
545 \sa addItem(), deleteItem()
546*/
547
548/*!
549 This method is called when an \a item has been deleted.
550 The default implementation calls removeItem. Be careful,
551 if your implementation of removeItem use pure virtual method
552 of QGraphicsItem like boundingRect(), then you should reimplement
553 this method.
554
555 \sa addItem(), removeItem()
556*/
557void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item)
558{
559 removeItem(item);
560}
561
562/*!
563 This virtual function is called by QGraphicsItem to notify the index
564 that some part of the \a item 's state changes. By reimplementing this
565 function, your can react to a change, and in some cases, (depending on \a
566 change,) adjustments in the index can be made.
567
568 \a change is the parameter of the item that is changing. \a value is the
569 value that changed; the type of the value depends on \a change.
570
571 The default implementation does nothing.
572
573 \sa QGraphicsItem::GraphicsItemChange
574*/
575void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value)
576{
577 Q_UNUSED(item);
578 Q_UNUSED(change);
579 Q_UNUSED(value);
580}
581
582/*!
583 Notify the index for a geometry change of an \a item.
584
585 \sa QGraphicsItem::prepareGeometryChange()
586*/
587void QGraphicsSceneIndex::prepareBoundingRectChange(const QGraphicsItem *item)
588{
589 Q_UNUSED(item);
590}
591
592QT_END_NAMESPACE
593
594#include "moc_qgraphicssceneindex_p.cpp"
void recursive_items_helper(QGraphicsItem *item, QRectF exposeRect, QGraphicsSceneIndexIntersector intersect, QList< QGraphicsItem * > *items, const QTransform &viewTransform, Qt::ItemSelectionMode mode, qreal parentOpacity, const void *intersectData) const
~QGraphicsSceneIndexPrivate()
Destructor of private scene index.
\inmodule QtCore\reentrant
Definition qpoint.h:231
static bool intersect_point(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, const QTransform &deviceTransform, const void *intersectData)
static bool intersect_rect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, const QTransform &deviceTransform, const void *intersectData)
static bool intersect_path(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, const QTransform &deviceTransform, const void *intersectData)
bool(* QGraphicsSceneIndexIntersector)(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode, const QTransform &deviceTransform, const void *data)