Details
-
Bug
-
Resolution: Fixed
-
P1: Critical
-
5.15.7
-
None
-
-
d1b9a4cac (dev)
Description
Unexpected visibleChanged and parentChanged signals on destruction of item based on QQuickItem.
When the item was invisible before deleting, this item and its children items emit visibleChanged signals inside ~QQuickItem (related to the item )
Which is not expected and can lead to unexpected behavior (see https://bugreports.qt.io/browse/QTBUG-107850), also it can trigger unnecessary flickering or actions on the scene and impact performance (if some logic is connected to that signals).
Isolated example:
class ItemForTesting: public QQuickItem { Q_OBJECT public: explicit ItemForTesting(QQuickItem *parent = nullptr); ~ItemForTesting() override = default; void doSomthing(); }; ItemForTesting::ItemForTesting(QQuickItem *parent) : QQuickItem(parent) {} void ItemForTesting::doSomthing() { // do something } //// Test case { .... QPointer<ItemForTesting> mainItem = new ItemForTesting(m_rootItem); mainItem->setVisible(false); // in this case visibleChanged will be emitted for item and for child items mainItem->connect(mainItem.data(), &QQuickItem::parentChanged, mainItem.data(), [=]() { qCritical() << "ParentChanged for mainItem. Check pointer" << QQmlData::wasDeleted(mainItem.data()) << mainItem.isNull(); }); mainItem->connect(mainItem.data(), &QQuickItem::visibleChanged, mainItem.data(), [=]() { qCritical() << "visibleChanged for mainItem to" << mainItem->isVisible() << "Check pointer" << QQmlData::wasDeleted(mainItem.data()) << mainItem.isNull(); mainItem->doSomething(); }); QQuickItem *childItem = new QQuickItem(mainItem); childItem->connect(childItem, &QQuickItem::visibleChanged, childItem, [=]() { qCritical() << "visibleChanged for childItem to" << childItem->isVisible(); // do something }); QSignalSpy spyDestroy(mainItem, &QObject::destroyed); mainItem->deleteLater(); spyDestroy.wait(); EXPECT_EQ(spyDestroy.count(), 1); }
Attached example qtbug107850_extended.ziphas 3 options:
- to change visible for mainItem created in QML
- to call deleting of mainItem created in QML -> in case if mainItem had visible = false (default case in this example) before the deletion it crashes.
- to call Cpp crash case (like mentioned in ticket https://bugreports.qt.io/browse/QTBUG-107850 description)
pressing on 2 -> crash
pressing on 3 -> crash
pressing on 1, then 2 -> no crash
Attachments
Issue Links
- clones
-
QTBUG-107850 Crash on QQuickItem destruction
- Closed
- relates to
-
QTBUG-107850 Crash on QQuickItem destruction
- Closed
-
QTBUG-108028 Property bindings can be re-evaluated after items are destroyed
- Closed
- mentioned in
-
Page Loading...