Fix hashing of QPersistentModelIndex
The hash and equality operators used need to be consistent with each other. Unfortunately, QPMI::operator==() is not suitable to do this. So specialize qHashEquals() for QPMI. Fixes: QTBUG-88966 Change-Id: If5f19a722ae9fc4e78e93537e7ea15726f148768 Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit 83e95956ed58e88b11e2cc3cb61c5beacb7985db) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
793dbd8ee6
commit
6012285e7d
@ -242,6 +242,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
QPersistentModelIndexData *d;
|
QPersistentModelIndexData *d;
|
||||||
friend size_t qHash(const QPersistentModelIndex &, size_t seed) noexcept;
|
friend size_t qHash(const QPersistentModelIndex &, size_t seed) noexcept;
|
||||||
|
friend bool qHashEquals(const QPersistentModelIndex &a, const QPersistentModelIndex &b) noexcept
|
||||||
|
{ return a.d == b.d; }
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QPersistentModelIndex &);
|
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QPersistentModelIndex &);
|
||||||
#endif
|
#endif
|
||||||
|
@ -252,6 +252,7 @@ private slots:
|
|||||||
void taskQTBUG_61476();
|
void taskQTBUG_61476();
|
||||||
void testInitialFocus();
|
void testInitialFocus();
|
||||||
void fetchUntilScreenFull();
|
void fetchUntilScreenFull();
|
||||||
|
void expandAfterTake();
|
||||||
};
|
};
|
||||||
|
|
||||||
class QtTestModel: public QAbstractItemModel
|
class QtTestModel: public QAbstractItemModel
|
||||||
@ -5218,6 +5219,39 @@ void tst_QTreeView::fetchUntilScreenFull()
|
|||||||
QVERIFY(expectedItemNumberFetched);
|
QVERIFY(expectedItemNumberFetched);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void populateModel(QStandardItemModel *model)
|
||||||
|
{
|
||||||
|
const int depth = 10;
|
||||||
|
for (int i1 = 0; i1 < depth; ++i1) {
|
||||||
|
QStandardItem *s1 = new QStandardItem;
|
||||||
|
s1->setText(QString::number(i1));
|
||||||
|
model->appendRow(s1);
|
||||||
|
for (int i2 = 0; i2 < depth; ++i2) {
|
||||||
|
QStandardItem *s2 = new QStandardItem;
|
||||||
|
s2->setText(QStringLiteral("%1 - %2").arg(i1).arg(i2));
|
||||||
|
s1->appendRow(s2);
|
||||||
|
for (int i3 = 0; i3 < depth; ++i3) {
|
||||||
|
QStandardItem *s3 = new QStandardItem;
|
||||||
|
s3->setText(QStringLiteral("%1 - %2 - %3").arg(i1).arg(i2).arg(i3));
|
||||||
|
s2->appendRow(s3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QTreeView::expandAfterTake()
|
||||||
|
{
|
||||||
|
QStandardItemModel model;
|
||||||
|
populateModel(&model);
|
||||||
|
QTreeView view;
|
||||||
|
view.setUniformRowHeights(true);
|
||||||
|
view.setModel(&model);
|
||||||
|
view.show();
|
||||||
|
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
||||||
|
view.expandAll();
|
||||||
|
model.takeItem(0);
|
||||||
|
populateModel(&model); // populate model again, having corrupted items inside QTreeViewPrivate::expandedIndexes
|
||||||
|
view.expandAll(); // adding new items to QTreeViewPrivate::expandedIndexes with corrupted persistent indices, causing crash sometimes
|
||||||
|
}
|
||||||
QTEST_MAIN(tst_QTreeView)
|
QTEST_MAIN(tst_QTreeView)
|
||||||
#include "tst_qtreeview.moc"
|
#include "tst_qtreeview.moc"
|
||||||
|
Loading…
Reference in New Issue
Block a user