diff --git a/src/quicklayouts/qquicklinearlayout.cpp b/src/quicklayouts/qquicklinearlayout.cpp index 116678c1d0..b34815e449 100644 --- a/src/quicklayouts/qquicklinearlayout.cpp +++ b/src/quicklayouts/qquicklinearlayout.cpp @@ -457,6 +457,10 @@ void QQuickGridLayoutBase::rearrange(const QSizeF &size) return; } + // Should normally not be needed, but there might be an incoming window resize event that we + // will process before we process updatePolish() + ensureLayoutItemsUpdated(QQuickLayout::ApplySizeHints | QQuickLayout::Recursive); + d->m_rearranging = true; qCDebug(lcQuickLayouts) << objectName() << "QQuickGridLayoutBase::rearrange()" << size; Qt::LayoutDirection visualDir = effectiveLayoutDirection(); diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml index 506893b631..7f7352e25b 100644 --- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml +++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml @@ -1470,6 +1470,43 @@ Item { verify(!BindingLoopDetector.bindingLoopDetected, "Detected binding loop") BindingLoopDetector.reset() } - } + + //--------------------------- + // QTBUG-111792 + Component { + id: rowlayoutCrashes_Component + RowLayout { + spacing: 5 + Rectangle { + color: "red" + implicitWidth: 10 + implicitHeight: 10 + } + Rectangle { + color: "green" + implicitWidth: 10 + implicitHeight: 10 + } + } + } + + function test_dontCrashAfterDestroyingChildren_data() { + return [ + { tag: "setWidth", func: function (layout) { layout.width = 42 } }, + { tag: "setHeight", func: function (layout) { layout.height = 42 } }, + { tag: "getImplicitWidth", func: function (layout) { let x = layout.implicitWidth } }, + { tag: "getImplicitHeight", func: function (layout) { let x = layout.implicitHeight } }, + ] + } + + function test_dontCrashAfterDestroyingChildren(data) { + var layout = createTemporaryObject(rowlayoutCrashes_Component, container) + waitForRendering(layout) + compare(layout.implicitWidth, 25) + layout.children[0].destroy() // deleteLater() + wait(0) // process the scheduled delete and actually invoke the dtor + data.func(layout) // call a function that might ultimately access the deleted item (but shouldn't) + } + } }