diff --git a/src/layouts/qquicklinearlayout.cpp b/src/layouts/qquicklinearlayout.cpp index b9a8e2249444dc3ff7f74f1af7ada9a550cf168a..13b582f9a96f6713f3a985f3667b048172592479 100644 --- a/src/layouts/qquicklinearlayout.cpp +++ b/src/layouts/qquicklinearlayout.cpp @@ -184,12 +184,18 @@ QSizeF QQuickGridLayoutBase::sizeHint(Qt::SizeHint whichSizeHint) const return d->engine.sizeHint(whichSizeHint, QSizeF()); } +QQuickGridLayoutBase::~QQuickGridLayoutBase() +{ + d_func()->m_isReady = false; +} + void QQuickGridLayoutBase::componentComplete() { Q_D(QQuickGridLayoutBase); quickLayoutDebug() << objectName() << "QQuickGridLayoutBase::componentComplete()" << parent(); d->m_disableRearrange = true; QQuickLayout::componentComplete(); // will call our geometryChange(), (where isComponentComplete() == true) + d->m_isReady = true; d->m_disableRearrange = false; updateLayoutItems(); @@ -235,7 +241,7 @@ void QQuickGridLayoutBase::componentComplete() void QQuickGridLayoutBase::invalidate(QQuickItem *childItem) { Q_D(QQuickGridLayoutBase); - if (!isComponentComplete()) + if (!isReady()) return; quickLayoutDebug() << "QQuickGridLayoutBase::invalidate()"; @@ -274,7 +280,7 @@ void QQuickGridLayoutBase::invalidate(QQuickItem *childItem) void QQuickGridLayoutBase::updateLayoutItems() { Q_D(QQuickGridLayoutBase); - if (!isComponentComplete() || !isVisible()) + if (!isReady() || !isVisible()) return; quickLayoutDebug() << "QQuickGridLayoutBase::updateLayoutItems"; d->engine.deleteItems(); @@ -294,7 +300,7 @@ void QQuickGridLayoutBase::itemChange(ItemChange change, const ItemChangeData &v QObject::connect(item, SIGNAL(implicitWidthChanged()), this, SLOT(onItemImplicitSizeChanged())); QObject::connect(item, SIGNAL(implicitHeightChanged()), this, SLOT(onItemImplicitSizeChanged())); - if (isComponentComplete() && isVisible()) + if (isReady() && isVisible()) updateLayoutItems(); } else if (change == ItemChildRemovedChange) { quickLayoutDebug() << "ItemChildRemovedChange"; @@ -303,7 +309,7 @@ void QQuickGridLayoutBase::itemChange(ItemChange change, const ItemChangeData &v QObject::disconnect(item, SIGNAL(visibleChanged()), this, SLOT(onItemVisibleChanged())); QObject::disconnect(item, SIGNAL(implicitWidthChanged()), this, SLOT(onItemImplicitSizeChanged())); QObject::disconnect(item, SIGNAL(implicitHeightChanged()), this, SLOT(onItemImplicitSizeChanged())); - if (isComponentComplete() && isVisible()) + if (isReady() && isVisible()) updateLayoutItems(); } @@ -314,7 +320,7 @@ void QQuickGridLayoutBase::geometryChanged(const QRectF &newGeometry, const QRec { Q_D(QQuickGridLayoutBase); QQuickLayout::geometryChanged(newGeometry, oldGeometry); - if (d->m_disableRearrange || !isComponentComplete() || !newGeometry.isValid()) + if (d->m_disableRearrange || !isReady() || !newGeometry.isValid()) return; quickLayoutDebug() << "QQuickGridLayoutBase::geometryChanged" << newGeometry << oldGeometry; rearrange(newGeometry.size()); @@ -328,6 +334,11 @@ void QQuickGridLayoutBase::removeGridItem(QGridLayoutItem *gridItem) d->engine.removeRows(index, 1, d->orientation); } +bool QQuickGridLayoutBase::isReady() const +{ + return d_func()->m_isReady; +} + void QQuickGridLayoutBase::removeLayoutItem(QQuickItem *item) { Q_D(QQuickGridLayoutBase); @@ -341,7 +352,7 @@ void QQuickGridLayoutBase::removeLayoutItem(QQuickItem *item) void QQuickGridLayoutBase::onItemVisibleChanged() { - if (!isComponentComplete()) + if (!isReady()) return; quickLayoutDebug() << "QQuickGridLayoutBase::onItemVisibleChanged"; updateLayoutItems(); @@ -349,6 +360,8 @@ void QQuickGridLayoutBase::onItemVisibleChanged() void QQuickGridLayoutBase::onItemDestroyed() { + if (!isReady()) + return; Q_D(QQuickGridLayoutBase); quickLayoutDebug() << "QQuickGridLayoutBase::onItemDestroyed"; QQuickItem *inDestruction = static_cast<QQuickItem *>(sender()); @@ -361,6 +374,8 @@ void QQuickGridLayoutBase::onItemDestroyed() void QQuickGridLayoutBase::onItemImplicitSizeChanged() { + if (!isReady()) + return; QQuickItem *item = static_cast<QQuickItem *>(sender()); Q_ASSERT(item); invalidate(item); @@ -369,7 +384,7 @@ void QQuickGridLayoutBase::onItemImplicitSizeChanged() void QQuickGridLayoutBase::rearrange(const QSizeF &size) { Q_D(QQuickGridLayoutBase); - if (!isComponentComplete()) + if (!isReady()) return; quickLayoutDebug() << objectName() << "QQuickGridLayoutBase::rearrange()" << size; diff --git a/src/layouts/qquicklinearlayout_p.h b/src/layouts/qquicklinearlayout_p.h index 76cc206b9c3e29a60eaf709b8ac35e6edecd8271..b38bd97f78d9a2a348c898195ad37f2a3ca320ea 100644 --- a/src/layouts/qquicklinearlayout_p.h +++ b/src/layouts/qquicklinearlayout_p.h @@ -62,8 +62,7 @@ public: explicit QQuickGridLayoutBase(QQuickGridLayoutBasePrivate &dd, Qt::Orientation orientation, QQuickItem *parent = 0); - ~QQuickGridLayoutBase() {} - + ~QQuickGridLayoutBase(); void componentComplete(); void invalidate(QQuickItem *childItem = 0); Qt::Orientation orientation() const; @@ -86,6 +85,7 @@ protected slots: private: void removeGridItem(QGridLayoutItem *gridItem); + bool isReady() const; Q_DECLARE_PRIVATE(QQuickGridLayoutBase) }; @@ -95,10 +95,11 @@ class QQuickGridLayoutBasePrivate : public QQuickLayoutPrivate Q_DECLARE_PUBLIC(QQuickGridLayoutBase) public: - QQuickGridLayoutBasePrivate() : m_disableRearrange(true) { } + QQuickGridLayoutBasePrivate() : m_disableRearrange(true), m_isReady(false) { } QQuickGridLayoutEngine engine; Qt::Orientation orientation; bool m_disableRearrange; + bool m_isReady; QSet<QQuickItem *> m_ignoredItems; }; diff --git a/tests/auto/controls/data/tst_rowlayout.qml b/tests/auto/controls/data/tst_rowlayout.qml index fd21f47560de6215bcf4b039bbb3d08c40cc6058..458a2885f2604a453faf400f039d904982e978a2 100644 --- a/tests/auto/controls/data/tst_rowlayout.qml +++ b/tests/auto/controls/data/tst_rowlayout.qml @@ -633,5 +633,25 @@ Item { compare(r1.y, 6) // 5.5 layout.destroy(); } + + + Component { + id: layout_deleteLayout + ColumnLayout { + property int dummyproperty: 0 // yes really - its needed + RowLayout { + Text { text: "label1" } // yes, both are needed + Text { text: "label2" } + } + } + } + + function test_destroyLayout() + { + var layout = layout_deleteLayout.createObject(container) + layout.children[0].children[0].visible = true + layout.visible = false + layout.destroy() // Do not crash + } } }