aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-05-20 14:37:12 +0200
committerUlf Hermann <ulf.hermann@qt.io>2020-05-25 10:21:38 +0200
commit5654d77ef667438ea13ed219e39d39080f769d66 (patch)
treefd262ee8948e5a27a3dcaa6d3e019c79e963943c
parentba047960a1af56249bd5f64883aaa70bddf48313 (diff)
Fix handling of QQuickViewPrivate::root
QQuickView is supposed to own the root item and shall also track it for external deletion. Therefore, when we assign a new root item we need to delete the old one. There is no point in setting a QPointer to nullptr after deleting it. It will do that by itself. When we fail to assign a new item, we should _not_ automatically delete the new one. Calling code typically does not expect the argument to a set* call to be deleted right away. Rather, return a boolean indicating whether we have successfully set the root object. This can then be used to get rid of the object if necessary. Coverity-Id: 218729 Change-Id: I79ed37d22d304bcc6d4e3c956b83a65fe157dfe0 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> (cherry picked from commit a64ee3a2481499f856d0f3fbc697399e0df1e8f8) Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r--src/quick/items/qquickview.cpp54
-rw-r--r--src/quick/items/qquickview_p.h2
2 files changed, 33 insertions, 23 deletions
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index c411da9519..70d7f57b81 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -76,7 +76,7 @@ void QQuickViewPrivate::init(QQmlEngine* e)
}
QQuickViewPrivate::QQuickViewPrivate()
- : root(nullptr), component(nullptr), resizeMode(QQuickView::SizeViewToRootObject), initialSize(0,0)
+ : component(nullptr), resizeMode(QQuickView::SizeViewToRootObject), initialSize(0,0)
{
}
@@ -92,10 +92,8 @@ void QQuickViewPrivate::execute()
return;
}
- if (root) {
+ if (root)
delete root;
- root = nullptr;
- }
if (component) {
delete component;
component = nullptr;
@@ -212,7 +210,6 @@ QQuickView::~QQuickView()
// be a child of the QQuickViewPrivate, and will be destroyed by its dtor
Q_D(QQuickView);
delete d->root;
- d->root = nullptr;
}
/*!
@@ -263,7 +260,8 @@ void QQuickView::setContent(const QUrl& url, QQmlComponent *component, QObject*
return;
}
- d->setRootObject(item);
+ if (!d->setRootObject(item))
+ delete item;
emit statusChanged(status());
}
@@ -486,43 +484,55 @@ void QQuickView::continueExecute()
return;
}
- d->setRootObject(obj);
+ if (!d->setRootObject(obj))
+ delete obj;
emit statusChanged(status());
}
/*!
\internal
+
+ Sets \a obj as root object and returns true if that operation succeeds.
+ Otherwise returns \c false. If \c false is returned, the root object is
+ \c nullptr afterwards. You can explicitly set the root object to nullptr,
+ and the return value will be \c true.
*/
-void QQuickViewPrivate::setRootObject(QObject *obj)
+bool QQuickViewPrivate::setRootObject(QObject *obj)
{
Q_Q(QQuickView);
if (root == obj)
- return;
+ return true;
+
+ delete root;
+ if (obj == nullptr)
+ return true;
+
if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(obj)) {
root = sgItem;
sgItem->setParentItem(q->QQuickWindow::contentItem());
QQml_setParent_noEvent(sgItem, q->QQuickWindow::contentItem());
- } else if (qobject_cast<QWindow *>(obj)) {
- qWarning() << "QQuickView does not support using windows as a root item." << endl
- << endl
- << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << endl;
- } else {
- qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << endl
- << endl
- << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << endl
- << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << endl;
- delete obj;
- root = nullptr;
- }
- if (root) {
initialSize = rootObjectSize();
if ((resizeMode == QQuickView::SizeViewToRootObject || q->width() <= 1 || q->height() <= 1) &&
initialSize != q->size()) {
q->resize(initialSize);
}
initResize();
+ return true;
+ }
+
+ if (qobject_cast<QWindow *>(obj)) {
+ qWarning() << "QQuickView does not support using a window as a root item." << endl
+ << endl
+ << "If you wish to create your root window from QML, consider using QQmlApplicationEngine instead." << endl;
+ return false;
}
+
+ qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << endl
+ << endl
+ << "Ensure your QML code is written for QtQuick 2, and uses a root that is or" << endl
+ << "inherits from QtQuick's Item (not a Timer, QtObject, etc)." << endl;
+ return false;
}
/*!
diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h
index 3f284c0519..75e369411f 100644
--- a/src/quick/items/qquickview_p.h
+++ b/src/quick/items/qquickview_p.h
@@ -91,7 +91,7 @@ public:
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) override;
void initResize();
void updateSize();
- void setRootObject(QObject *);
+ bool setRootObject(QObject *);
void init(QQmlEngine* e = nullptr);