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)
This commit is contained in:
parent
b8501e397e
commit
454de94787
@ -148,6 +148,10 @@
|
|||||||
private \c createShapeItem(), \c initialItemPosition() and \c
|
private \c createShapeItem(), \c initialItemPosition() and \c
|
||||||
initialItemColor() functions.
|
initialItemColor() functions.
|
||||||
|
|
||||||
|
\snippet widgets/tooltips/sortingbox.cpp 27
|
||||||
|
|
||||||
|
In the destructor, we delete all shape items.
|
||||||
|
|
||||||
\snippet widgets/tooltips/sortingbox.cpp 5
|
\snippet widgets/tooltips/sortingbox.cpp 5
|
||||||
|
|
||||||
QWidget::event() is the main event handler and receives all the
|
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
|
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
|
and the event's position. If several of the shape items cover the
|
||||||
position, we store the pointer to the uppermost item. Finally, we
|
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
|
move the shape item's pointer to the end of the list, and make
|
||||||
QWidget::update() function to make the item appear on top.
|
a call to the QWidget::update() function to make the item appear
|
||||||
|
on top.
|
||||||
|
|
||||||
The QWidget::update() function does not cause an immediate
|
The QWidget::update() function does not cause an immediate
|
||||||
repaint; instead it schedules a paint event for processing when Qt
|
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
|
The \c createShapeItem() function creates a single shape item. It
|
||||||
sets the path, tooltip, position and color, using the item's own
|
sets the path, tooltip, position and color, using the item's own
|
||||||
functions. In the end, the function appends the new item to the
|
functions. In the end, the function appends the new item's pointer
|
||||||
list of shape items, and calls the QWidget::update() function to
|
to the list of shape items, and calls QWidget::update() to make
|
||||||
make it appear with the other items within the \c SortingBox
|
it appear with the other items within the \c SortingBox widget.
|
||||||
widget.
|
|
||||||
|
|
||||||
\snippet widgets/tooltips/sortingbox.cpp 22
|
\snippet widgets/tooltips/sortingbox.cpp 22
|
||||||
|
|
||||||
|
@ -106,6 +106,13 @@ SortingBox::SortingBox(QWidget *parent)
|
|||||||
}
|
}
|
||||||
//! [4]
|
//! [4]
|
||||||
|
|
||||||
|
//! [27]
|
||||||
|
SortingBox::~SortingBox()
|
||||||
|
{
|
||||||
|
qDeleteAll(shapeItems);
|
||||||
|
}
|
||||||
|
//! [27]
|
||||||
|
|
||||||
//! [5]
|
//! [5]
|
||||||
bool SortingBox::event(QEvent *event)
|
bool SortingBox::event(QEvent *event)
|
||||||
{
|
{
|
||||||
@ -114,7 +121,7 @@ bool SortingBox::event(QEvent *event)
|
|||||||
QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
|
QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
|
||||||
int index = itemAt(helpEvent->pos());
|
int index = itemAt(helpEvent->pos());
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
QToolTip::showText(helpEvent->globalPos(), shapeItems[index].toolTip());
|
QToolTip::showText(helpEvent->globalPos(), shapeItems[index]->toolTip());
|
||||||
} else {
|
} else {
|
||||||
QToolTip::hideText();
|
QToolTip::hideText();
|
||||||
event->ignore();
|
event->ignore();
|
||||||
@ -144,13 +151,13 @@ void SortingBox::paintEvent(QPaintEvent * /* event */)
|
|||||||
{
|
{
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
for (const ShapeItem &shapeItem : qAsConst(shapeItems)) {
|
for (const ShapeItem *shapeItem : std::as_const(shapeItems)) {
|
||||||
//! [8] //! [9]
|
//! [8] //! [9]
|
||||||
painter.translate(shapeItem.position());
|
painter.translate(shapeItem->position());
|
||||||
//! [9] //! [10]
|
//! [9] //! [10]
|
||||||
painter.setBrush(shapeItem.color());
|
painter.setBrush(shapeItem->color());
|
||||||
painter.drawPath(shapeItem.path());
|
painter.drawPath(shapeItem->path());
|
||||||
painter.translate(-shapeItem.position());
|
painter.translate(-shapeItem->position());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//! [10]
|
//! [10]
|
||||||
@ -161,7 +168,7 @@ void SortingBox::mousePressEvent(QMouseEvent *event)
|
|||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton) {
|
||||||
int index = itemAt(event->position().toPoint());
|
int index = itemAt(event->position().toPoint());
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
itemInMotion = &shapeItems[index];
|
itemInMotion = shapeItems[index];
|
||||||
previousPosition = event->position().toPoint();
|
previousPosition = event->position().toPoint();
|
||||||
shapeItems.move(index, shapeItems.size() - 1);
|
shapeItems.move(index, shapeItems.size() - 1);
|
||||||
update();
|
update();
|
||||||
@ -216,11 +223,11 @@ void SortingBox::createNewTriangle()
|
|||||||
//! [16]
|
//! [16]
|
||||||
|
|
||||||
//! [17]
|
//! [17]
|
||||||
int SortingBox::itemAt(const QPoint &pos)
|
qsizetype SortingBox::itemAt(const QPoint &pos)
|
||||||
{
|
{
|
||||||
for (int i = shapeItems.size() - 1; i >= 0; --i) {
|
for (qsizetype i = shapeItems.size() - 1; i >= 0; --i) {
|
||||||
const ShapeItem &item = shapeItems[i];
|
const ShapeItem *item = shapeItems[i];
|
||||||
if (item.path().contains(pos - item.position()))
|
if (item->path().contains(pos - item->position()))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -255,11 +262,11 @@ void SortingBox::createShapeItem(const QPainterPath &path,
|
|||||||
const QString &toolTip, const QPoint &pos,
|
const QString &toolTip, const QPoint &pos,
|
||||||
const QColor &color)
|
const QColor &color)
|
||||||
{
|
{
|
||||||
ShapeItem shapeItem;
|
ShapeItem *shapeItem = new ShapeItem;
|
||||||
shapeItem.setPath(path);
|
shapeItem->setPath(path);
|
||||||
shapeItem.setToolTip(toolTip);
|
shapeItem->setToolTip(toolTip);
|
||||||
shapeItem.setPosition(pos);
|
shapeItem->setPosition(pos);
|
||||||
shapeItem.setColor(color);
|
shapeItem->setColor(color);
|
||||||
shapeItems.append(shapeItem);
|
shapeItems.append(shapeItem);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ class SortingBox : public QWidget
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
SortingBox(QWidget *parent = nullptr);
|
SortingBox(QWidget *parent = nullptr);
|
||||||
|
~SortingBox();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool event(QEvent *event) override;
|
bool event(QEvent *event) override;
|
||||||
@ -88,7 +89,7 @@ private:
|
|||||||
int updateButtonGeometry(QToolButton *button, int x, int y);
|
int updateButtonGeometry(QToolButton *button, int x, int y);
|
||||||
void createShapeItem(const QPainterPath &path, const QString &toolTip,
|
void createShapeItem(const QPainterPath &path, const QString &toolTip,
|
||||||
const QPoint &pos, const QColor &color);
|
const QPoint &pos, const QColor &color);
|
||||||
int itemAt(const QPoint &pos);
|
qsizetype itemAt(const QPoint &pos);
|
||||||
void moveItemTo(const QPoint &pos);
|
void moveItemTo(const QPoint &pos);
|
||||||
QPoint initialItemPosition(const QPainterPath &path);
|
QPoint initialItemPosition(const QPainterPath &path);
|
||||||
QPoint randomItemPosition();
|
QPoint randomItemPosition();
|
||||||
@ -99,7 +100,7 @@ private:
|
|||||||
const char *member);
|
const char *member);
|
||||||
|
|
||||||
//! [2]
|
//! [2]
|
||||||
QList<ShapeItem> shapeItems;
|
QList<ShapeItem *> shapeItems;
|
||||||
QPainterPath circlePath;
|
QPainterPath circlePath;
|
||||||
QPainterPath squarePath;
|
QPainterPath squarePath;
|
||||||
QPainterPath trianglePath;
|
QPainterPath trianglePath;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user