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 Pick-to: 6.5 6.2 Change-Id: I9be26fa7954be5f85729d24f166d66980af71801 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
df0b661bfc
commit
585bfe600a
@ -124,6 +124,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
|
||||
@ -199,8 +203,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
|
||||
@ -290,10 +295,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
|
||||
|
||||
|
@ -59,6 +59,13 @@ SortingBox::SortingBox(QWidget *parent)
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [27]
|
||||
SortingBox::~SortingBox()
|
||||
{
|
||||
qDeleteAll(shapeItems);
|
||||
}
|
||||
//! [27]
|
||||
|
||||
//! [5]
|
||||
bool SortingBox::event(QEvent *event)
|
||||
{
|
||||
@ -67,7 +74,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();
|
||||
@ -97,13 +104,13 @@ void SortingBox::paintEvent(QPaintEvent * /* event */)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
for (const ShapeItem &shapeItem : std::as_const(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]
|
||||
@ -114,7 +121,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();
|
||||
@ -169,11 +176,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;
|
||||
@ -208,11 +215,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();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ class SortingBox : public QWidget
|
||||
|
||||
public:
|
||||
SortingBox(QWidget *parent = nullptr);
|
||||
~SortingBox();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
@ -41,7 +42,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();
|
||||
@ -53,7 +54,7 @@ private:
|
||||
const PointerToMemberFunction &member);
|
||||
|
||||
//! [2]
|
||||
QList<ShapeItem> shapeItems;
|
||||
QList<ShapeItem *> shapeItems;
|
||||
QPainterPath circlePath;
|
||||
QPainterPath squarePath;
|
||||
QPainterPath trianglePath;
|
||||
|
Loading…
Reference in New Issue
Block a user