diff options
author | Axel Spoerl <axel.spoerl@qt.io> | 2023-03-22 10:11:11 +0100 |
---|---|---|
committer | Axel Spoerl <axel.spoerl@qt.io> | 2023-03-28 13:10:18 +0000 |
commit | 454de94787a4f0b54f2a629042b9aa73ed013026 (patch) | |
tree | 4a42f906e7d0c51f5980f0f489f8f1784a824809 | |
parent | b8501e397ea1af7d3d70fbe440070bcec403ad8f (diff) |
Fix pointer mismatch after QList::move() in tooltip example
The tooltip example moves shape items within a QWidget. Shape items are
stored in a QList of objects. When an item is moved, its pointer is
taken from the QList and stored in a member variable. To have the moved
item on the bottom of the list, QList::move() is called. This
operation re-arranges the list objects, and the member variable starts
pointing at a wrong object.
This patch changes the list from a list of objects, to a list of
pointers. Shape items are therefore allocated on the heap.
A destructor is added to free the heap with qDeleteAll.
The example's documentation is adapted accordingly and a snippet for
the destructor is added.
As a drive-by, int is replaced by qsizetype where it was used as an
index of a QList.
Fixes: QTBUG-104781
Change-Id: I9be26fa7954be5f85729d24f166d66980af71801
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 585bfe600a158743d68e4c8c81fb1a7106566d6a)
-rw-r--r-- | examples/widgets/doc/src/tooltips.qdoc | 16 | ||||
-rw-r--r-- | examples/widgets/widgets/tooltips/sortingbox.cpp | 39 | ||||
-rw-r--r-- | examples/widgets/widgets/tooltips/sortingbox.h | 5 |
3 files changed, 36 insertions, 24 deletions
diff --git a/examples/widgets/doc/src/tooltips.qdoc b/examples/widgets/doc/src/tooltips.qdoc index a278215503..da3f1bd489 100644 --- a/examples/widgets/doc/src/tooltips.qdoc +++ b/examples/widgets/doc/src/tooltips.qdoc @@ -148,6 +148,10 @@ private \c createShapeItem(), \c initialItemPosition() and \c initialItemColor() functions. + \snippet widgets/tooltips/sortingbox.cpp 27 + + In the destructor, we delete all shape items. + \snippet widgets/tooltips/sortingbox.cpp 5 QWidget::event() is the main event handler and receives all the @@ -223,8 +227,9 @@ If an item covers the position, we store a pointer to that item and the event's position. If several of the shape items cover the position, we store the pointer to the uppermost item. Finally, we - move the shape item to the end of the list, and make a call to the - QWidget::update() function to make the item appear on top. + move the shape item's pointer to the end of the list, and make + a call to the QWidget::update() function to make the item appear + on top. The QWidget::update() function does not cause an immediate repaint; instead it schedules a paint event for processing when Qt @@ -314,10 +319,9 @@ The \c createShapeItem() function creates a single shape item. It sets the path, tooltip, position and color, using the item's own - functions. In the end, the function appends the new item to the - list of shape items, and calls the QWidget::update() function to - make it appear with the other items within the \c SortingBox - widget. + functions. In the end, the function appends the new item's pointer + to the list of shape items, and calls QWidget::update() to make + it appear with the other items within the \c SortingBox widget. \snippet widgets/tooltips/sortingbox.cpp 22 diff --git a/examples/widgets/widgets/tooltips/sortingbox.cpp b/examples/widgets/widgets/tooltips/sortingbox.cpp index d993b098b2..733e567873 100644 --- a/examples/widgets/widgets/tooltips/sortingbox.cpp +++ b/examples/widgets/widgets/tooltips/sortingbox.cpp @@ -106,6 +106,13 @@ SortingBox::SortingBox(QWidget *parent) } //! [4] +//! [27] +SortingBox::~SortingBox() +{ + qDeleteAll(shapeItems); +} +//! [27] + //! [5] bool SortingBox::event(QEvent *event) { @@ -114,7 +121,7 @@ bool SortingBox::event(QEvent *event) QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event); int index = itemAt(helpEvent->pos()); if (index != -1) { - QToolTip::showText(helpEvent->globalPos(), shapeItems[index].toolTip()); + QToolTip::showText(helpEvent->globalPos(), shapeItems[index]->toolTip()); } else { QToolTip::hideText(); event->ignore(); @@ -144,13 +151,13 @@ void SortingBox::paintEvent(QPaintEvent * /* event */) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); - for (const ShapeItem &shapeItem : qAsConst(shapeItems)) { + for (const ShapeItem *shapeItem : std::as_const(shapeItems)) { //! [8] //! [9] - painter.translate(shapeItem.position()); + painter.translate(shapeItem->position()); //! [9] //! [10] - painter.setBrush(shapeItem.color()); - painter.drawPath(shapeItem.path()); - painter.translate(-shapeItem.position()); + painter.setBrush(shapeItem->color()); + painter.drawPath(shapeItem->path()); + painter.translate(-shapeItem->position()); } } //! [10] @@ -161,7 +168,7 @@ void SortingBox::mousePressEvent(QMouseEvent *event) if (event->button() == Qt::LeftButton) { int index = itemAt(event->position().toPoint()); if (index != -1) { - itemInMotion = &shapeItems[index]; + itemInMotion = shapeItems[index]; previousPosition = event->position().toPoint(); shapeItems.move(index, shapeItems.size() - 1); update(); @@ -216,11 +223,11 @@ void SortingBox::createNewTriangle() //! [16] //! [17] -int SortingBox::itemAt(const QPoint &pos) +qsizetype SortingBox::itemAt(const QPoint &pos) { - for (int i = shapeItems.size() - 1; i >= 0; --i) { - const ShapeItem &item = shapeItems[i]; - if (item.path().contains(pos - item.position())) + for (qsizetype i = shapeItems.size() - 1; i >= 0; --i) { + const ShapeItem *item = shapeItems[i]; + if (item->path().contains(pos - item->position())) return i; } return -1; @@ -255,11 +262,11 @@ void SortingBox::createShapeItem(const QPainterPath &path, const QString &toolTip, const QPoint &pos, const QColor &color) { - ShapeItem shapeItem; - shapeItem.setPath(path); - shapeItem.setToolTip(toolTip); - shapeItem.setPosition(pos); - shapeItem.setColor(color); + ShapeItem *shapeItem = new ShapeItem; + shapeItem->setPath(path); + shapeItem->setToolTip(toolTip); + shapeItem->setPosition(pos); + shapeItem->setColor(color); shapeItems.append(shapeItem); update(); } diff --git a/examples/widgets/widgets/tooltips/sortingbox.h b/examples/widgets/widgets/tooltips/sortingbox.h index 3d0cecea2b..90534ab13d 100644 --- a/examples/widgets/widgets/tooltips/sortingbox.h +++ b/examples/widgets/widgets/tooltips/sortingbox.h @@ -68,6 +68,7 @@ class SortingBox : public QWidget public: SortingBox(QWidget *parent = nullptr); + ~SortingBox(); protected: bool event(QEvent *event) override; @@ -88,7 +89,7 @@ private: int updateButtonGeometry(QToolButton *button, int x, int y); void createShapeItem(const QPainterPath &path, const QString &toolTip, const QPoint &pos, const QColor &color); - int itemAt(const QPoint &pos); + qsizetype itemAt(const QPoint &pos); void moveItemTo(const QPoint &pos); QPoint initialItemPosition(const QPainterPath &path); QPoint randomItemPosition(); @@ -99,7 +100,7 @@ private: const char *member); //! [2] - QList<ShapeItem> shapeItems; + QList<ShapeItem *> shapeItems; QPainterPath circlePath; QPainterPath squarePath; QPainterPath trianglePath; |