aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-01-03 10:38:33 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-06 10:40:08 +0100
commit39540124dd0900e0c99dcda8c0ebdf4f3cea8d5e (patch)
tree8fb7174b6523945101f7bd5177b973a745b357de /tests/auto/quick
parente3232bce40ddefd3b4dfa57a923b15cb47f051bf (diff)
Fix interaction of QQuickItems with the garbage collector
The QObject ownership of QQuickItem objects is not accessible / mutable in QML, because the parent property maps to the (dynamic) visual parent. There are use-cases of creating QQuickItem objects without a QObject parent and to support this, the visual parent needs to mark its visual children in order to provide intuitive semantics. [ChangeLog][QtQuick][Import Behavior Changes] A QQuick Item is now strongly referenced by its visual parent item, so it doesn't require a QObject parent to stay alive. Task-number: QTBUG-35913 Change-Id: Ief2d40ac76298a0cf241ca73ff654c4ecfa12748 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/qquickitem/data/visualParentOwnership.qml14
-rw-r--r--tests/auto/quick/qquickitem/tst_qquickitem.cpp65
2 files changed, 79 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickitem/data/visualParentOwnership.qml b/tests/auto/quick/qquickitem/data/visualParentOwnership.qml
new file mode 100644
index 0000000000..644d14ba43
--- /dev/null
+++ b/tests/auto/quick/qquickitem/data/visualParentOwnership.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Item {
+ Component {
+ id: factory
+ Item {}
+ }
+
+ property Item keepAliveProperty;
+
+ function createItemWithoutParent() {
+ return factory.createObject(/*parent*/ null);
+ }
+}
diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
index ad3c4fc208..f4f2374183 100644
--- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
@@ -49,6 +49,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <QDebug>
#include <QTimer>
+#include <QQmlEngine>
#include "../../shared/util.h"
class TestItem : public QQuickItem
@@ -167,6 +168,8 @@ private slots:
void acceptedMouseButtons();
+ void visualParentOwnership();
+
private:
enum PaintOrderOp {
@@ -1754,6 +1757,68 @@ void tst_qquickitem::acceptedMouseButtons()
QCOMPARE(item.releaseCount, 3);
}
+static void gc(QQmlEngine &engine)
+{
+ engine.collectGarbage();
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::processEvents();
+}
+
+void tst_qquickitem::visualParentOwnership()
+{
+ QQuickView view;
+ view.setSource(testFileUrl("visualParentOwnership.qml"));
+
+ QQuickItem *root = qobject_cast<QQuickItem*>(view.rootObject());
+ QVERIFY(root);
+
+ QVariant newObject;
+ {
+ QVERIFY(QMetaObject::invokeMethod(root, "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject)));
+ QPointer<QQuickItem> newItem = qvariant_cast<QQuickItem*>(newObject);
+ QVERIFY(!newItem.isNull());
+
+ QVERIFY(!newItem->parent());
+ QVERIFY(!newItem->parentItem());
+
+ newItem->setParentItem(root);
+
+ gc(*view.engine());
+
+ QVERIFY(!newItem.isNull());
+ newItem->setParentItem(0);
+
+ gc(*view.engine());
+ QVERIFY(newItem.isNull());
+ }
+ {
+ QVERIFY(QMetaObject::invokeMethod(root, "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject)));
+ QPointer<QQuickItem> firstItem = qvariant_cast<QQuickItem*>(newObject);
+ QVERIFY(!firstItem.isNull());
+
+ firstItem->setParentItem(root);
+
+ QVERIFY(QMetaObject::invokeMethod(root, "createItemWithoutParent", Q_RETURN_ARG(QVariant, newObject)));
+ QPointer<QQuickItem> secondItem = qvariant_cast<QQuickItem*>(newObject);
+ QVERIFY(!firstItem.isNull());
+
+ secondItem->setParentItem(firstItem);
+
+ gc(*view.engine());
+
+ delete firstItem;
+
+ root->setProperty("keepAliveProperty", newObject);
+
+ gc(*view.engine());
+ QVERIFY(!secondItem.isNull());
+
+ root->setProperty("keepAliveProperty", QVariant());
+
+ gc(*view.engine());
+ QVERIFY(secondItem.isNull());
+ }
+}
QTEST_MAIN(tst_qquickitem)