diff options
Diffstat (limited to 'src/qmlmodels')
-rw-r--r-- | src/qmlmodels/qqmladaptormodel.cpp | 18 | ||||
-rw-r--r-- | src/qmlmodels/qqmladaptormodel_p.h | 8 | ||||
-rw-r--r-- | src/qmlmodels/qqmldelegatemodel.cpp | 4 |
3 files changed, 20 insertions, 10 deletions
diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp index dc3ea8019e..fe0ab6bcbc 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) +void QQmlAdaptorModel::setModel(const QVariant &variant, QObject *) { accessors->cleanup(*this); list.setList(variant); + 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 531e8d9105..8635762bc4 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; QTypeRevision modelItemRevision = QTypeRevision::zero(); @@ -121,7 +125,7 @@ public: ~QQmlAdaptorModel(); inline QVariant model() const { return list.list(); } - void setModel(const QVariant &variant, QObject *parent); + void setModel(const QVariant &variant, QObject *parent = nullptr); void invalidateModel(); bool isValid() const; diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index bbaad6d878..5ace1809d1 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp +++ b/src/qmlmodels/qqmldelegatemodel.cpp @@ -259,7 +259,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) { @@ -443,7 +443,7 @@ void QQmlDelegateModel::setModel(const QVariant &model) _q_itemsRemoved(0, d->m_count); d->disconnectFromAbstractItemModel(); - d->m_adaptorModel.setModel(model, this); + d->m_adaptorModel.setModel(model); d->connectToAbstractItemModel(); d->m_adaptorModel.replaceWatchedRoles(QList<QByteArray>(), d->m_watchedRoles); |