From 8e20747e94fb24baf9eabbd034efe5c2cf810d55 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 24 Apr 2018 18:10:41 +0200 Subject: QQmlDelegateModel: provide better warnings Currently, QQmlDelegateModel errors look like this: : QML VisualDataModel: Error creating delegate This patch uses the delegate as the QQmlInfo object so that we get errors with actual file names and line numbers: qrc:/main.qml:19:19: QML Component: Error creating delegate This has several benefits: - It's obvious which file is causing the issue - A clickable link in Creator's application output pane Task-number: QTBUG-49224 Change-Id: I0df0d1a9e898aff5f83131ca62a47cc7f1c74c6e Reviewed-by: Simon Hausmann Reviewed-by: Michael Brasser --- src/qml/types/qqmldelegatemodel.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/qml/types') diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 44166e4aa8..c7351b654c 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -874,7 +874,6 @@ void QQmlDelegateModelPrivate::removeCacheItem(QQmlDelegateModelItem *cacheItem) void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status) { - Q_Q(QQmlDelegateModel); if (!isDoneIncubating(status)) return; @@ -891,7 +890,7 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba emitCreatedItem(incubationTask, cacheItem->object); cacheItem->releaseObject(); } else if (status == QQmlIncubator::Error) { - qmlWarning(q, m_delegate->errors()) << "Error creating delegate"; + qmlWarning(m_delegate, m_delegate->errors()) << "Error creating delegate"; } if (!cacheItem->isObjectReferenced()) { -- cgit v1.2.3 From 9d64da2fef62be237be964838ae9096f436ee7cd Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 24 Apr 2018 18:26:23 +0200 Subject: QQmlDelegateModel: include QQDMIncubationTask errors with our errors With the snippet in the referenced bug report (and the parent patch applied), the output is: qrc:/main.qml:19:19: QML ListView: Error creating delegate There should be more errors after this line, but since the delegate itself didn't have any errors, we need to also check with the incubation task. After doing so, the output becomes: qrc:/main.qml:19:19: QML ListView: Error creating delegate: qrc:/main.qml: Object destroyed during incubation This adds important context (for developers and for users reporting issues in the future) that was previously missing. Task-number: QTBUG-49224 Change-Id: Ic7ac1a06c7dbdf3746f960d28908cc10f6ae86f5 Reviewed-by: Simon Hausmann --- src/qml/types/qqmldelegatemodel.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/qml/types') diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index c7351b654c..26c20d043f 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -877,6 +877,8 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba if (!isDoneIncubating(status)) return; + const QList incubationTaskErrors = incubationTask->errors(); + QQmlDelegateModelItem *cacheItem = incubationTask->incubating; cacheItem->incubationTask = nullptr; incubationTask->incubating = nullptr; @@ -890,7 +892,7 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba emitCreatedItem(incubationTask, cacheItem->object); cacheItem->releaseObject(); } else if (status == QQmlIncubator::Error) { - qmlWarning(m_delegate, m_delegate->errors()) << "Error creating delegate"; + qmlWarning(m_delegate, incubationTaskErrors + m_delegate->errors()) << "Error creating delegate"; } if (!cacheItem->isObjectReferenced()) { -- cgit v1.2.3 From 01df9e5f46fd05a80f8f6fcaa91204e6184ded6f Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 26 Apr 2018 11:47:27 +0200 Subject: Fix QML context leak with visual data model and list property models When using the VDM or QML list properties as models, the delegate model injects an intermediate QQmlContext that provides access to the properties of the exposed QObject as context properties. Before commit e22b624d9ab1f36021adb9cdbfa9b37054282bb8, that context was marked to be owned by the parent QQmlContext. When the reference counting was introduced, that parent became referenced from the cacheItem (DelegateModelItem), but that intermediate QQmlContext became floating and was leaked. This can be observed by running the objectListModel test of tst_qquickvisualdatamodel with detect_leaks=1 in ASAN_OPTIONS. The leak is fixed by re-introducing the exceptional case of a parent holding a strong reference to the child, in just this one case. Change-Id: Iabc26990d39757b0abe0cddf69e76e88e40fba40 Reviewed-by: Lars Knoll Reviewed-by: Michael Brasser --- src/qml/types/qqmldelegatemodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml/types') diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 26c20d043f..eb02e8045a 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -989,7 +989,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ if (QQmlAdaptorModelProxyInterface *proxy = qobject_cast(cacheItem)) { ctxt = new QQmlContextData; - ctxt->setParent(cacheItem->contextData); + ctxt->setParent(cacheItem->contextData, /*stronglyReferencedByParent*/true); ctxt->contextObject = proxy->proxiedObject(); } } -- cgit v1.2.3