From 6a873778b976b4752e874a2d87ea84e5d9e0d3c5 Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Fri, 25 Aug 2023 15:35:08 +0200 Subject: [PATCH] QAbstractProxyModel: fix binding loops ... by using valueBypassingBindings() when accessing the properties from the setters. This commit is mostly trivial. Had to change the template parameters in the unit-test, because the updated QTestPrivate::testReadWritePropertyBasics() creates an instance of the TestedClass, and QAbstractProxyModel cannot be instantiated, since it has pure virtual methods. Task-number: QTBUG-116346 Pick-to: 6.6 6.5 Change-Id: I0cae29263ea9bb92c9de06891b0ba8633fb9fd72 Reviewed-by: Ulf Hermann --- src/corelib/itemmodels/qabstractproxymodel.cpp | 11 ++++++----- .../qabstractproxymodel/tst_qabstractproxymodel.cpp | 6 +++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp index 12974b5aaa..83e8cb8db3 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.cpp +++ b/src/corelib/itemmodels/qabstractproxymodel.cpp @@ -166,7 +166,8 @@ void QAbstractProxyModel::setSourceModel(QAbstractItemModel *sourceModel) d->model.removeBindingUnlessInWrapper(); // Special case to handle nullptr models. Otherwise we will have unwanted // notifications. - if (!sourceModel && d->model == QAbstractItemModelPrivate::staticEmptyModel()) + const QAbstractItemModel *currentModel = d->model.valueBypassingBindings(); + if (!sourceModel && currentModel == QAbstractItemModelPrivate::staticEmptyModel()) return; static const struct { const char *signalName; @@ -183,16 +184,16 @@ void QAbstractProxyModel::setSourceModel(QAbstractItemModel *sourceModel) // clang-format on }; - if (sourceModel != d->model) { - if (d->model) { + if (sourceModel != currentModel) { + if (currentModel) { for (const auto &c : connectionTable) - disconnect(d->model, c.signalName, this, c.slotName); + disconnect(currentModel, c.signalName, this, c.slotName); } if (sourceModel) { d->model.setValueBypassingBindings(sourceModel); for (const auto &c : connectionTable) - connect(d->model, c.signalName, this, c.slotName); + connect(sourceModel, c.signalName, this, c.slotName); } else { d->model.setValueBypassingBindings(QAbstractItemModelPrivate::staticEmptyModel()); } diff --git a/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp b/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp index d04d148fc3..4a9606d345 100644 --- a/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qabstractproxymodel/tst_qabstractproxymodel.cpp @@ -610,7 +610,7 @@ void tst_QAbstractProxyModel::sourceModelBinding() SubQAbstractProxyModel proxy; QStandardItemModel model1; QStandardItemModel model2; - QTestPrivate::testReadWritePropertyBasics( + QTestPrivate::testReadWritePropertyBasics( proxy, &model1, &model2, "sourceModel"); if (QTest::currentTestFailed()) { qDebug("Failed model - model test"); @@ -618,7 +618,7 @@ void tst_QAbstractProxyModel::sourceModelBinding() } proxy.setSourceModel(&model2); - QTestPrivate::testReadWritePropertyBasics( + QTestPrivate::testReadWritePropertyBasics( proxy, &model1, nullptr, "sourceModel"); if (QTest::currentTestFailed()) { qDebug("Failed model - nullptr test"); @@ -626,7 +626,7 @@ void tst_QAbstractProxyModel::sourceModelBinding() } proxy.setSourceModel(&model1); - QTestPrivate::testReadWritePropertyBasics( + QTestPrivate::testReadWritePropertyBasics( proxy, nullptr, &model2, "sourceModel"); if (QTest::currentTestFailed()) { qDebug("Failed nullptr - model test");