aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp18
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h2
-rw-r--r--tests/auto/quick/qquickrepeater/data/package.qml35
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp24
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"