Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qgraphicsview.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 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
5
6static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime < 2^9
7
247#include "qgraphicsview.h"
248#include "qgraphicsview_p.h"
249
250#include "qgraphicsitem.h"
251#include "qgraphicsitem_p.h"
252#include "qgraphicsscene.h"
253#include "qgraphicsscene_p.h"
254#include "qgraphicssceneevent.h"
255#include "qgraphicswidget.h"
256
257#include <QtCore/qdatetime.h>
258#include <QtCore/qdebug.h>
259#include <QtCore/qmath.h>
260#include <QtCore/qscopedvaluerollback.h>
261#include <QtWidgets/qapplication.h>
262#include <QtGui/qevent.h>
263#include <QtWidgets/qlayout.h>
264#include <QtGui/qtransform.h>
265#include <QtGui/qpainter.h>
266#include <QtGui/qpainterpath.h>
267#include <QtWidgets/qscrollbar.h>
268#include <QtWidgets/qstyleoption.h>
269
270#include <private/qevent_p.h>
271#include <QtGui/private/qeventpoint_p.h>
272
274
276
277inline int q_round_bound(qreal d) //### (int)(qreal) INT_MAX != INT_MAX for single precision
278{
279 if (d <= (qreal) INT_MIN)
280 return INT_MIN;
281 else if (d >= (qreal) INT_MAX)
282 return INT_MAX;
283 return d >= 0.0 ? int(d + 0.5) : int(d - int(d-1) + 0.5) + int(d-1);
284}
285
287{
288 for (int i = 0; i < touchEvent->pointCount(); ++i) {
289 auto &pt = touchEvent->point(i);
290 // the scene will set the item local pos, startPos, lastPos, and rect before delivering to
291 // an item, but for now those functions are returning the view's local coordinates
292 QMutableEventPoint::setScenePosition(pt, d->mapToScene(pt.position()));
293 // screenPos, startScreenPos, and lastScreenPos are already set
294 }
295}
296
301 : renderHints(QPainter::TextAntialiasing),
302 dragMode(QGraphicsView::NoDrag),
303 sceneInteractionAllowed(true), hasSceneRect(false),
304 connectedToScene(false),
305 useLastMouseEvent(false),
306 identityMatrix(true),
307 dirtyScroll(true),
308 accelerateScrolling(true),
309 keepLastCenterPoint(true),
310 transforming(false),
311 handScrolling(false),
312 mustAllocateStyleOptions(false),
313 mustResizeBackgroundPixmap(true),
314 fullUpdatePending(true),
315 hasUpdateClip(false),
316 mousePressButton(Qt::NoButton),
317 leftIndent(0), topIndent(0),
318 alignment(Qt::AlignCenter),
319 transformationAnchor(QGraphicsView::AnchorViewCenter), resizeAnchor(QGraphicsView::NoAnchor),
320 viewportUpdateMode(QGraphicsView::MinimalViewportUpdate),
321 scene(nullptr),
322#if QT_CONFIG(rubberband)
323 rubberBanding(false),
324 rubberBandSelectionMode(Qt::IntersectsItemShape),
325 rubberBandSelectionOperation(Qt::ReplaceSelection),
326#endif
327 handScrollMotions(0),
328#ifndef QT_NO_CURSOR
329 hasStoredOriginalCursor(false),
330#endif
331 lastDragDropEvent(nullptr),
332 updateSceneSlotReimplementedChecked(false)
333{
335}
336
340
345{
346 Q_Q(QGraphicsView);
347
348 const QSize maxSize = q->maximumViewportSize();
349 int width = maxSize.width();
350 int height = maxSize.height();
351 const QRectF viewRect = matrix.mapRect(q->sceneRect());
352
353 bool frameOnlyAround = (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, nullptr, q));
354 if (frameOnlyAround) {
355 if (hbarpolicy == Qt::ScrollBarAlwaysOn)
356 height -= frameWidth * 2;
357 if (vbarpolicy == Qt::ScrollBarAlwaysOn)
358 width -= frameWidth * 2;
359 }
360
361 // Adjust the maximum width and height of the viewport based on the width
362 // of visible scroll bars.
363 const int scrollBarExtent = q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, nullptr, q)
364 + (frameOnlyAround ? frameWidth * 2 : 0);
365
366 // We do not need to subtract the width scrollbars whose policy is
367 // Qt::ScrollBarAlwaysOn, this was already done by maximumViewportSize().
368 bool useHorizontalScrollBar = (viewRect.width() > width) && hbarpolicy == Qt::ScrollBarAsNeeded;
369 bool useVerticalScrollBar = (viewRect.height() > height) && vbarpolicy == Qt::ScrollBarAsNeeded;
370 if (useHorizontalScrollBar && vbarpolicy == Qt::ScrollBarAsNeeded) {
371 if (viewRect.height() > height - scrollBarExtent)
372 useVerticalScrollBar = true;
373 }
374 if (useVerticalScrollBar && hbarpolicy == Qt::ScrollBarAsNeeded) {
375 if (viewRect.width() > width - scrollBarExtent)
376 useHorizontalScrollBar = true;
377 }
378 if (useHorizontalScrollBar)
379 height -= scrollBarExtent;
380 if (useVerticalScrollBar)
381 width -= scrollBarExtent;
382
383 // Setting the ranges of these scroll bars can/will cause the values to
384 // change, and scrollContentsBy() will be called correspondingly. This
385 // will reset the last center point.
386 const QPointF savedLastCenterPoint = lastCenterPoint;
387
388 // Remember the former indent settings
389 const qreal oldLeftIndent = leftIndent;
390 const qreal oldTopIndent = topIndent;
391
392 // If the whole scene fits horizontally, we center the scene horizontally,
393 // and ignore the horizontal scroll bars.
394 const int left = q_round_bound(viewRect.left());
395 const int right = q_round_bound(viewRect.right() - width);
396 if (left >= right) {
398 case Qt::AlignLeft:
399 leftIndent = -viewRect.left();
400 break;
401 case Qt::AlignRight:
402 leftIndent = maxSize.width() - viewRect.width() - viewRect.left() - 1;
403 break;
404 case Qt::AlignHCenter:
405 default:
406 leftIndent = maxSize.width() / 2 - (viewRect.left() + viewRect.right()) / 2;
407 break;
408 }
409
410 hbar->setRange(0, 0);
411 } else {
412 leftIndent = 0;
413
414 hbar->setRange(left, right);
415 hbar->setPageStep(width);
416 hbar->setSingleStep(width / 20);
417
418 if (oldLeftIndent != 0)
419 hbar->setValue(-oldLeftIndent);
420 }
421
422 // If the whole scene fits vertically, we center the scene vertically, and
423 // ignore the vertical scroll bars.
424 const int top = q_round_bound(viewRect.top());
425 const int bottom = q_round_bound(viewRect.bottom() - height);
426 if (top >= bottom) {
428 case Qt::AlignTop:
429 topIndent = -viewRect.top();
430 break;
431 case Qt::AlignBottom:
432 topIndent = maxSize.height() - viewRect.height() - viewRect.top() - 1;
433 break;
434 case Qt::AlignVCenter:
435 default:
436 topIndent = maxSize.height() / 2 - (viewRect.top() + viewRect.bottom()) / 2;
437 break;
438 }
439
440 vbar->setRange(0, 0);
441 } else {
442 topIndent = 0;
443
444 vbar->setRange(top, bottom);
445 vbar->setPageStep(height);
446 vbar->setSingleStep(height / 20);
447
448 if (oldTopIndent != 0)
449 vbar->setValue(-oldTopIndent);
450 }
451
452 // Restorethe center point from before the ranges changed.
453 lastCenterPoint = savedLastCenterPoint;
454
455 // Issue a full update if the indents change.
456 // ### If the transform is still the same, we can get away with just a
457 // scroll instead.
458 if (oldLeftIndent != leftIndent || oldTopIndent != topIndent) {
459 dirtyScroll = true;
460 updateAll();
461 } else if (q->isRightToLeft() && !leftIndent) {
462 // In reverse mode, the horizontal scroll always changes after the content
463 // size has changed, as the scroll is calculated by summing the min and
464 // max values of the range and subtracting the current value. In normal
465 // mode the scroll remains unchanged unless the indent has changed.
466 dirtyScroll = true;
467 }
468
470 // Invalidate the background pixmap
472 }
473}
474
479{
480 Q_Q(QGraphicsView);
481 switch (anchor) {
483 if (q->underMouse()) {
484 // Last scene pos: lastMouseMoveScenePoint
485 // Current mouse pos:
486 QPointF transformationDiff = mapToScene(viewport->rect().toRectF().center())
487 - mapToScene(viewport->mapFromGlobal(QCursor::pos().toPointF()));
488 q->centerOn(lastMouseMoveScenePoint + transformationDiff);
489 } else {
490 q->centerOn(lastCenterPoint);
491 }
492 break;
493 }
495 q->centerOn(lastCenterPoint);
496 break;
498 break;
499 }
500}
501
506{
507 lastCenterPoint = mapToScene(viewport->rect().toRectF().center());
508}
509
517{
518 if (dirtyScroll)
519 const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
520 return scrollX;
521}
522
530{
531 if (dirtyScroll)
532 const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
533 return scrollY;
534}
535
542{
543 if (dirtyScroll)
544 const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
545 QRectF scrolled = QRectF(rect.translated(scrollX, scrollY));
546 return identityMatrix ? scrolled : matrix.inverted().mapRect(scrolled);
547}
548
549
556{
557 if (dirtyScroll)
558 const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
559 return (identityMatrix ? rect : matrix.mapRect(rect)).translated(-scrollX, -scrollY);
560}
561
566{
567 Q_Q(QGraphicsView);
569 if (q->isRightToLeft()) {
570 if (!leftIndent) {
571 scrollX += hbar->minimum();
572 scrollX += hbar->maximum();
573 scrollX -= hbar->value();
574 }
575 } else {
576 scrollX += hbar->value();
577 }
578
579 scrollY = qint64(vbar->value() - topIndent);
580
581 dirtyScroll = false;
582}
583
591{
592 Q_Q(const QGraphicsView);
593 if (q->dragMode() != QGraphicsView::NoDrag)
594 return false;
595
596 const QGraphicsItem *childItem = q->itemAt(startPos);
597
598 if (!startPos.isNull() && childItem && (childItem->flags() & QGraphicsItem::ItemIsMovable))
599 return false;
600
601 return QAbstractScrollAreaPrivate::canStartScrollingAt(startPos);
602}
603
608{
609 if (!useLastMouseEvent || !scene)
610 return;
611 QSinglePointEvent *spe = static_cast<QSinglePointEvent *>(&lastMouseEvent);
612 mouseMoveEventHandler(static_cast<QMouseEvent *>(spe));
613}
614
623
625{
626 Q_Q(QGraphicsView);
627
628#if QT_CONFIG(rubberband)
629 updateRubberBand(event);
630#endif
631
634
636 return;
637 if (handScrolling)
638 return;
639 if (!scene)
640 return;
641
643 mouseEvent.setWidget(viewport);
646 mouseEvent.setScenePos(q->mapToScene(event->position().toPoint()));
647 mouseEvent.setScreenPos(event->globalPosition().toPoint());
650 mouseEvent.setButtons(event->buttons());
651 mouseEvent.setButton(event->button());
652 mouseEvent.setModifiers(event->modifiers());
653 mouseEvent.setSource(event->source());
654 mouseEvent.setFlags(event->flags());
655 mouseEvent.setTimestamp(event->timestamp());
656 lastMouseMoveScenePoint = mouseEvent.scenePos();
657 lastMouseMoveScreenPoint = mouseEvent.screenPos();
658 mouseEvent.setAccepted(false);
659 if (event->spontaneous())
660 qt_sendSpontaneousEvent(scene, &mouseEvent);
661 else
663
664 // Remember whether the last event was accepted or not.
666
667 if (mouseEvent.isAccepted() && mouseEvent.buttons() != 0) {
668 // The event was delivered to a mouse grabber; the press is likely to
669 // have set a cursor, and we must not change it.
670 return;
671 }
672
673#ifndef QT_NO_CURSOR
674 // If all the items ignore hover events, we don't look-up any items
675 // in QGraphicsScenePrivate::dispatchHoverEvent, hence the
676 // cachedItemsUnderMouse list will be empty. We therefore do the look-up
677 // for cursor items here if not all items use the default cursor.
678 if (scene->d_func()->allItemsIgnoreHoverEvents && !scene->d_func()->allItemsUseDefaultCursor
679 && scene->d_func()->cachedItemsUnderMouse.isEmpty()) {
680 scene->d_func()->cachedItemsUnderMouse = scene->d_func()->itemsAtPosition(mouseEvent.screenPos(),
681 mouseEvent.scenePos(),
682 mouseEvent.widget());
683 }
684 // Find the topmost item under the mouse with a cursor.
685 for (QGraphicsItem *item : std::as_const(scene->d_func()->cachedItemsUnderMouse)) {
686 if (item->isEnabled() && item->hasCursor()) {
688 return;
689 }
690 }
691
692 // No items with cursors found; revert to the view cursor.
694 // Restore the original viewport cursor.
696 viewport->setCursor(originalCursor);
697 }
698#endif
699}
700
704#if QT_CONFIG(rubberband)
705QRegion QGraphicsViewPrivate::rubberBandRegion(const QWidget *widget, const QRect &rect) const
706{
708 QStyleOptionRubberBand option;
709 option.initFrom(widget);
710 option.rect = rect;
711 option.opaque = false;
713
714 QRegion tmp;
715 tmp += rect.adjusted(-1, -1, 1, 1);
717 tmp &= mask.region;
718 return tmp;
719}
720
721void QGraphicsViewPrivate::updateRubberBand(const QMouseEvent *event)
722{
723 Q_Q(QGraphicsView);
725 return;
726 // Check for enough drag distance
727 if ((mousePressViewPoint - event->position().toPoint()).manhattanLength() < QApplication::startDragDistance())
728 return;
729
730 // Update old rubberband
731 if (viewportUpdateMode != QGraphicsView::NoViewportUpdate && !rubberBandRect.isEmpty()) {
733 q->viewport()->update(rubberBandRegion(q->viewport(), rubberBandRect));
734 else
735 updateAll();
736 }
737
738 // Stop rubber banding if the user has let go of all buttons (even
739 // if we didn't get the release events).
740 if (!event->buttons()) {
741 rubberBanding = false;
742 rubberBandSelectionOperation = Qt::ReplaceSelection;
743 if (!rubberBandRect.isNull()) {
744 rubberBandRect = QRect();
745 emit q->rubberBandChanged(rubberBandRect, QPointF(), QPointF());
746 }
747 return;
748 }
749
750 QRect oldRubberband = rubberBandRect;
751
752 // Update rubberband position
753 const QPoint mp = q->mapFromScene(mousePressScenePoint);
754 const QPoint ep = event->position().toPoint();
755 rubberBandRect = QRect(qMin(mp.x(), ep.x()), qMin(mp.y(), ep.y()),
756 qAbs(mp.x() - ep.x()) + 1, qAbs(mp.y() - ep.y()) + 1);
757
758 if (rubberBandRect != oldRubberband || lastRubberbandScenePoint != lastMouseMoveScenePoint) {
760 oldRubberband = rubberBandRect;
761 emit q->rubberBandChanged(rubberBandRect, mousePressScenePoint, lastRubberbandScenePoint);
762 }
763
764 // Update new rubberband
767 q->viewport()->update(rubberBandRegion(q->viewport(), rubberBandRect));
768 else
769 updateAll();
770 }
771 // Set the new selection area
772 QPainterPath selectionArea;
773 selectionArea.addPolygon(q->mapToScene(rubberBandRect));
774 selectionArea.closeSubpath();
775 if (scene)
776 scene->setSelectionArea(selectionArea, rubberBandSelectionOperation, rubberBandSelectionMode, q->viewportTransform());
777}
778
779void QGraphicsViewPrivate::clearRubberBand()
780{
781 Q_Q(QGraphicsView);
783 return;
784
787 q->viewport()->update(rubberBandRegion(q->viewport(), rubberBandRect));
788 else
789 updateAll();
790 }
791
792 rubberBanding = false;
793 rubberBandSelectionOperation = Qt::ReplaceSelection;
794 if (!rubberBandRect.isNull()) {
795 rubberBandRect = QRect();
796 emit q->rubberBandChanged(rubberBandRect, QPointF(), QPointF());
797 }
798}
799#endif
800
804#ifndef QT_NO_CURSOR
806{
809 originalCursor = viewport->cursor();
810 }
811 viewport->setCursor(cursor);
812}
813#endif
814
818#ifndef QT_NO_CURSOR
820{
821 Q_Q(QGraphicsView);
822 const auto items = q->items(lastMouseEvent.position().toPoint());
823 for (QGraphicsItem *item : items) {
824 if (item->isEnabled() && item->hasCursor()) {
826 return;
827 }
828 }
829
830 // Restore the original viewport cursor.
834 viewport->setCursor(Qt::OpenHandCursor);
835 else
836 viewport->setCursor(originalCursor);
837 }
838}
839#endif
840
860
865 QDropEvent *source)
866{
867#if QT_CONFIG(draganddrop)
868 Q_Q(QGraphicsView);
869 dest->setScenePos(q->mapToScene(source->position().toPoint()));
870 dest->setScreenPos(q->mapToGlobal(source->position().toPoint()));
871 dest->setButtons(source->buttons());
872 dest->setModifiers(source->modifiers());
873 dest->setPossibleActions(source->possibleActions());
874 dest->setProposedAction(source->proposedAction());
875 dest->setDropAction(source->dropAction());
876 dest->setMimeData(source->mimeData());
877 dest->setWidget(viewport);
878 dest->setSource(qobject_cast<QWidget *>(source->source()));
879#else
880 Q_UNUSED(dest);
882#endif
883}
884
889{
890 Q_Q(const QGraphicsView);
891 if (dirtyScroll)
892 const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
893
895 QTransform itv = item->deviceTransform(q->viewportTransform());
896 return itv.mapRect(rect).toAlignedRect();
897 }
898
899 // Translate-only
900 // COMBINE
902 const QGraphicsItem *parentItem = item;
903 const QGraphicsItemPrivate *itemd;
904 do {
905 itemd = parentItem->d_ptr.data();
906 if (itemd->transformData)
907 break;
908 offset += itemd->pos;
909 } while ((parentItem = itemd->parent));
910
911 QRectF baseRect = rect.translated(offset.x(), offset.y());
912 if (!parentItem) {
913 if (identityMatrix) {
914 baseRect.translate(-scrollX, -scrollY);
915 return baseRect.toAlignedRect();
916 }
917 return matrix.mapRect(baseRect).translated(-scrollX, -scrollY).toAlignedRect();
918 }
919
920 QTransform tr = parentItem->sceneTransform();
921 if (!identityMatrix)
922 tr *= matrix;
923 QRectF r = tr.mapRect(baseRect);
924 r.translate(-scrollX, -scrollY);
925 return r.toAlignedRect();
926}
927
932{
933 Q_Q(const QGraphicsView);
934 if (dirtyScroll)
935 const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
936
937 // Accurate bounding region
938 QTransform itv = item->deviceTransform(q->viewportTransform());
939 return item->boundingRegion(itv) & itv.mapRect(rect).toAlignedRect();
940}
941
946{
947 if (!scene)
948 return;
949
950 if (fullUpdatePending) {
951 viewport->update();
954 } else {
955 viewport->update(dirtyRegion); // Already adjusted in updateRect/Region.
956 }
957
960}
961
962static inline bool intersectsViewport(const QRect &r, int width, int height)
963{ return !(r.left() > width) && !(r.right() < 0) && !(r.top() >= height) && !(r.bottom() < 0); }
964
965static inline bool containsViewport(const QRect &r, int width, int height)
966{ return r.left() <= 0 && r.top() <= 0 && r.right() >= width - 1 && r.bottom() >= height - 1; }
967
968static inline void QRect_unite(QRect *rect, const QRect &other)
969{
970 if (rect->isEmpty()) {
971 *rect = other;
972 } else {
973 rect->setCoords(qMin(rect->left(), other.left()), qMin(rect->top(), other.top()),
974 qMax(rect->right(), other.right()), qMax(rect->bottom(), other.bottom()));
975 }
976}
977
978/*
979 Calling this function results in update rects being clipped to the item's
980 bounding rect. Note that updates prior to this function call is not clipped.
981 The clip is removed by passing \nullptr.
982*/
984{
985 Q_Q(QGraphicsView);
986 // We simply ignore the request if the update mode is either FullViewportUpdate
987 // or NoViewportUpdate; in that case there's no point in clipping anything.
990 hasUpdateClip = false;
991 return;
992 }
993
994 // Calculate the clip (item's bounding rect in view coordinates).
995 // Optimized version of:
996 // QRect clip = item->deviceTransform(q->viewportTransform())
997 // .mapRect(item->boundingRect()).toAlignedRect();
998 QRect clip;
1000 QTransform xform = item->deviceTransform(q->viewportTransform());
1001 clip = xform.mapRect(item->boundingRect()).toAlignedRect();
1004 r.translate(item->d_ptr->sceneTransform.dx() - horizontalScroll(),
1006 clip = r.toAlignedRect();
1007 } else if (!q->isTransformed()) {
1008 clip = item->d_ptr->sceneTransform.mapRect(item->boundingRect()).toAlignedRect();
1009 } else {
1011 xform *= q->viewportTransform();
1012 clip = xform.mapRect(item->boundingRect()).toAlignedRect();
1013 }
1014
1015 if (hasUpdateClip) {
1016 // Intersect with old clip.
1017 updateClip &= clip;
1018 } else {
1019 updateClip = clip;
1020 hasUpdateClip = true;
1021 }
1022}
1023
1025{
1026 if (rect.isEmpty())
1027 return false;
1028
1031 // No point in updating with QRegion granularity; use the rect instead.
1032 return updateRectF(xform.mapRect(rect));
1033 }
1034
1035 // Update mode is either Minimal or Smart, so we have to do a potentially slow operation,
1036 // which is clearly documented here: QGraphicsItem::setBoundingRegionGranularity.
1037 const QRegion region = xform.map(QRegion(rect.toAlignedRect()));
1038 QRect viewRect = region.boundingRect();
1039 const bool dontAdjustForAntialiasing = optimizationFlags & QGraphicsView::DontAdjustForAntialiasing;
1040 if (dontAdjustForAntialiasing)
1041 viewRect.adjust(-1, -1, 1, 1);
1042 else
1043 viewRect.adjust(-2, -2, 2, 2);
1044 if (!intersectsViewport(viewRect, viewport->width(), viewport->height()))
1045 return false; // Update region for sure outside viewport.
1046
1047 for (QRect viewRect : region) {
1048 if (dontAdjustForAntialiasing)
1049 viewRect.adjust(-1, -1, 1, 1);
1050 else
1051 viewRect.adjust(-2, -2, 2, 2);
1052 if (hasUpdateClip)
1053 viewRect &= updateClip;
1054 dirtyRegion += viewRect;
1055 }
1056
1057 return true;
1058}
1059
1060// NB! Assumes the rect 'r' is already aligned and adjusted for antialiasing.
1061// For QRectF use updateRectF(const QRectF &) to ensure proper adjustments.
1063{
1065 || !intersectsViewport(r, viewport->width(), viewport->height())) {
1066 return false;
1067 }
1068
1069 switch (viewportUpdateMode) {
1071 fullUpdatePending = true;
1072 viewport->update();
1073 break;
1075 if (hasUpdateClip)
1077 else
1080 fullUpdatePending = true;
1081 viewport->update();
1082 }
1083 break;
1084 case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
1086 if (hasUpdateClip)
1088 else
1089 dirtyRegion += r;
1090 break;
1091 default:
1092 break;
1093 }
1094
1095 return true;
1096}
1097
1099{
1100 if (mustAllocateStyleOptions || (numItems > styleOptions.capacity()))
1101 // too many items, let's allocate on-the-fly
1102 return new QStyleOptionGraphicsItem[numItems];
1103
1104 // expand only whenever necessary
1105 if (numItems > styleOptions.size())
1106 styleOptions.resize(numItems);
1107
1109 return styleOptions.data();
1110}
1111
1118
1119extern QPainterPath qt_regionToPath(const QRegion &region);
1120
1130QList<QGraphicsItem *> QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems,
1131 const QTransform &viewTransform) const
1132{
1133 Q_Q(const QGraphicsView);
1134
1135 // Step 1) If all items are contained within the expose region, then
1136 // return a list of all visible items. ### the scene's growing bounding
1137 // rect does not take into account untransformable items.
1138 const QRectF exposedRegionSceneBounds = q->mapToScene(exposedRegion.boundingRect().adjusted(-1, -1, 1, 1))
1139 .boundingRect();
1140 if (exposedRegionSceneBounds.contains(scene->sceneRect())) {
1141 Q_ASSERT(allItems);
1142 *allItems = true;
1143
1144 // All items are guaranteed within the exposed region.
1146 }
1147
1148 // Step 2) If the expose region is a simple rect and the view is only
1149 // translated or scaled, search for items using
1150 // QGraphicsScene::items(QRectF).
1151 bool simpleRectLookup = exposedRegion.rectCount() == 1 && matrix.type() <= QTransform::TxScale;
1152 if (simpleRectLookup) {
1153 return scene->items(exposedRegionSceneBounds,
1155 Qt::AscendingOrder, viewTransform);
1156 }
1157
1158 // If the region is complex or the view has a complex transform, adjust
1159 // the expose region, convert it to a path, and then search for items
1160 // using QGraphicsScene::items(QPainterPath);
1161 QRegion adjustedRegion;
1162 for (const QRect &r : exposedRegion)
1163 adjustedRegion += r.adjusted(-1, -1, 1, 1);
1164
1165 const QPainterPath exposedScenePath(q->mapToScene(qt_regionToPath(adjustedRegion)));
1166 return scene->items(exposedScenePath, Qt::IntersectsItemBoundingRect,
1167 Qt::AscendingOrder, viewTransform);
1168}
1169
1178{
1179 Q_Q(QGraphicsView);
1180 QGraphicsItem *focusItem = nullptr;
1181 bool enabled = scene && (focusItem = scene->focusItem())
1183 q->setAttribute(Qt::WA_InputMethodEnabled, enabled);
1184 q->viewport()->setAttribute(Qt::WA_InputMethodEnabled, enabled);
1185
1186 if (!enabled) {
1187 q->setInputMethodHints({ });
1188 return;
1189 }
1190
1191 QGraphicsProxyWidget *proxy = focusItem->d_ptr->isWidget && focusItem->d_ptr->isProxyWidget()
1192 ? static_cast<QGraphicsProxyWidget *>(focusItem) : nullptr;
1193 if (!proxy) {
1194 q->setInputMethodHints(focusItem->inputMethodHints());
1195 } else if (QWidget *widget = proxy->widget()) {
1196 if (QWidget *fw = widget->focusWidget())
1197 widget = fw;
1199 } else {
1200 q->setInputMethodHints({ });
1201 }
1202}
1203
1208 : QAbstractScrollArea(*new QGraphicsViewPrivate, parent)
1209{
1210 setViewport(nullptr);
1211 setAcceptDrops(true);
1213 // Investigate leaving these disabled by default.
1215 viewport()->setAttribute(Qt::WA_InputMethodEnabled);
1216}
1217
1223 : QAbstractScrollArea(*new QGraphicsViewPrivate, parent)
1224{
1225 setScene(scene);
1226 setViewport(nullptr);
1227 setAcceptDrops(true);
1229 // Investigate leaving these disabled by default.
1231 viewport()->setAttribute(Qt::WA_InputMethodEnabled);
1232}
1233
1238 : QAbstractScrollArea(dd, parent)
1239{
1240 setViewport(nullptr);
1241 setAcceptDrops(true);
1243 // Investigate leaving these disabled by default.
1245 viewport()->setAttribute(Qt::WA_InputMethodEnabled);
1246}
1247
1252{
1253 Q_D(QGraphicsView);
1254 if (d->scene)
1255 d->scene->d_func()->views.removeAll(this);
1256 delete d->lastDragDropEvent;
1257}
1258
1263{
1264 Q_D(const QGraphicsView);
1265 if (d->scene) {
1266 QSizeF baseSize = d->matrix.mapRect(sceneRect()).size();
1267 baseSize += QSizeF(d->frameWidth * 2, d->frameWidth * 2);
1268 return baseSize.boundedTo((3 * QGuiApplication::primaryScreen()->virtualSize()) / 4).toSize();
1269 }
1270 return QAbstractScrollArea::sizeHint();
1271}
1272
1288QPainter::RenderHints QGraphicsView::renderHints() const
1289{
1290 Q_D(const QGraphicsView);
1291 return d->renderHints;
1292}
1293void QGraphicsView::setRenderHints(QPainter::RenderHints hints)
1294{
1295 Q_D(QGraphicsView);
1296 if (hints == d->renderHints)
1297 return;
1298 d->renderHints = hints;
1299 d->updateAll();
1300}
1301
1309{
1310 Q_D(QGraphicsView);
1311 QPainter::RenderHints oldHints = d->renderHints;
1312 d->renderHints.setFlag(hint, enabled);
1313 if (oldHints != d->renderHints)
1314 d->updateAll();
1315}
1316
1329Qt::Alignment QGraphicsView::alignment() const
1330{
1331 Q_D(const QGraphicsView);
1332 return d->alignment;
1333}
1335{
1336 Q_D(QGraphicsView);
1337 if (d->alignment != alignment) {
1338 d->alignment = alignment;
1339 d->recalculateContentSize();
1340 }
1341}
1342
1362{
1363 Q_D(const QGraphicsView);
1364 return d->transformationAnchor;
1365}
1367{
1368 Q_D(QGraphicsView);
1369 d->transformationAnchor = anchor;
1370
1371 // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
1372 // in order to have up-to-date information for centering the view.
1373 if (d->transformationAnchor == AnchorUnderMouse)
1374 d->viewport->setMouseTracking(true);
1375}
1376
1394{
1395 Q_D(const QGraphicsView);
1396 return d->resizeAnchor;
1397}
1399{
1400 Q_D(QGraphicsView);
1401 d->resizeAnchor = anchor;
1402
1403 // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
1404 // in order to have up-to-date information for centering the view.
1405 if (d->resizeAnchor == AnchorUnderMouse)
1406 d->viewport->setMouseTracking(true);
1407}
1408
1428{
1429 Q_D(const QGraphicsView);
1430 return d->viewportUpdateMode;
1431}
1433{
1434 Q_D(QGraphicsView);
1435 d->viewportUpdateMode = mode;
1436}
1437
1456QGraphicsView::OptimizationFlags QGraphicsView::optimizationFlags() const
1457{
1458 Q_D(const QGraphicsView);
1459 return d->optimizationFlags;
1460}
1462{
1463 Q_D(QGraphicsView);
1464 d->optimizationFlags = flags;
1465}
1466
1473{
1474 Q_D(QGraphicsView);
1475 d->optimizationFlags.setFlag(flag, enabled);
1476}
1477
1493{
1494 Q_D(const QGraphicsView);
1495 return d->dragMode;
1496}
1498{
1499 Q_D(QGraphicsView);
1500 if (d->dragMode == mode)
1501 return;
1502
1503#if QT_CONFIG(rubberband)
1504 d->clearRubberBand();
1505#endif
1506
1507#ifndef QT_NO_CURSOR
1508 if (d->dragMode == ScrollHandDrag)
1509 viewport()->unsetCursor();
1510#endif
1511
1512 // If dragMode is unset while dragging, e.g. via a keyEvent, we
1513 // don't unset the handScrolling state. When enabling scrolling
1514 // again the mouseMoveEvent will automatically start scrolling,
1515 // without a mousePress
1516 if (d->dragMode == ScrollHandDrag && mode == NoDrag && d->handScrolling)
1517 d->handScrolling = false;
1518
1519 d->dragMode = mode;
1520
1521#ifndef QT_NO_CURSOR
1522 if (d->dragMode == ScrollHandDrag) {
1523 // Forget the stored viewport cursor when we enter scroll hand drag mode.
1524 d->hasStoredOriginalCursor = false;
1525 viewport()->setCursor(Qt::OpenHandCursor);
1526 }
1527#endif
1528}
1529
1530#if QT_CONFIG(rubberband)
1544Qt::ItemSelectionMode QGraphicsView::rubberBandSelectionMode() const
1545{
1546 Q_D(const QGraphicsView);
1547 return d->rubberBandSelectionMode;
1548}
1549void QGraphicsView::setRubberBandSelectionMode(Qt::ItemSelectionMode mode)
1550{
1551 Q_D(QGraphicsView);
1552 d->rubberBandSelectionMode = mode;
1553}
1554
1567QRect QGraphicsView::rubberBandRect() const
1568{
1569 Q_D(const QGraphicsView);
1570 if (d->dragMode != QGraphicsView::RubberBandDrag || !d->sceneInteractionAllowed || !d->rubberBanding)
1571 return QRect();
1572
1573 return d->rubberBandRect;
1574}
1575#endif
1576
1597QGraphicsView::CacheMode QGraphicsView::cacheMode() const
1598{
1599 Q_D(const QGraphicsView);
1600 return d->cacheMode;
1601}
1603{
1604 Q_D(QGraphicsView);
1605 if (mode == d->cacheMode)
1606 return;
1607 d->cacheMode = mode;
1609}
1610
1625{
1626 Q_D(QGraphicsView);
1627 if (d->cacheMode == CacheNone)
1628 return;
1629
1630 if (d->cacheMode & CacheBackground) {
1631 // Background caching is enabled.
1632 d->mustResizeBackgroundPixmap = true;
1633 d->updateAll();
1634 } else if (d->mustResizeBackgroundPixmap) {
1635 // Background caching is disabled.
1636 // Cleanup, free some resources.
1637 d->mustResizeBackgroundPixmap = false;
1638 d->backgroundPixmap = QPixmap();
1639 d->backgroundPixmapExposed = QRegion();
1640 }
1641}
1642
1659void QGraphicsView::invalidateScene(const QRectF &rect, QGraphicsScene::SceneLayers layers)
1660{
1661 Q_D(QGraphicsView);
1662 if ((layers & QGraphicsScene::BackgroundLayer) && !d->mustResizeBackgroundPixmap) {
1663 QRect viewRect = mapFromScene(rect).boundingRect();
1664 if (viewport()->rect().intersects(viewRect)) {
1665 // The updated background area is exposed; schedule this area for
1666 // redrawing.
1667 d->backgroundPixmapExposed += viewRect;
1668 if (d->scene)
1669 d->scene->update(rect);
1670 }
1671 }
1672}
1673
1685{
1686 Q_D(const QGraphicsView);
1687 return d->sceneInteractionAllowed;
1688}
1690{
1691 Q_D(QGraphicsView);
1692 d->sceneInteractionAllowed = allowed;
1693}
1694
1702{
1703 Q_D(const QGraphicsView);
1704 return d->scene;
1705}
1706
1718{
1719 Q_D(QGraphicsView);
1720 if (d->scene == scene)
1721 return;
1722
1723 // Always update the viewport when the scene changes.
1724 d->updateAll();
1725
1726 // Remove the previously assigned scene.
1727 if (d->scene) {
1728 disconnect(d->scene, SIGNAL(changed(QList<QRectF>)),
1729 this, SLOT(updateScene(QList<QRectF>)));
1730 disconnect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
1731 this, SLOT(updateSceneRect(QRectF)));
1732 d->scene->d_func()->removeView(this);
1733 d->connectedToScene = false;
1734
1735 if (isActiveWindow() && isVisible()) {
1736 QEvent windowDeactivate(QEvent::WindowDeactivate);
1737 QCoreApplication::sendEvent(d->scene, &windowDeactivate);
1738 }
1739 if (hasFocus())
1740 d->scene->clearFocus();
1741 }
1742
1743 // Assign the new scene and update the contents (scrollbars, etc.)).
1744 if ((d->scene = scene)) {
1745 connect(d->scene, SIGNAL(sceneRectChanged(QRectF)),
1746 this, SLOT(updateSceneRect(QRectF)));
1747 d->updateSceneSlotReimplementedChecked = false;
1748 d->scene->d_func()->addView(this);
1749 d->recalculateContentSize();
1750 d->lastCenterPoint = sceneRect().center();
1751 d->keepLastCenterPoint = true;
1752 // We are only interested in mouse tracking if items accept
1753 // hover events or use non-default cursors.
1754 if (!d->scene->d_func()->allItemsIgnoreHoverEvents
1755 || !d->scene->d_func()->allItemsUseDefaultCursor) {
1756 d->viewport->setMouseTracking(true);
1757 }
1758
1759 // enable touch events if any items is interested in them
1760 if (!d->scene->d_func()->allItemsIgnoreTouchEvents)
1761 d->viewport->setAttribute(Qt::WA_AcceptTouchEvents);
1762
1763 if (isActiveWindow() && isVisible()) {
1764 QEvent windowActivate(QEvent::WindowActivate);
1765 QCoreApplication::sendEvent(d->scene, &windowActivate);
1766 }
1767 } else {
1768 d->recalculateContentSize();
1769 }
1770
1771 d->updateInputMethodSensitivity();
1772
1773 if (d->scene && hasFocus())
1774 d->scene->setFocus();
1775}
1776
1801{
1802 Q_D(const QGraphicsView);
1803 if (d->hasSceneRect)
1804 return d->sceneRect;
1805 if (d->scene)
1806 return d->scene->sceneRect();
1807 return QRectF();
1808}
1810{
1811 Q_D(QGraphicsView);
1812 d->hasSceneRect = !rect.isNull();
1813 d->sceneRect = rect;
1814 d->recalculateContentSize();
1815}
1816
1823{
1824 Q_D(QGraphicsView);
1825 QTransform matrix = d->matrix;
1828}
1829
1836{
1837 Q_D(QGraphicsView);
1838 QTransform matrix = d->matrix;
1839 matrix.scale(sx, sy);
1841}
1842
1849{
1850 Q_D(QGraphicsView);
1851 QTransform matrix = d->matrix;
1852 matrix.shear(sh, sv);
1854}
1855
1862{
1863 Q_D(QGraphicsView);
1864 QTransform matrix = d->matrix;
1865 matrix.translate(dx, dy);
1867}
1868
1882{
1883 Q_D(QGraphicsView);
1884 qreal width = viewport()->width();
1885 qreal height = viewport()->height();
1886 QPointF viewPoint = d->matrix.map(pos);
1887 QPointF oldCenterPoint = pos;
1888
1889 if (!d->leftIndent) {
1890 if (isRightToLeft()) {
1891 qint64 horizontal = 0;
1892 horizontal += horizontalScrollBar()->minimum();
1893 horizontal += horizontalScrollBar()->maximum();
1894 horizontal -= qRound(viewPoint.x() - width / 2.0);
1895 horizontalScrollBar()->setValue(horizontal);
1896 } else {
1897 horizontalScrollBar()->setValue(qRound(viewPoint.x() - width / 2.0));
1898 }
1899 }
1900 if (!d->topIndent)
1901 verticalScrollBar()->setValue(qRound(viewPoint.y() - height / 2.0));
1902 d->lastCenterPoint = oldCenterPoint;
1903}
1904
1925
1935void QGraphicsView::ensureVisible(const QRectF &rect, int xmargin, int ymargin)
1936{
1937 Q_D(QGraphicsView);
1938 qreal width = viewport()->width();
1939 qreal height = viewport()->height();
1940 QRectF viewRect = d->matrix.mapRect(rect);
1941
1942 qreal left = d->horizontalScroll();
1943 qreal right = left + width;
1944 qreal top = d->verticalScroll();
1945 qreal bottom = top + height;
1946
1947 if (viewRect.left() <= left + xmargin) {
1948 // need to scroll from the left
1949 if (!d->leftIndent)
1950 horizontalScrollBar()->setValue(int(viewRect.left() - xmargin - 0.5));
1951 }
1952 if (viewRect.right() >= right - xmargin) {
1953 // need to scroll from the right
1954 if (!d->leftIndent)
1955 horizontalScrollBar()->setValue(int(viewRect.right() - width + xmargin + 0.5));
1956 }
1957 if (viewRect.top() <= top + ymargin) {
1958 // need to scroll from the top
1959 if (!d->topIndent)
1960 verticalScrollBar()->setValue(int(viewRect.top() - ymargin - 0.5));
1961 }
1962 if (viewRect.bottom() >= bottom - ymargin) {
1963 // need to scroll from the bottom
1964 if (!d->topIndent)
1965 verticalScrollBar()->setValue(int(viewRect.bottom() - height + ymargin + 0.5));
1966 }
1967}
1968
1988void QGraphicsView::ensureVisible(const QGraphicsItem *item, int xmargin, int ymargin)
1989{
1990 ensureVisible(item->sceneBoundingRect(), xmargin, ymargin);
1991}
1992
2018{
2019 Q_D(QGraphicsView);
2020 if (!d->scene || rect.isNull())
2021 return;
2022
2023 // Reset the view scale to 1:1.
2024 QRectF unity = d->matrix.mapRect(QRectF(0, 0, 1, 1));
2025 if (unity.isEmpty())
2026 return;
2027 scale(1 / unity.width(), 1 / unity.height());
2028
2029 // Find the ideal x / y scaling ratio to fit \a rect in the view.
2030 int margin = 2;
2031 QRectF viewRect = viewport()->rect().adjusted(margin, margin, -margin, -margin);
2032 if (viewRect.isEmpty())
2033 return;
2034 QRectF sceneRect = d->matrix.mapRect(rect);
2035 if (sceneRect.isEmpty())
2036 return;
2037 qreal xratio = viewRect.width() / sceneRect.width();
2038 qreal yratio = viewRect.height() / sceneRect.height();
2039
2040 // Respect the aspect ratio mode.
2041 switch (aspectRatioMode) {
2043 xratio = yratio = qMin(xratio, yratio);
2044 break;
2046 xratio = yratio = qMax(xratio, yratio);
2047 break;
2049 break;
2050 }
2051
2052 // Scale and center on the center of \a rect.
2053 scale(xratio, yratio);
2054 centerOn(rect.center());
2055}
2056
2078{
2082 fitInView(path.boundingRect(), aspectRatioMode);
2083 } else {
2084 fitInView(item->d_ptr->sceneTransform.map(path).boundingRect(), aspectRatioMode);
2085 }
2086}
2087
2109 Qt::AspectRatioMode aspectRatioMode)
2110{
2111 // ### Switch to using the recursive rendering algorithm instead.
2112
2113 Q_D(QGraphicsView);
2114 if (!d->scene || !(painter && painter->isActive()))
2115 return;
2116
2117 // Default source rect = viewport rect
2118 QRect sourceRect = source;
2119 if (source.isNull())
2120 sourceRect = viewport()->rect();
2121
2122 // Default target rect = device rect
2123 QRectF targetRect = target;
2124 if (target.isNull()) {
2126 targetRect = sourceRect;
2127 else
2128 targetRect.setRect(0, 0, painter->device()->width(), painter->device()->height());
2129 }
2130
2131 // Find the ideal x / y scaling ratio to fit \a source into \a target.
2132 qreal xratio = targetRect.width() / sourceRect.width();
2133 qreal yratio = targetRect.height() / sourceRect.height();
2134
2135 // Scale according to the aspect ratio mode.
2136 switch (aspectRatioMode) {
2138 xratio = yratio = qMin(xratio, yratio);
2139 break;
2141 xratio = yratio = qMax(xratio, yratio);
2142 break;
2144 break;
2145 }
2146
2147 // Find all items to draw, and reverse the list (we want to draw
2148 // in reverse order).
2149 QPolygonF sourceScenePoly = mapToScene(sourceRect.adjusted(-1, -1, 1, 1));
2150 QList<QGraphicsItem *> itemList = d->scene->items(sourceScenePoly,
2152 QGraphicsItem **itemArray = new QGraphicsItem *[itemList.size()];
2153 int numItems = itemList.size();
2154 for (int i = 0; i < numItems; ++i)
2155 itemArray[numItems - i - 1] = itemList.at(i);
2156 itemList.clear();
2157
2158 // Setup painter matrix.
2159 QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
2160 QTransform painterMatrix = d->matrix * moveMatrix;
2161 painterMatrix *= QTransform()
2162 .translate(targetRect.left(), targetRect.top())
2163 .scale(xratio, yratio)
2164 .translate(-sourceRect.left(), -sourceRect.top());
2165
2166 // Generate the style options
2167 QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
2168 for (int i = 0; i < numItems; ++i)
2169 itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], painterMatrix, targetRect.toRect());
2170
2171 painter->save();
2172
2173 // Clip in device coordinates to avoid QRegion transformations.
2174 painter->setClipRect(targetRect);
2176 path.addPolygon(sourceScenePoly);
2177 path.closeSubpath();
2178 painter->setClipPath(painterMatrix.map(path), Qt::IntersectClip);
2179
2180 // Transform the painter.
2181 painter->setTransform(painterMatrix, true);
2182
2183 // Render the scene.
2184 QRectF sourceSceneRect = sourceScenePoly.boundingRect();
2185 drawBackground(painter, sourceSceneRect);
2186 drawItems(painter, numItems, itemArray, styleOptionArray);
2187 drawForeground(painter, sourceSceneRect);
2188
2189 delete [] itemArray;
2190 d->freeStyleOptionsArray(styleOptionArray);
2191
2192 painter->restore();
2193}
2194
2202QList<QGraphicsItem *> QGraphicsView::items() const
2203{
2204 Q_D(const QGraphicsView);
2205 if (!d->scene)
2206 return QList<QGraphicsItem *>();
2207 return d->scene->items();
2208}
2209
2224QList<QGraphicsItem *> QGraphicsView::items(const QPoint &pos) const
2225{
2226 Q_D(const QGraphicsView);
2227 if (!d->scene)
2228 return QList<QGraphicsItem *>();
2229 // ### Unify these two, and use the items(QPointF) version in
2230 // QGraphicsScene instead. The scene items function could use the viewport
2231 // transform to map the point to a rect/polygon.
2232 if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) {
2233 // Use the rect version
2235 return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1)),
2239 }
2240 // Use the polygon version
2241 return d->scene->items(mapToScene(pos.x(), pos.y(), 1, 1),
2245}
2246
2269QList<QGraphicsItem *> QGraphicsView::items(const QRect &rect, Qt::ItemSelectionMode mode) const
2270{
2271 Q_D(const QGraphicsView);
2272 if (!d->scene)
2273 return QList<QGraphicsItem *>();
2274 return d->scene->items(mapToScene(rect), mode, Qt::DescendingOrder, viewportTransform());
2275}
2276
2301{
2302 Q_D(const QGraphicsView);
2303 if (!d->scene)
2304 return QList<QGraphicsItem *>();
2305 return d->scene->items(mapToScene(polygon), mode, Qt::DescendingOrder, viewportTransform());
2306}
2307
2321{
2322 Q_D(const QGraphicsView);
2323 if (!d->scene)
2324 return QList<QGraphicsItem *>();
2325 return d->scene->items(mapToScene(path), mode, Qt::DescendingOrder, viewportTransform());
2326}
2327
2340{
2341 Q_D(const QGraphicsView);
2342 if (!d->scene)
2343 return nullptr;
2344 const QList<QGraphicsItem *> itemsAtPos = items(pos);
2345 return itemsAtPos.isEmpty() ? nullptr : itemsAtPos.first();
2346}
2347
2366{
2367 Q_D(const QGraphicsView);
2368 QPointF p = point;
2369 p.rx() += d->horizontalScroll();
2370 p.ry() += d->verticalScroll();
2371 return d->identityMatrix ? p : d->matrix.inverted().map(p);
2372}
2373
2388{
2389 Q_D(const QGraphicsView);
2390 if (!rect.isValid())
2391 return QPolygonF();
2392
2393 QPointF scrollOffset(d->horizontalScroll(), d->verticalScroll());
2394 QRect r = rect.adjusted(0, 0, 1, 1);
2395 QPointF tl = scrollOffset + r.topLeft();
2396 QPointF tr = scrollOffset + r.topRight();
2397 QPointF br = scrollOffset + r.bottomRight();
2398 QPointF bl = scrollOffset + r.bottomLeft();
2399
2400 QPolygonF poly(4);
2401 if (!d->identityMatrix) {
2402 QTransform x = d->matrix.inverted();
2403 poly[0] = x.map(tl);
2404 poly[1] = x.map(tr);
2405 poly[2] = x.map(br);
2406 poly[3] = x.map(bl);
2407 } else {
2408 poly[0] = tl;
2409 poly[1] = tr;
2410 poly[2] = br;
2411 poly[3] = bl;
2412 }
2413 return poly;
2414}
2415
2430{
2431 QPolygonF poly;
2432 poly.reserve(polygon.size());
2433 for (const QPoint &point : polygon)
2434 poly << mapToScene(point);
2435 return poly;
2436}
2437
2445{
2446 Q_D(const QGraphicsView);
2447 QTransform matrix = QTransform::fromTranslate(d->horizontalScroll(), d->verticalScroll());
2448 matrix *= d->matrix.inverted();
2449 return matrix.map(path);
2450}
2451
2458{
2459 Q_D(const QGraphicsView);
2460 QPointF p = d->identityMatrix ? point : d->matrix.map(point);
2461 p.rx() -= d->horizontalScroll();
2462 p.ry() -= d->verticalScroll();
2463 return p.toPoint();
2464}
2465
2480{
2481 Q_D(const QGraphicsView);
2482 QPointF tl;
2483 QPointF tr;
2484 QPointF br;
2485 QPointF bl;
2486 if (!d->identityMatrix) {
2487 const QTransform &x = d->matrix;
2488 tl = x.map(rect.topLeft());
2489 tr = x.map(rect.topRight());
2490 br = x.map(rect.bottomRight());
2491 bl = x.map(rect.bottomLeft());
2492 } else {
2493 tl = rect.topLeft();
2494 tr = rect.topRight();
2495 br = rect.bottomRight();
2496 bl = rect.bottomLeft();
2497 }
2498 QPointF scrollOffset(d->horizontalScroll(), d->verticalScroll());
2499 tl -= scrollOffset;
2500 tr -= scrollOffset;
2501 br -= scrollOffset;
2502 bl -= scrollOffset;
2503
2504 QPolygon poly(4);
2505 poly[0] = tl.toPoint();
2506 poly[1] = tr.toPoint();
2507 poly[2] = br.toPoint();
2508 poly[3] = bl.toPoint();
2509 return poly;
2510}
2511
2526{
2527 QPolygon poly;
2528 poly.reserve(polygon.size());
2529 for (const QPointF &point : polygon)
2530 poly << mapFromScene(point);
2531 return poly;
2532}
2533
2541{
2542 Q_D(const QGraphicsView);
2543 QTransform matrix = d->matrix;
2544 matrix *= QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
2545 return matrix.map(path);
2546}
2547
2552{
2553 Q_D(const QGraphicsView);
2554 if (!d->scene)
2555 return QVariant();
2556
2557 QVariant value = d->scene->inputMethodQuery(query);
2558 if (value.userType() == QMetaType::QRectF)
2559 value = d->mapRectFromScene(value.toRectF());
2560 else if (value.userType() == QMetaType::QPointF)
2561 value = mapFromScene(value.toPointF());
2562 else if (value.userType() == QMetaType::QRect)
2563 value = d->mapRectFromScene(value.toRect()).toRect();
2564 else if (value.userType() == QMetaType::QPoint)
2565 value = mapFromScene(value.toPoint());
2566 return value;
2567}
2568
2583{
2584 Q_D(const QGraphicsView);
2585 return d->backgroundBrush;
2586}
2588{
2589 Q_D(QGraphicsView);
2590 d->backgroundBrush = brush;
2591 d->updateAll();
2592
2593 if (d->cacheMode & CacheBackground) {
2594 // Invalidate the background pixmap
2595 d->mustResizeBackgroundPixmap = true;
2596 }
2597}
2598
2613{
2614 Q_D(const QGraphicsView);
2615 return d->foregroundBrush;
2616}
2618{
2619 Q_D(QGraphicsView);
2620 d->foregroundBrush = brush;
2621 d->updateAll();
2622}
2623
2629void QGraphicsView::updateScene(const QList<QRectF> &rects)
2630{
2631 // ### Note: Since 4.5, this slot is only called if the user explicitly
2632 // establishes a connection between the scene and the view, as the scene
2633 // and view are no longer connected. We need to keep it working (basically
2634 // leave it as it is), but the new delivery path is through
2635 // QGraphicsScenePrivate::itemUpdate().
2636 Q_D(QGraphicsView);
2637 if (d->fullUpdatePending || d->viewportUpdateMode == QGraphicsView::NoViewportUpdate)
2638 return;
2639
2640 // Extract and reset dirty scene rect info.
2641 QList<QRect> dirtyViewportRects;
2642 dirtyViewportRects.reserve(d->dirtyRegion.rectCount() + rects.size());
2643 for (const QRect &dirtyRect : d->dirtyRegion)
2644 dirtyViewportRects += dirtyRect;
2645 d->dirtyRegion = QRegion();
2646 d->dirtyBoundingRect = QRect();
2647
2648 bool fullUpdate = !d->accelerateScrolling || d->viewportUpdateMode == QGraphicsView::FullViewportUpdate;
2649 bool boundingRectUpdate = (d->viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate)
2650 || (d->viewportUpdateMode == QGraphicsView::SmartViewportUpdate
2651 && ((dirtyViewportRects.size() + rects.size()) >= QGRAPHICSVIEW_REGION_RECT_THRESHOLD));
2652
2653 QRegion updateRegion;
2655 QRect viewportRect = viewport()->rect();
2656 bool redraw = false;
2658
2659 // Convert scene rects to viewport rects.
2660 for (const QRectF &rect : rects) {
2661 QRect xrect = transform.mapRect(rect).toAlignedRect();
2662 if (!(d->optimizationFlags & DontAdjustForAntialiasing))
2663 xrect.adjust(-2, -2, 2, 2);
2664 else
2665 xrect.adjust(-1, -1, 1, 1);
2666 if (!viewportRect.intersects(xrect))
2667 continue;
2668 dirtyViewportRects << xrect;
2669 }
2670
2671 for (const QRect &rect : std::as_const(dirtyViewportRects)) {
2672 // Add the exposed rect to the update region. In rect update
2673 // mode, we only count the bounding rect of items.
2674 if (!boundingRectUpdate) {
2675 updateRegion += rect;
2676 } else {
2677 boundingRect |= rect;
2678 }
2679 redraw = true;
2680 if (fullUpdate) {
2681 // If fullUpdate is true and we found a visible dirty rect,
2682 // we're done.
2683 break;
2684 }
2685 }
2686
2687 if (!redraw)
2688 return;
2689
2690 if (fullUpdate)
2691 viewport()->update();
2692 else if (boundingRectUpdate)
2693 viewport()->update(boundingRect);
2694 else
2695 viewport()->update(updateRegion);
2696}
2697
2706{
2707 Q_D(QGraphicsView);
2708 if (!d->hasSceneRect) {
2709 d->sceneRect = rect;
2710 d->recalculateContentSize();
2711 }
2712}
2713
2722{
2723 Q_D(QGraphicsView);
2724
2725 if (!widget) {
2726 qWarning("QGraphicsView::setupViewport: cannot initialize null widget");
2727 return;
2728 }
2729
2730 const bool isGLWidget = widget->inherits("QOpenGLWidget");
2731
2732 d->accelerateScrolling = !(isGLWidget);
2733
2735
2736 if (isGLWidget)
2737 d->stereoEnabled = QWidgetPrivate::get(widget)->isStereoEnabled();
2738
2739 if (!isGLWidget) {
2740 // autoFillBackground enables scroll acceleration.
2742 }
2743
2744 // We are only interested in mouse tracking if items
2745 // accept hover events or use non-default cursors or if
2746 // AnchorUnderMouse is used as transformation or resize anchor.
2747 if ((d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents
2748 || !d->scene->d_func()->allItemsUseDefaultCursor))
2749 || d->transformationAnchor == AnchorUnderMouse
2750 || d->resizeAnchor == AnchorUnderMouse) {
2751 widget->setMouseTracking(true);
2752 }
2753
2754 // enable touch events if any items is interested in them
2755 if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents)
2757
2758#ifndef QT_NO_GESTURES
2759 if (d->scene) {
2760 const auto gestures = d->scene->d_func()->grabbedGestures.keys();
2761 for (Qt::GestureType gesture : gestures)
2762 widget->grabGesture(gesture);
2763 }
2764#endif
2765
2766 widget->setAcceptDrops(acceptDrops());
2767}
2768
2773{
2774 Q_D(QGraphicsView);
2775
2776 if (d->sceneInteractionAllowed) {
2777 switch (event->type()) {
2779 if (d->scene)
2780 return QCoreApplication::sendEvent(d->scene, event);
2781 break;
2782 case QEvent::KeyPress:
2783 if (d->scene) {
2784 QKeyEvent *k = static_cast<QKeyEvent *>(event);
2785 if (k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) {
2786 // Send the key events to the scene. This will invoke the
2787 // scene's tab focus handling, and if the event is
2788 // accepted, we return (prevent further event delivery),
2789 // and the base implementation will call QGraphicsView's
2790 // focusNextPrevChild() function. If the event is ignored,
2791 // we fall back to standard tab focus handling.
2793 if (event->isAccepted())
2794 return true;
2795 // Ensure the event doesn't propagate just because the
2796 // scene ignored it. If the event propagates, then tab
2797 // handling will be called twice (this and parent).
2798 event->accept();
2799 }
2800 }
2801 break;
2802 default:
2803 break;
2804 }
2805 }
2806
2807 return QAbstractScrollArea::event(event);
2808}
2809
2814{
2815 Q_D(QGraphicsView);
2816 if (!d->scene)
2817 return QAbstractScrollArea::viewportEvent(event);
2818
2819 switch (event->type()) {
2820 case QEvent::Enter:
2822 break;
2825 break;
2827 // ### This is a temporary fix for until we get proper mouse
2828 // grab events. mouseGrabberItem should be set to 0 if we lose
2829 // the mouse grab.
2830 // Remove all popups when the scene loses focus.
2831 if (!d->scene->d_func()->popupWidgets.isEmpty())
2832 d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.constFirst());
2834 break;
2835 case QEvent::Show:
2836 if (d->scene && isActiveWindow()) {
2837 QEvent windowActivate(QEvent::WindowActivate);
2838 QCoreApplication::sendEvent(d->scene, &windowActivate);
2839 }
2840 break;
2841 case QEvent::Hide:
2842 // spontaneous event will generate a WindowDeactivate.
2843 if (!event->spontaneous() && d->scene && isActiveWindow()) {
2844 QEvent windowDeactivate(QEvent::WindowDeactivate);
2845 QCoreApplication::sendEvent(d->scene, &windowDeactivate);
2846 }
2847 break;
2848 case QEvent::Leave: {
2849 // ### This is a temporary fix for until we get proper mouse grab
2850 // events. activeMouseGrabberItem should be set to 0 if we lose the
2851 // mouse grab.
2854 || (QApplication::activeWindow() != window())) {
2855 if (!d->scene->d_func()->popupWidgets.isEmpty())
2856 d->scene->d_func()->removePopup(d->scene->d_func()->popupWidgets.constFirst());
2857 }
2858 d->useLastMouseEvent = false;
2860 leaveEvent.setWidget(viewport());
2861 QCoreApplication::sendEvent(d->scene, &leaveEvent);
2862 event->setAccepted(leaveEvent.isAccepted());
2863 break;
2864 }
2865#if QT_CONFIG(tooltip)
2866 case QEvent::ToolTip: {
2867 QHelpEvent *toolTip = static_cast<QHelpEvent *>(event);
2869 helpEvent.setWidget(viewport());
2870 helpEvent.setScreenPos(toolTip->globalPos());
2871 helpEvent.setScenePos(mapToScene(toolTip->pos()));
2872 QCoreApplication::sendEvent(d->scene, &helpEvent);
2873 toolTip->setAccepted(helpEvent.isAccepted());
2874 return true;
2875 }
2876#endif
2877 case QEvent::Paint:
2878 // Reset full update
2879 d->fullUpdatePending = false;
2880 d->dirtyScrollOffset = QPoint();
2881 if (d->scene) {
2882 // Check if this view reimplements the updateScene slot; if it
2883 // does, we can't do direct update delivery and have to fall back
2884 // to connecting the changed signal.
2885 if (!d->updateSceneSlotReimplementedChecked) {
2886 d->updateSceneSlotReimplementedChecked = true;
2887 const QMetaObject *mo = metaObject();
2888 if (mo != &QGraphicsView::staticMetaObject) {
2889 if (mo->indexOfSlot("updateScene(QList<QRectF>)")
2890 != QGraphicsView::staticMetaObject.indexOfSlot("updateScene(QList<QRectF>)")) {
2891 connect(d->scene, SIGNAL(changed(QList<QRectF>)),
2892 this, SLOT(updateScene(QList<QRectF>)));
2893 }
2894 }
2895 }
2896 }
2897 break;
2898 case QEvent::TouchBegin:
2900 case QEvent::TouchEnd:
2901 {
2902 if (!isEnabled())
2903 return false;
2904
2905 if (d->scene && d->sceneInteractionAllowed) {
2906 // Convert and deliver the touch event to the scene.
2907 QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
2908 QMutableTouchEvent::from(touchEvent)->setTarget(viewport());
2910 QCoreApplication::sendEvent(d->scene, touchEvent);
2911 } else {
2912 event->ignore();
2913 }
2914
2915 return true;
2916 }
2917#ifndef QT_NO_GESTURES
2918 case QEvent::Gesture:
2920 {
2921 if (!isEnabled())
2922 return false;
2923
2924 if (d->scene && d->sceneInteractionAllowed) {
2925 QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(event);
2926 gestureEvent->setWidget(viewport());
2927 QCoreApplication::sendEvent(d->scene, gestureEvent);
2928 }
2929 return true;
2930 }
2931#endif // QT_NO_GESTURES
2932 default:
2933 break;
2934 }
2935
2936 return QAbstractScrollArea::viewportEvent(event);
2937}
2938
2939#ifndef QT_NO_CONTEXTMENU
2944{
2945 Q_D(QGraphicsView);
2946 if (!d->scene || !d->sceneInteractionAllowed)
2947 return;
2948
2949 d->mousePressViewPoint = event->pos();
2950 d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
2951 d->mousePressScreenPoint = event->globalPos();
2952 d->lastMouseMoveScenePoint = d->mousePressScenePoint;
2953 d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;
2954
2956 contextEvent.setWidget(viewport());
2957 contextEvent.setScenePos(d->mousePressScenePoint);
2958 contextEvent.setScreenPos(d->mousePressScreenPoint);
2959 contextEvent.setModifiers(event->modifiers());
2960 contextEvent.setReason((QGraphicsSceneContextMenuEvent::Reason)(event->reason()));
2961 contextEvent.setAccepted(event->isAccepted());
2962 contextEvent.setTimestamp(event->timestamp());
2963 QCoreApplication::sendEvent(d->scene, &contextEvent);
2964 event->setAccepted(contextEvent.isAccepted());
2965}
2966#endif // QT_NO_CONTEXTMENU
2967
2968#if QT_CONFIG(draganddrop)
2972void QGraphicsView::dropEvent(QDropEvent *event)
2973{
2974 Q_D(QGraphicsView);
2975 if (!d->scene || !d->sceneInteractionAllowed)
2976 return;
2977
2978 // Generate a scene event.
2980 d->populateSceneDragDropEvent(&sceneEvent, event);
2981
2982 // Send it to the scene.
2983 QCoreApplication::sendEvent(d->scene, &sceneEvent);
2984
2985 // Accept the originating event if the scene accepted the scene event.
2986 event->setAccepted(sceneEvent.isAccepted());
2987 if (sceneEvent.isAccepted())
2988 event->setDropAction(sceneEvent.dropAction());
2989
2990 delete d->lastDragDropEvent;
2991 d->lastDragDropEvent = nullptr;
2992}
2993
2997void QGraphicsView::dragEnterEvent(QDragEnterEvent *event)
2998{
2999 Q_D(QGraphicsView);
3000 if (!d->scene || !d->sceneInteractionAllowed)
3001 return;
3002
3003 // Disable replaying of mouse move events.
3004 d->useLastMouseEvent = false;
3005
3006 // Generate a scene event.
3008 d->populateSceneDragDropEvent(&sceneEvent, event);
3009
3010 // Store it for later use.
3011 d->storeDragDropEvent(&sceneEvent);
3012
3013 // Send it to the scene.
3014 QCoreApplication::sendEvent(d->scene, &sceneEvent);
3015
3016 // Accept the originating event if the scene accepted the scene event.
3017 if (sceneEvent.isAccepted()) {
3018 event->setAccepted(true);
3019 event->setDropAction(sceneEvent.dropAction());
3020 }
3021}
3022
3026void QGraphicsView::dragLeaveEvent(QDragLeaveEvent *event)
3027{
3028 Q_D(QGraphicsView);
3029 if (!d->scene || !d->sceneInteractionAllowed)
3030 return;
3031 if (!d->lastDragDropEvent) {
3032 qWarning("QGraphicsView::dragLeaveEvent: drag leave received before drag enter");
3033 return;
3034 }
3035
3036 // Generate a scene event.
3038 sceneEvent.setScenePos(d->lastDragDropEvent->scenePos());
3039 sceneEvent.setScreenPos(d->lastDragDropEvent->screenPos());
3040 sceneEvent.setButtons(d->lastDragDropEvent->buttons());
3041 sceneEvent.setModifiers(d->lastDragDropEvent->modifiers());
3042 sceneEvent.setPossibleActions(d->lastDragDropEvent->possibleActions());
3043 sceneEvent.setProposedAction(d->lastDragDropEvent->proposedAction());
3044 sceneEvent.setDropAction(d->lastDragDropEvent->dropAction());
3045 sceneEvent.setMimeData(d->lastDragDropEvent->mimeData());
3046 sceneEvent.setWidget(d->lastDragDropEvent->widget());
3047 sceneEvent.setSource(d->lastDragDropEvent->source());
3048 delete d->lastDragDropEvent;
3049 d->lastDragDropEvent = nullptr;
3050
3051 // Send it to the scene.
3052 QCoreApplication::sendEvent(d->scene, &sceneEvent);
3053
3054 // Accept the originating event if the scene accepted the scene event.
3055 if (sceneEvent.isAccepted())
3056 event->setAccepted(true);
3057}
3058
3062void QGraphicsView::dragMoveEvent(QDragMoveEvent *event)
3063{
3064 Q_D(QGraphicsView);
3065 if (!d->scene || !d->sceneInteractionAllowed)
3066 return;
3067
3068 // Generate a scene event.
3070 d->populateSceneDragDropEvent(&sceneEvent, event);
3071
3072 // Store it for later use.
3073 d->storeDragDropEvent(&sceneEvent);
3074
3075 // Send it to the scene.
3076 QCoreApplication::sendEvent(d->scene, &sceneEvent);
3077
3078 // Ignore the originating event if the scene ignored the scene event.
3079 event->setAccepted(sceneEvent.isAccepted());
3080 if (sceneEvent.isAccepted())
3081 event->setDropAction(sceneEvent.dropAction());
3082}
3083#endif // QT_CONFIG(draganddrop)
3084
3089{
3090 Q_D(QGraphicsView);
3091 d->updateInputMethodSensitivity();
3092 QAbstractScrollArea::focusInEvent(event);
3093 if (d->scene)
3095 // Pass focus on if the scene cannot accept focus.
3096 if (!d->scene || !event->isAccepted())
3097 QAbstractScrollArea::focusInEvent(event);
3098}
3099
3104{
3105 return QAbstractScrollArea::focusNextPrevChild(next);
3106}
3107
3112{
3113 Q_D(QGraphicsView);
3114 QAbstractScrollArea::focusOutEvent(event);
3115 if (d->scene)
3117}
3118
3123{
3124 Q_D(QGraphicsView);
3125 if (!d->scene || !d->sceneInteractionAllowed) {
3126 QAbstractScrollArea::keyPressEvent(event);
3127 return;
3128 }
3130 if (!event->isAccepted())
3131 QAbstractScrollArea::keyPressEvent(event);
3132}
3133
3138{
3139 Q_D(QGraphicsView);
3140 if (!d->scene || !d->sceneInteractionAllowed)
3141 return;
3143 if (!event->isAccepted())
3144 QAbstractScrollArea::keyReleaseEvent(event);
3145}
3146
3151{
3152 Q_D(QGraphicsView);
3153 if (!d->scene || !d->sceneInteractionAllowed)
3154 return;
3155
3156 d->storeMouseEvent(event);
3157 d->mousePressViewPoint = event->position().toPoint();
3158 d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
3159 d->mousePressScreenPoint = event->globalPosition().toPoint();
3160 d->lastMouseMoveScenePoint = d->mousePressScenePoint;
3161 d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;
3162 d->mousePressButton = event->button();
3163
3165 mouseEvent.setWidget(viewport());
3166 mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
3167 mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
3168 mouseEvent.setScenePos(mapToScene(d->mousePressViewPoint));
3169 mouseEvent.setScreenPos(d->mousePressScreenPoint);
3170 mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
3171 mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
3172 mouseEvent.setButtons(event->buttons());
3173 mouseEvent.setAccepted(false);
3174 mouseEvent.setButton(event->button());
3175 mouseEvent.setModifiers(event->modifiers());
3176 mouseEvent.setSource(event->source());
3177 mouseEvent.setFlags(event->flags());
3178 mouseEvent.setTimestamp(event->timestamp());
3179 if (event->spontaneous())
3180 qt_sendSpontaneousEvent(d->scene, &mouseEvent);
3181 else
3182 QCoreApplication::sendEvent(d->scene, &mouseEvent);
3183
3184 // Update the original mouse event accepted state.
3185 const bool isAccepted = mouseEvent.isAccepted();
3186 event->setAccepted(isAccepted);
3187
3188 // Update the last mouse event accepted state.
3189 d->lastMouseEvent.setAccepted(isAccepted);
3190}
3191
3196{
3197 Q_D(QGraphicsView);
3198
3199 // Store this event for replaying, finding deltas, and for
3200 // scroll-dragging; even in non-interactive mode, scroll hand dragging is
3201 // allowed, so we store the event at the very top of this function.
3202 d->storeMouseEvent(event);
3203 d->lastMouseEvent.setAccepted(false);
3204
3205 if (d->sceneInteractionAllowed) {
3206 // Store some of the event's button-down data.
3207 d->mousePressViewPoint = event->position().toPoint();
3208 d->mousePressScenePoint = mapToScene(d->mousePressViewPoint);
3209 d->mousePressScreenPoint = event->globalPosition().toPoint();
3210 d->lastMouseMoveScenePoint = d->mousePressScenePoint;
3211 d->lastMouseMoveScreenPoint = d->mousePressScreenPoint;
3212 d->mousePressButton = event->button();
3213
3214 if (d->scene) {
3215 // Convert and deliver the mouse event to the scene.
3217 mouseEvent.setWidget(viewport());
3218 mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
3219 mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
3220 mouseEvent.setScenePos(d->mousePressScenePoint);
3221 mouseEvent.setScreenPos(d->mousePressScreenPoint);
3222 mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
3223 mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
3224 mouseEvent.setButtons(event->buttons());
3225 mouseEvent.setButton(event->button());
3226 mouseEvent.setModifiers(event->modifiers());
3227 mouseEvent.setSource(event->source());
3228 mouseEvent.setFlags(event->flags());
3229 mouseEvent.setAccepted(false);
3230 mouseEvent.setTimestamp(event->timestamp());
3231 if (event->spontaneous())
3232 qt_sendSpontaneousEvent(d->scene, &mouseEvent);
3233 else
3234 QCoreApplication::sendEvent(d->scene, &mouseEvent);
3235
3236 // Update the original mouse event accepted state.
3237 bool isAccepted = mouseEvent.isAccepted();
3238 event->setAccepted(isAccepted);
3239
3240 // Update the last mouse event accepted state.
3241 d->lastMouseEvent.setAccepted(isAccepted);
3242
3243 if (isAccepted)
3244 return;
3245 }
3246 }
3247
3248#if QT_CONFIG(rubberband)
3249 if (d->dragMode == QGraphicsView::RubberBandDrag && !d->rubberBanding) {
3250 if (d->sceneInteractionAllowed) {
3251 // Rubberbanding is only allowed in interactive mode.
3252 event->accept();
3253 d->rubberBanding = true;
3254 d->rubberBandRect = QRect();
3255 if (d->scene) {
3256 bool extendSelection = (event->modifiers() & Qt::ControlModifier) != 0;
3257
3258 if (extendSelection) {
3259 d->rubberBandSelectionOperation = Qt::AddToSelection;
3260 } else {
3261 d->rubberBandSelectionOperation = Qt::ReplaceSelection;
3262 d->scene->clearSelection();
3263 }
3264 }
3265 }
3266 } else
3267#endif
3268 if (d->dragMode == QGraphicsView::ScrollHandDrag && event->button() == Qt::LeftButton) {
3269 // Left-button press in scroll hand mode initiates hand scrolling.
3270 event->accept();
3271 d->handScrolling = true;
3272 d->handScrollMotions = 0;
3273#ifndef QT_NO_CURSOR
3274 viewport()->setCursor(Qt::ClosedHandCursor);
3275#endif
3276 }
3277}
3278
3283{
3284 Q_D(QGraphicsView);
3285
3286 if (d->dragMode == QGraphicsView::ScrollHandDrag) {
3287 if (d->handScrolling) {
3288 QScrollBar *hBar = horizontalScrollBar();
3289 QScrollBar *vBar = verticalScrollBar();
3290 QPoint delta = event->position().toPoint() - d->lastMouseEvent.position().toPoint();
3291 hBar->setValue(hBar->value() + (isRightToLeft() ? delta.x() : -delta.x()));
3292 vBar->setValue(vBar->value() - delta.y());
3293
3294 // Detect how much we've scrolled to disambiguate scrolling from
3295 // clicking.
3296 ++d->handScrollMotions;
3297 }
3298 }
3299
3300 d->mouseMoveEventHandler(event);
3301}
3302
3307{
3308 Q_D(QGraphicsView);
3309
3310#if QT_CONFIG(rubberband)
3311 if (d->dragMode == QGraphicsView::RubberBandDrag && d->sceneInteractionAllowed && !event->buttons()) {
3312 d->clearRubberBand();
3313 } else
3314#endif
3315 if (d->dragMode == QGraphicsView::ScrollHandDrag && event->button() == Qt::LeftButton) {
3316#ifndef QT_NO_CURSOR
3317 // Restore the open hand cursor. ### There might be items
3318 // under the mouse that have a valid cursor at this time, so
3319 // we could repeat the steps from mouseMoveEvent().
3320 viewport()->setCursor(Qt::OpenHandCursor);
3321#endif
3322 d->handScrolling = false;
3323
3324 if (d->scene && d->sceneInteractionAllowed && !d->lastMouseEvent.isAccepted() && d->handScrollMotions <= 6) {
3325 // If we've detected very little motion during the hand drag, and
3326 // no item accepted the last event, we'll interpret that as a
3327 // click to the scene, and reset the selection.
3328 d->scene->clearSelection();
3329 }
3330 }
3331
3332 d->storeMouseEvent(event);
3333
3334 if (!d->sceneInteractionAllowed)
3335 return;
3336
3337 if (!d->scene)
3338 return;
3339
3341 mouseEvent.setWidget(viewport());
3342 mouseEvent.setButtonDownScenePos(d->mousePressButton, d->mousePressScenePoint);
3343 mouseEvent.setButtonDownScreenPos(d->mousePressButton, d->mousePressScreenPoint);
3344 mouseEvent.setScenePos(mapToScene(event->position().toPoint()));
3345 mouseEvent.setScreenPos(event->globalPosition().toPoint());
3346 mouseEvent.setLastScenePos(d->lastMouseMoveScenePoint);
3347 mouseEvent.setLastScreenPos(d->lastMouseMoveScreenPoint);
3348 mouseEvent.setButtons(event->buttons());
3349 mouseEvent.setButton(event->button());
3350 mouseEvent.setModifiers(event->modifiers());
3351 mouseEvent.setSource(event->source());
3352 mouseEvent.setFlags(event->flags());
3353 mouseEvent.setAccepted(false);
3354 mouseEvent.setTimestamp(event->timestamp());
3355 if (event->spontaneous())
3356 qt_sendSpontaneousEvent(d->scene, &mouseEvent);
3357 else
3358 QCoreApplication::sendEvent(d->scene, &mouseEvent);
3359
3360 // Update the last mouse event selected state.
3361 d->lastMouseEvent.setAccepted(mouseEvent.isAccepted());
3362
3363#ifndef QT_NO_CURSOR
3364 if (mouseEvent.isAccepted() && mouseEvent.buttons() == 0 && viewport()->testAttribute(Qt::WA_SetCursor)) {
3365 // The last mouse release on the viewport will trigger clearing the cursor.
3366 d->_q_unsetViewportCursor();
3367 }
3368#endif
3369}
3370
3371#if QT_CONFIG(wheelevent)
3375void QGraphicsView::wheelEvent(QWheelEvent *event)
3376{
3377 Q_D(QGraphicsView);
3378 if (!d->scene || !d->sceneInteractionAllowed) {
3379 QAbstractScrollArea::wheelEvent(event);
3380 return;
3381 }
3382
3383 event->ignore();
3384
3386 wheelEvent.setWidget(viewport());
3387 wheelEvent.setScenePos(mapToScene(event->position().toPoint()));
3388 wheelEvent.setScreenPos(event->globalPosition().toPoint());
3389 wheelEvent.setButtons(event->buttons());
3390 wheelEvent.setModifiers(event->modifiers());
3391 const bool horizontal = qAbs(event->angleDelta().x()) > qAbs(event->angleDelta().y());
3392 wheelEvent.setDelta(horizontal ? event->angleDelta().x() : event->angleDelta().y());
3393 wheelEvent.setPixelDelta(event->pixelDelta());
3394 wheelEvent.setPhase(event->phase());
3395 wheelEvent.setInverted(event->isInverted());
3396 wheelEvent.setOrientation(horizontal ? Qt::Horizontal : Qt::Vertical);
3397 wheelEvent.setAccepted(false);
3398 wheelEvent.setTimestamp(event->timestamp());
3399 QCoreApplication::sendEvent(d->scene, &wheelEvent);
3400 event->setAccepted(wheelEvent.isAccepted());
3401 if (!event->isAccepted())
3402 QAbstractScrollArea::wheelEvent(event);
3403}
3404#endif // QT_CONFIG(wheelevent)
3405
3410{
3411 Q_D(QGraphicsView);
3412 if (!d->scene) {
3413 QAbstractScrollArea::paintEvent(event);
3414 return;
3415 }
3416
3417 // Set up painter state protection.
3418 d->scene->d_func()->painterStateProtection = !(d->optimizationFlags & DontSavePainterState);
3419
3420 // Determine the exposed region
3421 d->exposedRegion = event->region();
3422 QRectF exposedSceneRect = mapToScene(d->exposedRegion.boundingRect()).boundingRect();
3423
3424 // Set up the painter
3426#if QT_CONFIG(rubberband)
3427 if (d->rubberBanding && !d->rubberBandRect.isEmpty())
3428 painter.save();
3429#endif
3430 // Set up render hints
3432 painter.setRenderHints(d->renderHints, true);
3433
3434 // Set up viewport transform
3435 const bool viewTransformed = isTransformed();
3436 if (viewTransformed)
3438 const QTransform viewTransform = painter.worldTransform();
3439
3440 const auto actuallyDraw = [&]() {
3441 // Draw background
3442 if (d->cacheMode & CacheBackground) {
3443 // Recreate the background pixmap, and flag the whole background as
3444 // exposed.
3445 if (d->mustResizeBackgroundPixmap) {
3446 const qreal dpr = d->viewport->devicePixelRatio();
3447 d->backgroundPixmap = QPixmap(viewport()->size() * dpr);
3448 d->backgroundPixmap.setDevicePixelRatio(dpr);
3449 QBrush bgBrush = viewport()->palette().brush(viewport()->backgroundRole());
3450 if (!bgBrush.isOpaque())
3451 d->backgroundPixmap.fill(Qt::transparent);
3452 QPainter p(&d->backgroundPixmap);
3453 p.fillRect(0, 0, d->backgroundPixmap.width(), d->backgroundPixmap.height(), bgBrush);
3454 d->backgroundPixmapExposed = QRegion(viewport()->rect());
3455 d->mustResizeBackgroundPixmap = false;
3456 }
3457
3458 // Redraw exposed areas
3459 if (!d->backgroundPixmapExposed.isEmpty()) {
3460 QPainter backgroundPainter(&d->backgroundPixmap);
3461 backgroundPainter.setClipRegion(d->backgroundPixmapExposed, Qt::ReplaceClip);
3462 if (viewTransformed)
3463 backgroundPainter.setTransform(viewTransform);
3464 QRectF backgroundExposedSceneRect = mapToScene(d->backgroundPixmapExposed.boundingRect()).boundingRect();
3465 drawBackground(&backgroundPainter, backgroundExposedSceneRect);
3466 d->backgroundPixmapExposed = QRegion();
3467 }
3468
3469 // Blit the background from the background pixmap
3470 if (viewTransformed) {
3472 painter.drawPixmap(QPoint(), d->backgroundPixmap);
3473 painter.setWorldTransform(viewTransform);
3474 } else {
3475 painter.drawPixmap(QPoint(), d->backgroundPixmap);
3476 }
3477 } else {
3478 if (!(d->optimizationFlags & DontSavePainterState))
3479 painter.save();
3480
3481 drawBackground(&painter, exposedSceneRect);
3482 if (!(d->optimizationFlags & DontSavePainterState))
3483 painter.restore();
3484 }
3485
3486 // Items
3487 if (!(d->optimizationFlags & IndirectPainting)) {
3488 const quint32 oldRectAdjust = d->scene->d_func()->rectAdjust;
3489 if (d->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
3490 d->scene->d_func()->rectAdjust = 1;
3491 else
3492 d->scene->d_func()->rectAdjust = 2;
3493 d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : nullptr,
3494 &d->exposedRegion, viewport());
3495 d->scene->d_func()->rectAdjust = oldRectAdjust;
3496 // Make sure the painter's world transform is restored correctly when
3497 // drawing without painter state protection (DontSavePainterState).
3498 // We only change the worldTransform() so there's no need to do a full-blown
3499 // save() and restore(). Also note that we don't have to do this in case of
3500 // IndirectPainting (the else branch), because in that case we always save()
3501 // and restore() in QGraphicsScene::drawItems().
3502 if (!d->scene->d_func()->painterStateProtection)
3503 painter.setOpacity(1.0);
3504 painter.setWorldTransform(viewTransform);
3505 } else {
3506 // Make sure we don't have unpolished items before we draw
3507 if (!d->scene->d_func()->unpolishedItems.isEmpty())
3508 d->scene->d_func()->_q_polishItems();
3509 // We reset updateAll here (after we've issued polish events)
3510 // so that we can discard update requests coming from polishEvent().
3511 d->scene->d_func()->updateAll = false;
3512
3513 // Find all exposed items
3514 bool allItems = false;
3515 QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems, viewTransform);
3516 if (!itemList.isEmpty()) {
3517 // Generate the style options.
3518 const int numItems = itemList.size();
3519 QGraphicsItem **itemArray = &itemList[0]; // Relies on QList internals, but is perfectly valid.
3520 QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
3522 for (int i = 0; i < numItems; ++i) {
3523 QGraphicsItem *item = itemArray[i];
3524 QGraphicsItemPrivate *itemd = item->d_ptr.data();
3525 itemd->initStyleOption(&styleOptionArray[i], viewTransform, d->exposedRegion, allItems);
3526 // Cache the item's area in view coordinates.
3527 // Note that we have to do this here in case the base class implementation
3528 // (QGraphicsScene::drawItems) is not called. If it is, we'll do this
3529 // operation twice, but that's the price one has to pay for using indirect
3530 // painting :-/.
3532 if (!itemd->itemIsUntransformable()) {
3534 if (viewTransformed)
3535 transform *= viewTransform;
3536 } else {
3537 transform = item->deviceTransform(viewTransform);
3538 }
3539 itemd->paintedViewBoundingRects.insert(d->viewport, transform.mapRect(brect).toRect());
3540 }
3541 // Draw the items.
3542 drawItems(&painter, numItems, itemArray, styleOptionArray);
3543 d->freeStyleOptionsArray(styleOptionArray);
3544 }
3545 }
3546
3547 // Foreground
3548 drawForeground(&painter, exposedSceneRect);
3549
3550 #if QT_CONFIG(rubberband)
3551 // Rubberband
3552 if (d->rubberBanding && !d->rubberBandRect.isEmpty()) {
3553 painter.restore();
3554 QStyleOptionRubberBand option;
3555 option.initFrom(viewport());
3556 option.rect = d->rubberBandRect;
3558
3560 if (viewport()->style()->styleHint(QStyle::SH_RubberBand_Mask, &option, viewport(), &mask)) {
3561 // painter clipping for masked rubberbands
3563 }
3564
3565 viewport()->style()->drawControl(QStyle::CE_RubberBand, &option, &painter, viewport());
3566 }
3567 #endif
3568 };
3569
3570 actuallyDraw();
3571
3572 // For stereo we want to draw everything twice, once to each buffer
3573 if (d->stereoEnabled) {
3575 if (w->toggleStereoTargetBuffer()) {
3576 actuallyDraw();
3577 w->toggleStereoTargetBuffer();
3578 }
3579 }
3580
3581 painter.end();
3582
3583 // Restore painter state protection.
3584 d->scene->d_func()->painterStateProtection = true;
3585}
3586
3591{
3592 Q_D(QGraphicsView);
3593 // Save the last center point - the resize may scroll the view, which
3594 // changes the center point.
3595 QPointF oldLastCenterPoint = d->lastCenterPoint;
3596
3597 QAbstractScrollArea::resizeEvent(event);
3598 d->recalculateContentSize();
3599
3600 // Restore the center point again.
3601 if (d->resizeAnchor == NoAnchor && !d->keepLastCenterPoint) {
3602 d->updateLastCenterPoint();
3603 } else {
3604 d->lastCenterPoint = oldLastCenterPoint;
3605 }
3606 d->centerView(d->resizeAnchor);
3607 d->keepLastCenterPoint = false;
3608
3609 if (d->cacheMode & CacheBackground) {
3610 // Invalidate the background pixmap
3611 d->mustResizeBackgroundPixmap = true;
3612 }
3613}
3614
3619{
3620 Q_D(QGraphicsView);
3621 d->dirtyScroll = true;
3622 if (d->transforming)
3623 return;
3624 if (isRightToLeft())
3625 dx = -dx;
3626
3627 if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate) {
3628 if (d->viewportUpdateMode != QGraphicsView::FullViewportUpdate) {
3629 if (d->accelerateScrolling) {
3630#if QT_CONFIG(rubberband)
3631 // Update new and old rubberband regions
3632 if (!d->rubberBandRect.isEmpty()) {
3633 QRegion rubberBandRegion(d->rubberBandRegion(viewport(), d->rubberBandRect));
3634 rubberBandRegion += rubberBandRegion.translated(-dx, -dy);
3635 viewport()->update(rubberBandRegion);
3636 }
3637#endif
3638 d->dirtyScrollOffset.rx() += dx;
3639 d->dirtyScrollOffset.ry() += dy;
3640 d->dirtyRegion.translate(dx, dy);
3641 viewport()->scroll(dx, dy);
3642 } else {
3643 d->updateAll();
3644 }
3645 } else {
3646 d->updateAll();
3647 }
3648 }
3649
3650 d->updateLastCenterPoint();
3651
3652 if (d->cacheMode & CacheBackground) {
3653 // Below, QPixmap::scroll() works in device pixels, while the delta values
3654 // and backgroundPixmapExposed are in device independent pixels.
3655 const qreal dpr = d->backgroundPixmap.devicePixelRatio();
3656 const qreal inverseDpr = qreal(1) / dpr;
3657
3658 // Scroll the background pixmap
3659 QRegion exposed;
3660 if (!d->backgroundPixmap.isNull())
3661 d->backgroundPixmap.scroll(dx * dpr, dy * dpr, d->backgroundPixmap.rect(), &exposed);
3662
3663 // Invalidate the background pixmap
3664 d->backgroundPixmapExposed.translate(dx, dy);
3665 const QRegion exposedScaled = QTransform::fromScale(inverseDpr, inverseDpr).map(exposed);
3666 d->backgroundPixmapExposed += exposedScaled;
3667 }
3668
3669 // Always replay on scroll.
3670 if (d->sceneInteractionAllowed)
3671 d->replayLastMouseEvent();
3672}
3673
3678{
3679 Q_D(QGraphicsView);
3680 d->recalculateContentSize();
3681 d->centerView(d->transformationAnchor);
3682 QAbstractScrollArea::showEvent(event);
3683}
3684
3689{
3690 Q_D(QGraphicsView);
3691 if (d->scene)
3693}
3694
3713{
3714 Q_D(QGraphicsView);
3715 if (d->scene && d->backgroundBrush.style() == Qt::NoBrush) {
3716 d->scene->drawBackground(painter, rect);
3717 return;
3718 }
3719
3720 const bool wasAa = painter->testRenderHint(QPainter::Antialiasing);
3721 if (wasAa)
3723 painter->fillRect(rect, d->backgroundBrush);
3724 if (wasAa)
3726}
3727
3746{
3747 Q_D(QGraphicsView);
3748 if (d->scene && d->foregroundBrush.style() == Qt::NoBrush) {
3749 d->scene->drawForeground(painter, rect);
3750 return;
3751 }
3752
3753 painter->fillRect(rect, d->foregroundBrush);
3754}
3755
3775 const QStyleOptionGraphicsItem options[])
3776{
3777 Q_D(QGraphicsView);
3778 if (d->scene) {
3779 QWidget *widget = painter->device() == viewport() ? viewport() : nullptr;
3780 d->scene->drawItems(painter, numItems, items, options, widget);
3781 }
3782}
3783
3791{
3792 Q_D(const QGraphicsView);
3793 return d->matrix;
3794}
3795
3802{
3803 Q_D(const QGraphicsView);
3804 QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll());
3805 return d->identityMatrix ? moveMatrix : d->matrix * moveMatrix;
3806}
3807
3817{
3818 Q_D(const QGraphicsView);
3819 return !d->identityMatrix || d->horizontalScroll() || d->verticalScroll();
3820}
3821
3849{
3850 Q_D(QGraphicsView);
3851 QTransform oldMatrix = d->matrix;
3852 if (!combine)
3853 d->matrix = matrix;
3854 else
3855 d->matrix = matrix * d->matrix;
3856 if (oldMatrix == d->matrix)
3857 return;
3858
3859 d->identityMatrix = d->matrix.isIdentity();
3860 d->transforming = true;
3861 if (d->scene) {
3862 d->recalculateContentSize();
3863 d->centerView(d->transformationAnchor);
3864 } else {
3865 d->updateLastCenterPoint();
3866 }
3867
3868 if (d->sceneInteractionAllowed)
3869 d->replayLastMouseEvent();
3870 d->transforming = false;
3871
3872 // Any matrix operation requires a full update.
3873 d->updateAll();
3874}
3875
3885
3887{
3888 QPointF p = point;
3889 p.rx() += horizontalScroll();
3890 p.ry() += verticalScroll();
3891 return identityMatrix ? p : matrix.inverted().map(p);
3892}
3893
3895{
3896 QPointF scrollOffset(horizontalScroll(), verticalScroll());
3897 QPointF tl = scrollOffset + rect.topLeft();
3898 QPointF tr = scrollOffset + rect.topRight();
3899 QPointF br = scrollOffset + rect.bottomRight();
3900 QPointF bl = scrollOffset + rect.bottomLeft();
3901
3902 QPolygonF poly(4);
3903 if (!identityMatrix) {
3905 poly[0] = x.map(tl);
3906 poly[1] = x.map(tr);
3907 poly[2] = x.map(br);
3908 poly[3] = x.map(bl);
3909 } else {
3910 poly[0] = tl;
3911 poly[1] = tr;
3912 poly[2] = br;
3913 poly[3] = bl;
3914 }
3915 return poly.boundingRect();
3916}
3917
3919
3920#include "moc_qgraphicsview.cpp"
static QWidget * activeModalWidget()
Returns the active modal widget.
static QWidget * activePopupWidget()
Returns the active popup widget.
int startDragDistance
the minimum distance required for a drag and drop operation to start.
static QWidget * activeWindow()
Returns the application top-level window that has the keyboard input focus, or \nullptr if no applica...
\inmodule QtGui
Definition qbrush.h:30
bool isOpaque() const
Returns true if the brush is fully opaque otherwise false.
Definition qbrush.cpp:830
The QContextMenuEvent class contains parameters that describe a context menu event.
Definition qevent.h:594
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
The QCursor class provides a mouse cursor with an arbitrary shape.
Definition qcursor.h:45
static QPoint pos()
Returns the position of the cursor (hot spot) of the primary screen in global screen coordinates.
Definition qcursor.cpp:188
\inmodule QtCore
Definition qcoreevent.h:45
virtual void setAccepted(bool accepted)
Definition qcoreevent.h:307
@ GraphicsSceneDragLeave
Definition qcoreevent.h:200
@ GraphicsSceneMouseMove
Definition qcoreevent.h:189
@ GestureOverride
Definition qcoreevent.h:254
@ GraphicsSceneContextMenu
Definition qcoreevent.h:193
@ GraphicsSceneMouseRelease
Definition qcoreevent.h:191
@ GraphicsSceneDragEnter
Definition qcoreevent.h:198
@ GraphicsSceneDragMove
Definition qcoreevent.h:199
@ ShortcutOverride
Definition qcoreevent.h:158
@ GraphicsSceneMousePress
Definition qcoreevent.h:190
@ KeyPress
Definition qcoreevent.h:64
@ TouchUpdate
Definition qcoreevent.h:242
@ TouchBegin
Definition qcoreevent.h:241
@ WindowActivate
Definition qcoreevent.h:83
@ GraphicsSceneMouseDoubleClick
Definition qcoreevent.h:192
@ GraphicsSceneWheel
Definition qcoreevent.h:202
@ GraphicsSceneDrop
Definition qcoreevent.h:201
@ GraphicsSceneHelp
Definition qcoreevent.h:197
@ WindowDeactivate
Definition qcoreevent.h:84
@ GraphicsSceneLeave
Definition qcoreevent.h:203
bool isAccepted() const
Definition qcoreevent.h:308
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:470
The QGestureEvent class provides the description of triggered gestures.
Definition qgesture.h:244
void setWidget(QWidget *widget)
void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, const QRegion &exposedRegion, bool allItems=false) const
bool itemIsUntransformable() const
virtual bool isProxyWidget() const
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
QTransform deviceTransform(const QTransform &viewportTransform) const
QScopedPointer< QGraphicsItemPrivate > d_ptr
QPainterPath clipPath() const
virtual QPainterPath shape() const
Returns the shape of this item as a QPainterPath in local coordinates.
QRectF sceneBoundingRect() const
Returns the bounding rect of this item in scene coordinates, by combining sceneTransform() with bound...
virtual QRectF boundingRect() const =0
This pure virtual function defines the outer bounds of the item as a rectangle; all painting must be ...
QCursor cursor() const
Returns the current cursor shape for the item.
bool isEnabled() const
Returns true if the item is enabled; otherwise, false is returned.
bool isClipped() const
Returns true if this item is clipped.
bool hasCursor() const
Returns true if this item has a cursor set; otherwise, false is returned.
QTransform sceneTransform() const
QRegion boundingRegion(const QTransform &itemToDeviceTransform) const
Qt::InputMethodHints inputMethodHints() const
Returns the current input method hints of this item.
The QGraphicsProxyWidget class provides a proxy layer for embedding a QWidget in a QGraphicsScene.
The QGraphicsSceneContextMenuEvent class provides context menu events in the graphics view framework.
Reason
This enum describes the reason why the context event was sent.
The QGraphicsSceneDragDropEvent class provides events for drag and drop in the graphics view framewor...
void setButtons(Qt::MouseButtons buttons)
void setMimeData(const QMimeData *data)
void setPossibleActions(Qt::DropActions actions)
void setProposedAction(Qt::DropAction action)
void setModifiers(Qt::KeyboardModifiers modifiers)
void setDropAction(Qt::DropAction action)
This function lets the receiver of the drop set the drop action that was performed to action,...
void setScreenPos(const QPoint &pos)
void setScenePos(const QPointF &pos)
The QGraphicsSceneEvent class provides a base class for all graphics view related events.
void setWidget(QWidget *widget)
void setTimestamp(quint64 ts)
QWidget * widget() const
Returns the widget where the event originated, or \nullptr if the event originates from another appli...
The QGraphicsSceneHelpEvent class provides events when a tooltip is requested.
void setScenePos(const QPointF &pos)
void setScreenPos(const QPoint &pos)
The QGraphicsSceneMouseEvent class provides mouse events in the graphics view framework.
void setFlags(Qt::MouseEventFlags)
void setLastScenePos(const QPointF &pos)
void setButton(Qt::MouseButton button)
void setScenePos(const QPointF &pos)
QPoint screenPos() const
Returns the mouse cursor position in screen coordinates.
Qt::MouseButtons buttons() const
Returns the combination of mouse buttons that were pressed at the time the event was sent.
void setButtonDownScenePos(Qt::MouseButton button, const QPointF &pos)
void setButtons(Qt::MouseButtons buttons)
QPointF scenePos() const
Returns the mouse cursor position in scene coordinates.
void setModifiers(Qt::KeyboardModifiers modifiers)
void setButtonDownScreenPos(Qt::MouseButton button, const QPoint &pos)
void setLastScreenPos(const QPoint &pos)
void setSource(Qt::MouseEventSource source)
void setScreenPos(const QPoint &pos)
The QGraphicsSceneWheelEvent class provides wheel events in the graphics view framework.
The QGraphicsScene class provides a surface for managing a large number of 2D graphical items.
QList< QGraphicsItem * > items(Qt::SortOrder order=Qt::DescendingOrder) const
Returns an ordered list of all items on the scene.
QRectF sceneRect
the scene rectangle; the bounding rectangle of the scene
void setSelectionArea(const QPainterPath &path, const QTransform &deviceTransform)
QGraphicsItem * focusItem() const
When the scene is active, this functions returns the scene's current focus item, or \nullptr if no it...
QRect mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const
void storeDragDropEvent(const QGraphicsSceneDragDropEvent *event)
QMutableSinglePointEvent lastMouseEvent
Qt::Alignment alignment
void freeStyleOptionsArray(QStyleOptionGraphicsItem *array)
QPointer< QGraphicsScene > scene
bool updateRegion(const QRectF &rect, const QTransform &xform)
QGraphicsView::DragMode dragMode
bool updateRect(const QRect &rect)
void _q_setViewportCursor(const QCursor &cursor)
qint64 horizontalScroll() const
bool updateRectF(const QRectF &rect)
QGraphicsView::ViewportUpdateMode viewportUpdateMode
static void translateTouchEvent(QGraphicsViewPrivate *d, QTouchEvent *touchEvent)
QGraphicsView::OptimizationFlags optimizationFlags
qint64 verticalScroll() const
QRectF mapRectToScene(const QRect &rect) const
QList< QStyleOptionGraphicsItem > styleOptions
QList< QGraphicsItem * > findItems(const QRegion &exposedRegion, bool *allItems, const QTransform &viewTransform) const
QRectF mapRectFromScene(const QRectF &rect) const
void populateSceneDragDropEvent(QGraphicsSceneDragDropEvent *dest, QDropEvent *source)
QPointF mapToScene(const QPointF &point) const
void mouseMoveEventHandler(QMouseEvent *event)
QStyleOptionGraphicsItem * allocStyleOptionsArray(int numItems)
QGraphicsSceneDragDropEvent * lastDragDropEvent
void centerView(QGraphicsView::ViewportAnchor anchor)
bool canStartScrollingAt(const QPoint &startPos) const override
QRegion mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const
void storeMouseEvent(QMouseEvent *event)
Qt::MouseButton mousePressButton
void setUpdateClip(QGraphicsItem *)
QGraphicsView::CacheMode cacheMode
The QGraphicsView class provides a widget for displaying the contents of a QGraphicsScene.
QPainter::RenderHints renderHints
the default render hints for the view
void mousePressEvent(QMouseEvent *event) override
\reimp
void setInteractive(bool allowed)
void shear(qreal sh, qreal sv)
Shears the current view transformation by (sh, sv).
QPointF mapToScene(const QPoint &point) const
Returns the viewport coordinate point mapped to scene coordinates.
void mouseMoveEvent(QMouseEvent *event) override
\reimp
QSize sizeHint() const override
\reimp
QList< QGraphicsItem * > items() const
Returns a list of all the items in the associated scene, in descending stacking order (i....
void setResizeAnchor(ViewportAnchor anchor)
void updateScene(const QList< QRectF > &rects)
Schedules an update of the scene rectangles rects.
void centerOn(const QPointF &pos)
Scrolls the contents of the viewport to ensure that the scene coordinate pos, is centered in the view...
void focusInEvent(QFocusEvent *event) override
\reimp
void updateSceneRect(const QRectF &rect)
Notifies QGraphicsView that the scene's scene rect has changed.
void setForegroundBrush(const QBrush &brush)
ViewportUpdateMode viewportUpdateMode
how the viewport should update its contents.
void setTransform(const QTransform &matrix, bool combine=false)
Sets the view's current transformation matrix to matrix.
bool isInteractive() const
void resetCachedContent()
Resets any cached content.
void setDragMode(DragMode mode)
QBrush backgroundBrush
the background brush of the scene.
void setRenderHints(QPainter::RenderHints hints)
void contextMenuEvent(QContextMenuEvent *event) override
\reimp
void setBackgroundBrush(const QBrush &brush)
void translate(qreal dx, qreal dy)
Translates the current view transformation by (dx, dy).
void setOptimizationFlag(OptimizationFlag flag, bool enabled=true)
Enables flag if enabled is true; otherwise disables flag.
Qt::Alignment alignment
the alignment of the scene in the view when the whole scene is visible.
bool isTransformed() const
void setupViewport(QWidget *widget) override
This slot is called by QAbstractScrollArea after setViewport() has been called.
QTransform transform() const
Returns the current transformation matrix for the view.
void resetTransform()
Resets the view transformation to the identity matrix.
bool viewportEvent(QEvent *event) override
\reimp
bool event(QEvent *event) override
\reimp
void scrollContentsBy(int dx, int dy) override
\reimp
void ensureVisible(const QRectF &rect, int xmargin=50, int ymargin=50)
Scrolls the contents of the viewport so that the scene rectangle rect is visible, with margins specif...
OptimizationFlags optimizationFlags
flags that can be used to tune QGraphicsView's performance.
bool focusNextPrevChild(bool next) override
\reimp
virtual void drawItems(QPainter *painter, int numItems, QGraphicsItem *items[], const QStyleOptionGraphicsItem options[])
QVariant inputMethodQuery(Qt::InputMethodQuery query) const override
\reimp
void mouseDoubleClickEvent(QMouseEvent *event) override
\reimp
void paintEvent(QPaintEvent *event) override
\reimp
void inputMethodEvent(QInputMethodEvent *event) override
\reimp
QRectF sceneRect
the area of the scene visualized by this view.
void mouseReleaseEvent(QMouseEvent *event) override
\reimp
virtual void drawForeground(QPainter *painter, const QRectF &rect)
Draws the foreground of the scene using painter, after the background and all items are drawn.
void scale(qreal sx, qreal sy)
Scales the current view transformation by (sx, sy).
virtual void drawBackground(QPainter *painter, const QRectF &rect)
Draws the background of the scene using painter, before any items and the foreground are drawn.
void focusOutEvent(QFocusEvent *event) override
\reimp
void invalidateScene(const QRectF &rect=QRectF(), QGraphicsScene::SceneLayers layers=QGraphicsScene::AllLayers)
Invalidates and schedules a redraw of layers inside rect.
ViewportAnchor
This enums describe the possible anchors that QGraphicsView can use when the user resizes the view or...
void fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRadioMode=Qt::IgnoreAspectRatio)
Scales the view matrix and scrolls the scroll bars to ensure that the scene rectangle rect fits insid...
void setCacheMode(CacheMode mode)
QTransform viewportTransform() const
Returns a matrix that maps scene coordinates to viewport coordinates.
ViewportAnchor transformationAnchor
how the view should position the scene during transformations.
void resizeEvent(QResizeEvent *event) override
\reimp
DragMode dragMode
the behavior for dragging the mouse over the scene while the left mouse button is pressed.
DragMode
This enum describes the default action for the view when pressing and dragging the mouse over the vie...
void setRenderHint(QPainter::RenderHint hint, bool enabled=true)
If enabled is true, the render hint hint is enabled; otherwise it is disabled.
~QGraphicsView()
Destructs the QGraphicsView object.
QGraphicsItem * itemAt(const QPoint &pos) const
Returns the item at position pos, which is in viewport coordinates.
void keyPressEvent(QKeyEvent *event) override
\reimp
void render(QPainter *painter, const QRectF &target=QRectF(), const QRect &source=QRect(), Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio)
Renders the source rect, which is in view coordinates, from the scene into target,...
void setScene(QGraphicsScene *scene)
Sets the current scene to scene.
void keyReleaseEvent(QKeyEvent *event) override
\reimp
void showEvent(QShowEvent *event) override
\reimp
QGraphicsView(QWidget *parent=nullptr)
Constructs a QGraphicsView.
ViewportAnchor resizeAnchor
how the view should position the scene when the view is resized.
QPoint mapFromScene(const QPointF &point) const
Returns the scene coordinate point to viewport coordinates.
void setTransformationAnchor(ViewportAnchor anchor)
QGraphicsScene * scene() const
Returns a pointer to the scene that is currently visualized in the view.
void setOptimizationFlags(OptimizationFlags flags)
void rotate(qreal angle)
Rotates the current view transformation angle degrees clockwise.
void setSceneRect(const QRectF &rect)
void setViewportUpdateMode(ViewportUpdateMode mode)
QBrush foregroundBrush
the foreground brush of the scene.
CacheMode cacheMode
which parts of the view are cached
void setAlignment(Qt::Alignment alignment)
QScreen * primaryScreen
the primary (or default) screen of the application.
The QHelpEvent class provides an event that is used to request helpful information about a particular...
Definition qevent.h:788
const QPoint & globalPos() const
Returns the mouse cursor position when the event was generated in global coordinates.
Definition qevent.h:799
const QPoint & pos() const
Returns the mouse cursor position when the event was generated, relative to the widget to which the e...
Definition qevent.h:798
The QInputMethodEvent class provides parameters for input method events.
Definition qevent.h:625
The QKeyEvent class describes a key event.
Definition qevent.h:424
int key() const
Returns the code of the key that was pressed or released.
Definition qevent.h:434
qsizetype size() const noexcept
Definition qlist.h:397
qsizetype capacity() const
Definition qlist.h:422
void reserve(qsizetype size)
Definition qlist.h:753
pointer data()
Definition qlist.h:431
void resize(qsizetype size)
Definition qlist.h:403
\inmodule QtGui
Definition qevent.h:196
static QMutableTouchEvent * from(QTouchEvent *e)
Definition qevent_p.h:37
\inmodule QtCore
Definition qobject.h:103
bool inherits(const char *classname) const
Returns true if this object is an instance of a class that inherits className or a QObject subclass t...
Definition qobject.h:348
virtual int devType() const
int width() const
int height() const
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:486
\inmodule QtGui
void addPolygon(const QPolygonF &polygon)
Adds the given polygon to the path as an (unclosed) subpath.
void closeSubpath()
Closes the current subpath by drawing a line to the beginning of the subpath, automatically starting ...
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
RenderHints renderHints() const
Returns a flag that specifies the rendering hints that are set for this painter.
QPaintDevice * device() const
Returns the paint device on which this painter is currently painting, or \nullptr if the painter is n...
void setClipRect(const QRectF &, Qt::ClipOperation op=Qt::ReplaceClip)
Enables clipping, and sets the clip region to the given rectangle using the given clip operation.
void setClipPath(const QPainterPath &path, Qt::ClipOperation op=Qt::ReplaceClip)
Enables clipping, and sets the clip path for the painter to the given path, with the clip operation.
void restore()
Restores the current painter state (pops a saved state off the stack).
const QTransform & worldTransform() const
Returns the world transformation matrix.
void setOpacity(qreal opacity)
void save()
Saves the current painter state (pushes the state onto a stack).
void setWorldTransform(const QTransform &matrix, bool combine=false)
Sets the world transformation matrix.
void drawPixmap(const QRectF &targetRect, const QPixmap &pixmap, const QRectF &sourceRect)
Draws the rectangular portion source of the given pixmap into the given target in the paint device.
RenderHint
Renderhints are used to specify flags to QPainter that may or may not be respected by any given engin...
Definition qpainter.h:51
@ Antialiasing
Definition qpainter.h:52
bool end()
Ends painting.
bool isActive() const
Returns true if begin() has been called and end() has not yet been called; otherwise returns false.
void setRenderHints(RenderHints hints, bool on=true)
void fillRect(const QRectF &, const QBrush &)
Fills the given rectangle with the brush specified.
void setClipRegion(const QRegion &, Qt::ClipOperation op=Qt::ReplaceClip)
Sets the clip region to the given region using the specified clip operation.
void setTransform(const QTransform &transform, bool combine=false)
bool testRenderHint(RenderHint hint) const
Definition qpainter.h:407
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr qreal & rx() noexcept
Returns a reference to the x coordinate of this point.
Definition qpoint.h:363
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition qpoint.h:404
\inmodule QtCore\reentrant
Definition qpoint.h:25
constexpr bool isNull() const noexcept
Returns true if both the x and y coordinates are set to 0, otherwise returns false.
Definition qpoint.h:125
constexpr int & rx() noexcept
Returns a reference to the x coordinate of this point.
Definition qpoint.h:155
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:130
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:135
virtual void setAccepted(bool accepted) override
\reimp
Definition qevent.cpp:318
The QPolygonF class provides a list of points using floating point precision.
Definition qpolygon.h:96
The QPolygon class provides a list of points using integer precision.
Definition qpolygon.h:23
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr bool isEmpty() const noexcept
Returns true if the rectangle is empty, otherwise returns false.
Definition qrect.h:661
constexpr qreal height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:732
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:729
constexpr QRectF translated(qreal dx, qreal dy) const noexcept
Returns a copy of the rectangle that is translated dx along the x axis and dy along the y axis,...
Definition qrect.h:762
constexpr QRectF adjusted(qreal x1, qreal y1, qreal x2, qreal y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition qrect.h:813
constexpr QPointF center() const noexcept
Returns the center point of the rectangle.
Definition qrect.h:699
\inmodule QtCore\reentrant
Definition qrect.h:30
bool intersects(const QRect &r) const noexcept
Returns true if this rectangle intersects with the given rectangle (i.e., there is at least one pixel...
Definition qrect.cpp:1069
constexpr void adjust(int x1, int y1, int x2, int y2) noexcept
Adds dx1, dy1, dx2 and dy2 respectively to the existing coordinates of the rectangle.
Definition qrect.h:373
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr QRect adjusted(int x1, int y1, int x2, int y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition qrect.h:370
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:176
constexpr int left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:173
constexpr void setRect(int x, int y, int w, int h) noexcept
Sets the coordinates of the rectangle's top-left corner to ({x}, {y}), and its size to the given widt...
Definition qrect.h:346
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:236
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
QRect boundingRect() const noexcept
Returns the bounding rectangle of this region.
int rectCount() const noexcept
void translate(int dx, int dy)
Translates (moves) the region dx along the X axis and dy along the Y axis.
The QResizeEvent class contains event parameters for resize events.
Definition qevent.h:548
T * data() const noexcept
Returns the value of the pointer referenced by this object.
The QScrollBar widget provides a vertical or horizontal scroll bar.
Definition qscrollbar.h:20
The QShowEvent class provides an event that is sent when a widget is shown.
Definition qevent.h:578
A base class for pointer events containing a single point, such as mouse events.
Definition qevent.h:109
QPointF position() const
Returns the position of the point in this event, relative to the widget or item that received the eve...
Definition qevent.h:119
\inmodule QtCore
Definition qsize.h:208
constexpr QSizeF boundedTo(const QSizeF &) const noexcept
Returns a size holding the minimum width and height of this size and the given otherSize.
Definition qsize.h:396
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
The QStyleHintReturnMask class provides style hints that return a QRegion.
The QStyleOptionGraphicsItem class is used to describe the parameters needed to draw a QGraphicsItem.
@ SH_ScrollView_FrameOnlyAroundContents
Definition qstyle.h:602
@ SH_RubberBand_Mask
Definition qstyle.h:639
virtual int styleHint(StyleHint stylehint, const QStyleOption *opt=nullptr, const QWidget *widget=nullptr, QStyleHintReturn *returnData=nullptr) const =0
Returns an integer representing the specified style hint for the given widget described by the provid...
@ CE_RubberBand
Definition qstyle.h:209
@ PM_ScrollBarExtent
Definition qstyle.h:426
QEventPoint & point(int touchId)
The QTouchEvent class contains parameters that describe a touch event.
Definition qevent.h:917
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
QTransform & rotate(qreal a, Qt::Axis axis=Qt::ZAxis, qreal distanceToPlane=1024.0f)
static QTransform fromScale(qreal dx, qreal dy)
Creates a matrix which corresponds to a scaling of sx horizontally and sy vertically.
QTransform & scale(qreal sx, qreal sy)
Scales the coordinate system by sx horizontally and sy vertically, and returns a reference to the mat...
qreal dx() const
Returns the horizontal translation factor.
Definition qtransform.h:235
QPoint map(const QPoint &p) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QTransform & shear(qreal sh, qreal sv)
Shears the coordinate system by sh horizontally and sv vertically, and returns a reference to the mat...
static QTransform fromTranslate(qreal dx, qreal dy)
Creates a matrix which corresponds to a translation of dx along the x axis and dy along the y axis.
QTransform inverted(bool *invertible=nullptr) const
Returns an inverted copy of this matrix.
QTransform & translate(qreal dx, qreal dy)
Moves the coordinate system dx along the x axis and dy along the y axis, and returns a reference to t...
QRect mapRect(const QRect &) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isIdentity() const
Returns true if the matrix is the identity matrix, otherwise returns false.
Definition qtransform.h:169
qreal dy() const
Returns the vertical translation factor.
Definition qtransform.h:239
\inmodule QtCore
Definition qvariant.h:65
static QWidgetPrivate * get(QWidget *w)
Definition qwidget_p.h:212
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setAutoFillBackground(bool enabled)
Definition qwidget.cpp:330
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
void setMouseTracking(bool enable)
Definition qwidget.h:853
QWidget * focusWidget() const
Returns the last child of this widget that setFocus had been called on.
Definition qwidget.cpp:6828
void setAcceptDrops(bool on)
Definition qwidget.cpp:3436
void setFocusPolicy(Qt::FocusPolicy policy)
Definition qwidget.cpp:7822
void grabGesture(Qt::GestureType type, Qt::GestureFlags flags=Qt::GestureFlags())
Subscribes the widget to a given gesture with specific flags.
Qt::InputMethodHints inputMethodHints
What input method specific hints the widget has.
Definition qwidget.h:178
QStyle * style() const
Definition qwidget.cpp:2600
void setInputMethodHints(Qt::InputMethodHints hints)
Definition qwidget.cpp:9971
QOpenGLWidget * widget
[1]
QCursor cursor
auto mo
[7]
rect
[4]
uint alignment
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
Definition qcompare.h:63
InputMethodQuery
@ AlignRight
Definition qnamespace.h:146
@ AlignBottom
Definition qnamespace.h:154
@ AlignVCenter
Definition qnamespace.h:155
@ AlignTop
Definition qnamespace.h:153
@ AlignHCenter
Definition qnamespace.h:148
@ AlignHorizontal_Mask
Definition qnamespace.h:151
@ AlignVertical_Mask
Definition qnamespace.h:161
@ AlignLeft
Definition qnamespace.h:144
@ LeftButton
Definition qnamespace.h:58
@ WA_AcceptTouchEvents
Definition qnamespace.h:404
@ WA_SetCursor
Definition qnamespace.h:305
@ WA_InputMethodEnabled
Definition qnamespace.h:295
@ ReplaceClip
@ IntersectClip
AspectRatioMode
@ KeepAspectRatioByExpanding
@ KeepAspectRatio
@ IgnoreAspectRatio
@ StrongFocus
Definition qnamespace.h:110
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
@ AddToSelection
@ ReplaceSelection
@ OpenHandCursor
@ ClosedHandCursor
@ transparent
Definition qnamespace.h:47
@ Key_Tab
Definition qnamespace.h:664
@ Key_Backtab
Definition qnamespace.h:665
@ ScrollBarAlwaysOn
@ ScrollBarAsNeeded
@ DescendingOrder
Definition qnamespace.h:123
@ AscendingOrder
Definition qnamespace.h:122
@ ControlModifier
ItemSelectionMode
@ IntersectsItemShape
@ IntersectsItemBoundingRect
@ NoBrush
GestureType
constexpr Initialization Uninitialized
Definition brush.cpp:5
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
const EGLAttrib EGLOutputLayerEXT * layers
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
bool qt_sendSpontaneousEvent(QObject *, QEvent *)
static QRectF adjustedItemEffectiveBoundingRect(const QGraphicsItem *item)
static bool intersectsViewport(const QRect &r, int width, int height)
static bool containsViewport(const QRect &r, int width, int height)
static void QRect_unite(QRect *rect, const QRect &other)
static const int QGRAPHICSVIEW_REGION_RECT_THRESHOLD
QPainterPath qt_regionToPath(const QRegion &region)
Definition qregion.cpp:1007
QT_BEGIN_NAMESPACE bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event)
int q_round_bound(qreal d)
static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS
#define qWarning
Definition qlogging.h:166
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLint GLint GLint GLint GLint x
[0]
GLenum mode
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLdouble GLdouble GLdouble GLdouble top
GLdouble GLdouble right
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLint GLsizei width
GLint left
GLint GLint bottom
GLfloat angle
GLenum target
GLbitfield flags
GLenum GLuint GLintptr offset
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint y
GLsizei GLsizei GLchar * source
struct _cl_event * event
GLuint GLenum GLenum transform
GLenum query
GLenum array
GLuint GLenum matrix
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLsizei const GLchar *const * path
GLfloat GLfloat p
[1]
GLuint GLenum option
GLenum GLenum GLenum GLenum GLenum scale
static const QRectF boundingRect(const QPointF *points, int pointCount)
QPainterPath qt_regionToPath(const QRegion &region)
Definition qregion.cpp:1007
static QT_BEGIN_NAMESPACE qreal dpr(const QWindow *w)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define QT_CONFIG(feature)
#define tr(X)
#define emit
#define Q_UNUSED(x)
unsigned int quint32
Definition qtypes.h:50
long long qint64
Definition qtypes.h:60
double qreal
Definition qtypes.h:187
if(qFloatDistance(a, b)<(1<< 7))
[0]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
obj metaObject() -> className()
QObject::connect nullptr
myObject disconnect()
[26]
QSharedPointer< T > other(t)
[5]
QGraphicsScene scene
[0]
QGraphicsItem * item
view viewport() -> scroll(dx, dy, deviceRect)
edit isVisible()
QList< QTreeWidgetItem * > items
app setAttribute(Qt::AA_DontShowIconsInMenus)
QPainter painter(this)
[7]
aWidget window() -> setWindowTitle("New Window Title")
[2]
scrollArea setBackgroundRole(QPalette::Dark)
QNetworkProxy proxy
[0]
\inmodule QtCore