class MyDeleteObject : public QObject
{
Q_OBJECT
- Q_PROPERTY(QObject *nestedObject READ nestedObject NOTIFY nestedObjectChanged);
- Q_PROPERTY(int deleteNestedObject READ deleteNestedObject NOTIFY deleteNestedObjectChanged);
+ Q_PROPERTY(QObject *nestedObject READ nestedObject NOTIFY nestedObjectChanged)
+ Q_PROPERTY(int deleteNestedObject READ deleteNestedObject NOTIFY deleteNestedObjectChanged)
+ Q_PROPERTY(QObject *object2 READ object2 NOTIFY object2Changed)
public:
- MyDeleteObject() : m_nestedObject(new MyQmlObject) {}
+ MyDeleteObject() : m_nestedObject(new MyQmlObject), m_object1(0), m_object2(0) {}
+ Q_INVOKABLE QObject *object1() const { return m_object1; }
+ Q_INVOKABLE QObject *object2() const { return m_object2; }
+ void setObject1(QObject *object) { m_object1 = object; }
+ void setObject2(QObject *object) { m_object2 = object; emit object2Changed(); }
QObject *nestedObject() const { return m_nestedObject; }
int deleteNestedObject() { delete m_nestedObject; m_nestedObject = 0; return 1; }
signals:
void nestedObjectChanged();
void deleteNestedObjectChanged();
+ void object2Changed();
private:
MyQmlObject *m_nestedObject;
+ QObject *m_object1;
+ QObject *m_object2;
};
class DateTimeExporter : public QObject
void fallbackBindings();
void propertyOverride();
void concatenatedStringPropertyAccess();
+ void jsOwnedObjectsDeletedOnEngineDestroy();
private:
static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
delete object;
}
+void tst_qqmlecmascript::jsOwnedObjectsDeletedOnEngineDestroy()
+{
+ QQmlEngine *myEngine = new QQmlEngine;
+
+ MyDeleteObject deleteObject;
+ deleteObject.setObjectName("deleteObject");
+ QObject * const object1 = new QObject;
+ QObject * const object2 = new QObject;
+ object1->setObjectName("object1");
+ object2->setObjectName("object2");
+ deleteObject.setObject1(object1);
+ deleteObject.setObject2(object2);
+
+ // Objects returned by function calls get marked as destructible, but objects returned by
+ // property getters do not - therefore we explicitly set the object as destructible.
+ QQmlEngine::setObjectOwnership(object2, QQmlEngine::JavaScriptOwnership);
+
+ myEngine->rootContext()->setContextProperty("deleteObject", &deleteObject);
+ QQmlComponent component(myEngine, testFileUrl("jsOwnedObjectsDeletedOnEngineDestroy.qml"));
+ QObject *object = component.create();
+ QVERIFY(object);
+
+ // Destroying the engine should delete all JS owned QObjects
+ QSignalSpy spy1(object1, SIGNAL(destroyed()));
+ QSignalSpy spy2(object2, SIGNAL(destroyed()));
+ delete myEngine;
+ QCOMPARE(spy1.count(), 1);
+ QCOMPARE(spy2.count(), 1);
+
+ delete object;
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"