QTreeView: make sure to not ask the old model during setModel

Within QTreeView::setModel() the header might emit columnCountChanged
which then tries to update the geometries based on the old model which
is wrong.
Fix it by setting geometryRecursionBlock to true so
QTreeView::updateGeometries() will not ask the old model for it's data.

Fixes: QTBUG-75982
Change-Id: Ia0dd36cd7c6c5347fbc285deac43da6941accbe7
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Christian Ehrlicher 2019-06-12 20:49:06 +02:00
parent 80ac9e8b7c
commit c15a069830
2 changed files with 16 additions and 0 deletions

View File

@ -233,7 +233,9 @@ void QTreeView::setModel(QAbstractItemModel *model)
d->viewItems.clear();
d->expandedIndexes.clear();
d->hiddenIndexes.clear();
d->geometryRecursionBlock = true; // do not update geometries due to signals from the headers
d->header->setModel(model);
d->geometryRecursionBlock = false;
QAbstractItemView::setModel(model);
// QAbstractItemView connects to a private slot

View File

@ -2862,6 +2862,7 @@ public:
};
Node *root;
bool crash = false;
EvilModel(QObject *parent = nullptr): QAbstractItemModel(parent), root(new Node)
{}
@ -2870,6 +2871,11 @@ public:
delete root;
}
void setCrash()
{
crash = true;
}
void change()
{
emit layoutAboutToBeChanged();
@ -2938,6 +2944,10 @@ public:
QVariant data(const QModelIndex &idx, int role) const override
{
if (crash) {
QTest::qFail("Should not get here...", __FILE__, __LINE__);
return QVariant();
}
if (idx.isValid() && role == Qt::DisplayRole) {
Node *parentNode = root;
if (idx.isValid()) {
@ -2957,6 +2967,7 @@ void tst_QTreeView::evilModel_data()
{
QTest::addColumn<bool>("visible");
QTest::newRow("visible") << false;
QTest::newRow("visible") << true;
}
void tst_QTreeView::evilModel()
@ -3126,6 +3137,9 @@ void tst_QTreeView::evilModel()
model.change();
view.setRootIndex(secondLevel);
model.setCrash();
view.setModel(nullptr);
}
void tst_QTreeView::indexRowSizeHint()