aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlopenmetaobject.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2014-06-29 15:47:04 +0800
committerSimon Hausmann <simon.hausmann@qt.io>2018-05-11 08:51:43 +0000
commit9f5bd5ab102325b03c2afaae39c6927fa89a956c (patch)
tree88c1c4e07020e54545c7d82d8e2f42d767b2d022 /src/qml/qml/qqmlopenmetaobject.cpp
parent5132709440d9161aae5893341d9180137f1181d7 (diff)
Fix storing QObject pointers in dynamic role models
Storing QObject pointers in a dynamic role model man end up crashing the application once those objects get deleted. As it looks impossible to make QVariant::fromValue<QObject*>(...) track the life cycle in a binary compatible way, this patch fixes the crashes by tracking with a QPointer at the level of QVariant storage. That's the QQmlOpenMetaObject in the case of the dynamic role model. In principle a similar approach is already in place for storage of QML declared properties - this patch mirrors the approach. Test cases provided by Ben Lau <xbenlau@gmail.com> and Chris Adams <chris.adams@jollamobile.com>. Task-number: QTBUG-35639 Change-Id: I0aee227cd2057654c2cb843c4ebb57ed2ec9a8bf Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlopenmetaobject.cpp')
-rw-r--r--src/qml/qml/qqmlopenmetaobject.cpp10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlopenmetaobject.cpp b/src/qml/qml/qqmlopenmetaobject.cpp
index ff89278faf..ce5983e05c 100644
--- a/src/qml/qml/qqmlopenmetaobject.cpp
+++ b/src/qml/qml/qqmlopenmetaobject.cpp
@@ -187,14 +187,22 @@ public:
struct Property {
private:
QVariant m_value;
+ QPointer<QObject> qobjectTracker;
public:
bool valueSet = false;
- const QVariant &value() const { return m_value; }
+ QVariant value() const {
+ if (QMetaType::typeFlags(m_value.userType()) & QMetaType::PointerToQObject
+ && qobjectTracker.isNull())
+ return QVariant::fromValue<QObject*>(nullptr);
+ return m_value;
+ }
QVariant &valueRef() { return m_value; }
void setValue(const QVariant &v) {
m_value = v;
valueSet = true;
+ if (QMetaType::typeFlags(v.userType()) & QMetaType::PointerToQObject)
+ qobjectTracker = m_value.value<QObject*>();
}
};