diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2019-02-13 13:31:07 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-02-14 08:01:28 +0000 |
commit | dbc811e164019b5f9ce371cb7b49d695644f6a90 (patch) | |
tree | cf73cd456d27ec35d16239f94ba80b89775d3408 /tests/auto/quick/qquickvisualdatamodel | |
parent | 0148243a77a42de1ba6170a1da3977b3026c1927 (diff) |
DelegateModel: Zero foreign context objects when they are deleted
If we keep plain pointers to objects we don't own, we need to zero them
when something else deletes them.
Fixes: QTBUG-73733
Change-Id: Ib4f3e144f10f70ab6cf44af4ffa62725470d3972
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'tests/auto/quick/qquickvisualdatamodel')
-rw-r--r-- | tests/auto/quick/qquickvisualdatamodel/data/externalManagedModel.qml | 65 | ||||
-rw-r--r-- | tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp | 68 |
2 files changed, 133 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickvisualdatamodel/data/externalManagedModel.qml b/tests/auto/quick/qquickvisualdatamodel/data/externalManagedModel.qml new file mode 100644 index 0000000000..44c157b824 --- /dev/null +++ b/tests/auto/quick/qquickvisualdatamodel/data/externalManagedModel.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tests of the QtQuick module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Window 2.2 +import QtQuick 2.6 +import QtQml.Models 2.11 +import example 1.0 + +Window { + visible: true + property bool running: rebuildTimer.running + ListView { + anchors.fill: parent + model: delegateModel + } + + DelegateModel { + id: delegateModel + model: objectsProvider.objects + delegate: Item {} + } + + Timer { + id: rebuildTimer + running: true + repeat: true + interval: 1 + + property int count: 0 + onTriggered: { + objectsProvider.rebuild(); + if (++count === 10) + running = false; + } + } + + ObjectsProvider { + id: objectsProvider + } +} diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp index 1b8654ecdd..fac8283e2c 100644 --- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp +++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp @@ -431,6 +431,7 @@ private slots: void asynchronousMove_data(); void asynchronousCancel(); void invalidContext(); + void externalManagedModel(); private: template <int N> void groups_verify( @@ -4234,6 +4235,73 @@ void tst_qquickvisualdatamodel::invalidContext() QVERIFY(!item); } +class ObjectsProvider : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty<QObject> objects READ objects NOTIFY objectsChanged) + +public: + explicit ObjectsProvider(QObject *parent = nullptr) : QObject(parent) {} + + Q_INVOKABLE void rebuild() + { + for (auto old: m_objects) + old->deleteLater(); + + m_objects.clear(); + emit objectsChanged(); + + const int size = std::rand() & 0xff; + for (int i = 0; i < size; ++i) { + auto newElement = new QObject(this); + QQmlEngine::setObjectOwnership(newElement, QQmlEngine::CppOwnership); + m_objects.push_back(newElement); + } + emit objectsChanged(); + } + + Q_INVOKABLE QQmlListProperty<QObject> objects() + { + return QQmlListProperty<QObject>(this, nullptr, &ObjectsProvider::listLength, + &ObjectsProvider::listAt); + } + + static int listLength(QQmlListProperty<QObject> *property) + { + auto objectsProvider = qobject_cast<ObjectsProvider*>(property->object); + return objectsProvider ? objectsProvider->m_objects.length() : 0; + } + + static QObject* listAt(QQmlListProperty<QObject> *property, int index) + { + auto objectsProvider = qobject_cast<ObjectsProvider*>(property->object); + return objectsProvider ? objectsProvider->m_objects.at(index) : nullptr; + } + +signals: + void objectsChanged(); + +private: + QList<QObject *> m_objects; +}; + +void tst_qquickvisualdatamodel::externalManagedModel() +{ + qmlRegisterType<ObjectsProvider>("example", 1, 0, "ObjectsProvider"); + + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("externalManagedModel.qml")); + QVERIFY(component.isReady()); + + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + + QVERIFY(object->property("running").toBool()); + + // Make sure it runs to completion without crashing. + QTRY_VERIFY(!object->property("running").toBool()); +} + QTEST_MAIN(tst_qquickvisualdatamodel) #include "tst_qquickvisualdatamodel.moc" |