diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2024-04-11 15:49:07 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2024-04-16 00:09:50 +0200 |
commit | a407541a032de6f372206a0bc190775a0db950af (patch) | |
tree | 7a427b78c6c3ae5bcbb52469320c43b60a2dbc25 /tests | |
parent | f5e5e4d3e84289ed1f2af1c8397649b25aa088d4 (diff) |
DelegateChooser: React to changes of choice property (via QAIM)
Detect when a QAIM changes the value of the role affecting the choice
made by DelegateChooser and tell the view to recreate the delegate if
necessary.
For performance reasons, we don't want to track changes for non-QAIM
based models [1]; document this remaining limitation.
[1]: We don't have a convenient place where we could detect both the
"role" change and the affected index (which means that we would need to
invalidate everything, and possibly way too often.). It might be
possible to refactor the code to allow for this, too, but that would
robably be a larger change, and not suitable for picking it back.
Pick-to: 6.7
Fixes: QTBUG-75887
Change-Id: Ic91dc436e53b4280debf2698c76f2ead4bdf15d6
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/qml/qqmldelegatemodel/data/viewUpdatedOnDelegateChoiceAffectingRoleChange.qml | 93 | ||||
-rw-r--r-- | tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp | 22 |
2 files changed, 115 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmldelegatemodel/data/viewUpdatedOnDelegateChoiceAffectingRoleChange.qml b/tests/auto/qml/qqmldelegatemodel/data/viewUpdatedOnDelegateChoiceAffectingRoleChange.qml new file mode 100644 index 0000000000..b2367b3a6e --- /dev/null +++ b/tests/auto/qml/qqmldelegatemodel/data/viewUpdatedOnDelegateChoiceAffectingRoleChange.qml @@ -0,0 +1,93 @@ +import QtQuick +import Qt.labs.qmlmodels +import QtQml.Models + +Item { + id: root + property bool triggered: false + onTriggeredChanged: { + rootLM.setProperty(1, "currentRole", "first"); + } + width: 800 + height: 680 + + function verify(): bool { + rootLV.currentIndex = 1; // needed for itemAtIndex to work + if (root.triggered) + return rootLV.itemAtIndex(0).isFirst && rootLV.itemAtIndex(1).isFirst; + else + return rootLV.itemAtIndex(0).isFirst && !rootLV.itemAtIndex(1).isFirst; + } + + ListModel { + id: rootLM + ListElement { + currentRole: "first" + firstText: "TEXT_FIRST_1" + secondText: "TEXT_SECOND_1" + } + ListElement { + currentRole: "second" + firstText: "TEXT_FIRST_2" + secondText: "TEXT_SECOND_2" + } + } + + DelegateModel { + id: delModel + model: rootLM + delegate: DelegateChooser { + id: delegateChooser + role: "currentRole" + DelegateChoice { + roleValue: "first" + Rectangle { + property bool isFirst: true + height: 30 + width: rootLV.width + color: "yellow" + Text { + anchors.centerIn: parent + text: firstText + " " + currentRole + } + } + } + DelegateChoice { + roleValue: "second" + Rectangle { + property bool isFirst: false + height: 30 + width: rootLV.width + color: "red" + Text { + anchors.centerIn: parent + text: secondText + " " + currentRole + } + } + } + } + } + + TapHandler { + // for manual testing + onTapped: root.triggered = true + } + + Rectangle { + width: 200 + height: 300 + anchors.centerIn: parent + border.color: "black" + border.width: 1 + color: "blue" + + ListView { + id: rootLV + objectName: "listview" + anchors.margins: 30 + anchors.fill: parent + cacheBuffer: 0 + model: delModel + } + } +} diff --git a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp index 7f71724c04..2cacda5513 100644 --- a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp +++ b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp @@ -41,6 +41,7 @@ private slots: void unknownContainersAsModel(); void doNotUnrefObjectUnderConstruction(); void clearCacheDuringInsertion(); + void viewUpdatedOnDelegateChoiceAffectingRoleChange(); }; class AbstractItemModel : public QAbstractItemModel @@ -594,6 +595,27 @@ void tst_QQmlDelegateModel::clearCacheDuringInsertion() QTRY_COMPARE(object->property("testModel").toInt(), 0); } +void tst_QQmlDelegateModel::viewUpdatedOnDelegateChoiceAffectingRoleChange() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("viewUpdatedOnDelegateChoiceAffectingRoleChange.qml")); + QVERIFY2(component.isReady(), qPrintable(component.errorString())); + std::unique_ptr<QObject> object(component.create()); + QVERIFY(object); + QQuickItem *listview = object->findChild<QQuickItem *>("listview"); + QVERIFY(listview); + QTRY_VERIFY(listview->property("count").toInt() > 0); + bool returnedValue = false; + QMetaObject::invokeMethod(object.get(), "verify", Q_RETURN_ARG(bool, returnedValue)); + QVERIFY(returnedValue); + returnedValue = false; + + object->setProperty("triggered", "true"); + QTRY_VERIFY(listview->property("count").toInt() > 0); + QMetaObject::invokeMethod(object.get(), "verify", Q_RETURN_ARG(bool, returnedValue)); + QVERIFY(returnedValue); +} + QTEST_MAIN(tst_QQmlDelegateModel) #include "tst_qqmldelegatemodel.moc" |