diff options
-rw-r--r-- | src/qml/types/qqmldelegatemodel.cpp | 18 | ||||
-rw-r--r-- | src/qml/types/qqmldelegatemodel_p_p.h | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquickrepeater/data/package.qml | 35 | ||||
-rw-r--r-- | tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp | 24 |
4 files changed, 78 insertions, 1 deletions
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 3863f9e968..1c0da2875c 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -3256,7 +3256,10 @@ void QQmlPartsModel::createdPackage(int index, QQuickPackage *package) void QQmlPartsModel::initPackage(int index, QQuickPackage *package) { - emit initItem(index, package->part(m_part)); + if (m_modelUpdatePending) + m_pendingPackageInitializations << index; + else + emit initItem(index, package->part(m_part)); } void QQmlPartsModel::destroyingPackage(QQuickPackage *package) @@ -3268,9 +3271,22 @@ void QQmlPartsModel::destroyingPackage(QQuickPackage *package) void QQmlPartsModel::emitModelUpdated(const QQmlChangeSet &changeSet, bool reset) { + m_modelUpdatePending = false; emit modelUpdated(changeSet, reset); if (changeSet.difference() != 0) emit countChanged(); + + QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(m_model); + QVector<int> pendingPackageInitializations; + qSwap(pendingPackageInitializations, m_pendingPackageInitializations); + for (int index : pendingPackageInitializations) { + if (!model->m_delegate || index < 0 || index >= model->m_compositor.count(m_compositorGroup)) + continue; + QObject *object = model->object(m_compositorGroup, index, QQmlIncubator::Asynchronous); + if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object)) + emit initItem(index, package->part(m_part)); + model->release(object); + } } //============================================================================ diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index 30401a2105..fc46986e23 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -378,8 +378,10 @@ private: QString m_part; QString m_filterGroup; QList<QByteArray> m_watchedRoles; + QVector<int> m_pendingPackageInitializations; // vector holds model indices Compositor::Group m_compositorGroup; bool m_inheritGroup; + bool m_modelUpdatePending = true; }; class QMetaPropertyBuilder; diff --git a/tests/auto/quick/qquickrepeater/data/package.qml b/tests/auto/quick/qquickrepeater/data/package.qml new file mode 100644 index 0000000000..1f9eb0d970 --- /dev/null +++ b/tests/auto/quick/qquickrepeater/data/package.qml @@ -0,0 +1,35 @@ +import QtQuick 2.0 +import QtQml.Models 2.2 +import QtQuick.Window 2.0 + +Window { + width: 300 + height: 300 + visible: true + DelegateModel { + id: mdl + + model: 1 + delegate: Package { + Item { + id: first + Package.name: "first" + objectName: "firstItem" + } + Item{ + id: second + Package.name: "second" + objectName: "secondItem" + } + } + } + + Repeater { + id: repeater1 + model: mdl.parts.first + } + Repeater { + id: repeater2 + model: mdl.parts.second + } +} diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp index 0499e2f9a6..791c3ae19a 100644 --- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp +++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp @@ -76,6 +76,7 @@ private slots: void stackingOrder(); void objectModel(); void QTBUG54859_asynchronousMove(); + void package(); }; class TestObject : public QObject @@ -1014,6 +1015,29 @@ void tst_QQuickRepeater::QTBUG54859_asynchronousMove() QTRY_COMPARE(item->property("finished"), QVariant(true)); } +void tst_QQuickRepeater::package() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("package.qml")); + + QScopedPointer<QObject>o(component.create()); // don't crash! + QVERIFY(o != nullptr); + + { + QQuickRepeater *repeater1 = qobject_cast<QQuickRepeater*>(qmlContext(o.data())->contextProperty("repeater1").value<QObject*>()); + QVERIFY(repeater1); + QCOMPARE(repeater1->count(), 1); + QCOMPARE(repeater1->itemAt(0)->objectName(), "firstItem"); + } + + { + QQuickRepeater *repeater2 = qobject_cast<QQuickRepeater*>(qmlContext(o.data())->contextProperty("repeater2").value<QObject*>()); + QVERIFY(repeater2); + QCOMPARE(repeater2->count(), 1); + QCOMPARE(repeater2->itemAt(0)->objectName(), "secondItem"); + } +} + QTEST_MAIN(tst_QQuickRepeater) #include "tst_qquickrepeater.moc" |