diff options
Diffstat (limited to 'src/qmlmodels')
-rw-r--r-- | src/qmlmodels/qqmladaptormodel.cpp | 18 | ||||
-rw-r--r-- | src/qmlmodels/qqmladaptormodel_p.h | 6 | ||||
-rw-r--r-- | src/qmlmodels/qqmldelegatemodel.cpp | 3 | ||||
-rw-r--r-- | src/qmlmodels/qqmlinstantiator.cpp | 2 |
4 files changed, 20 insertions, 9 deletions
diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp index 2126ad3dc5..991a5c9e08 100644 --- a/src/qmlmodels/qqmladaptormodel.cpp +++ b/src/qmlmodels/qqmladaptormodel.cpp @@ -962,30 +962,36 @@ QQmlAdaptorModel::~QQmlAdaptorModel() accessors->cleanup(*this); } -void QQmlAdaptorModel::setModel(const QVariant &variant, QObject *parent, QQmlEngine *engine) +void QQmlAdaptorModel::setModel(const QVariant &variant, QObject *, QQmlEngine *engine) { accessors->cleanup(*this); list.setList(variant, engine); + modelStrongReference.clear(); if (QObject *object = qvariant_cast<QObject *>(list.list())) { - setObject(object, parent); + if (QQmlData *ddata = QQmlData::get(object)) + modelStrongReference = ddata->jsWrapper; + setObject(object); if (qobject_cast<QAbstractItemModel *>(object)) accessors = new VDMAbstractItemModelDataType(this); else accessors = new VDMObjectDelegateDataType; } else if (list.type() == QQmlListAccessor::ListProperty) { - setObject(static_cast<const QQmlListReference *>(variant.constData())->object(), parent); + auto object = static_cast<const QQmlListReference *>(variant.constData())->object(); + if (QQmlData *ddata = QQmlData::get(object)) + modelStrongReference = ddata->jsWrapper; + setObject(object); accessors = new VDMObjectDelegateDataType; } else if (list.type() == QQmlListAccessor::ObjectList) { - setObject(nullptr, parent); + setObject(nullptr); accessors = new VDMObjectDelegateDataType; } else if (list.type() != QQmlListAccessor::Invalid && list.type() != QQmlListAccessor::Instance) { // Null QObject - setObject(nullptr, parent); + setObject(nullptr); accessors = new VDMListDelegateDataType; } else { - setObject(nullptr, parent); + setObject(nullptr); accessors = &qt_vdm_null_accessors; } } diff --git a/src/qmlmodels/qqmladaptormodel_p.h b/src/qmlmodels/qqmladaptormodel_p.h index ba54c864c6..4dbb6ed54e 100644 --- a/src/qmlmodels/qqmladaptormodel_p.h +++ b/src/qmlmodels/qqmladaptormodel_p.h @@ -70,7 +70,7 @@ class QQmlDelegateModel; class QQmlDelegateModelItem; class QQmlDelegateModelItemMetaType; -class Q_QMLMODELS_PRIVATE_EXPORT QQmlAdaptorModel : public QQmlStrongJSQObjectReference<QObject> +class Q_QMLMODELS_PRIVATE_EXPORT QQmlAdaptorModel : public QQmlGuard<QObject> { public: class Accessors @@ -114,6 +114,10 @@ public: const Accessors *accessors; QPersistentModelIndex rootIndex; QQmlListAccessor list; + // we need to ensure that a JS created model does not get gced, but cannot + // arbitrarily set the parent (using QQmlStrongJSQObjectReference) of QObject based models, + // as that causes issues with singletons + QV4::PersistentValue modelStrongReference; int modelItemRevision = 0; diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index 2079a8ed04..523c0df779 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp +++ b/src/qmlmodels/qqmldelegatemodel.cpp @@ -258,7 +258,7 @@ QQmlDelegateModel::~QQmlDelegateModel() { Q_D(QQmlDelegateModel); d->disconnectFromAbstractItemModel(); - d->m_adaptorModel.setObject(nullptr, this); + d->m_adaptorModel.setObject(nullptr); for (QQmlDelegateModelItem *cacheItem : qAsConst(d->m_cache)) { if (cacheItem->object) { @@ -1728,6 +1728,7 @@ void QQmlDelegateModel::_q_itemsRemoved(int index, int count) return; d->m_count -= count; + Q_ASSERT(d->m_count >= 0); const QList<QQmlDelegateModelItem *> cache = d->m_cache; //Prevents items being deleted in remove loop for (QQmlDelegateModelItem *item : cache) diff --git a/src/qmlmodels/qqmlinstantiator.cpp b/src/qmlmodels/qqmlinstantiator.cpp index 3a0d746eb6..1d5249d4c0 100644 --- a/src/qmlmodels/qqmlinstantiator.cpp +++ b/src/qmlmodels/qqmlinstantiator.cpp @@ -147,7 +147,7 @@ void QQmlInstantiatorPrivate::_q_modelUpdated(const QQmlChangeSet &changeSet, bo { Q_Q(QQmlInstantiator); - if (!componentComplete || effectiveReset) + if (!componentComplete || effectiveReset || !active) return; if (reset) { |