Templates: Disconnect menu bar items when clearing

Otherwise we get change notifications for half-dead change listeners and
subsequent crashes.

Pick-to: 6.10 6.9 6.8 6.5
Task-number: QTBUG-137554
Change-Id: I194ca0f8c3a540b1bfc41fa969d0cd3b9e6c24e4
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Ulf Hermann 2025-06-25 15:55:35 +02:00
parent 182bb9d04d
commit fc0bf5a9fd
3 changed files with 48 additions and 1 deletions

View File

@ -339,7 +339,8 @@ QQuickMenu *QQuickMenuBarPrivate::menus_at(QQmlListProperty<QQuickMenu> *prop, q
void QQuickMenuBarPrivate::menus_clear(QQmlListProperty<QQuickMenu> *prop) void QQuickMenuBarPrivate::menus_clear(QQmlListProperty<QQuickMenu> *prop)
{ {
QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object); QQuickMenuBar *menuBar = static_cast<QQuickMenuBar *>(prop->object);
QQuickMenuBarPrivate::get(menuBar)->contentModel->clear(); for (int count = menuBar->count(); count > 0; count = menuBar->count())
menuBar->takeMenu(count - 1);
} }
QPalette QQuickMenuBarPrivate::defaultPalette() const QPalette QQuickMenuBarPrivate::defaultPalette() const

View File

@ -0,0 +1,35 @@
import QtQuick
import QtQuick.Templates
Item {
property int v: 0
MenuBar {
id: menuBar
Menu {}
}
Instantiator {
id: instantiator
delegate: Menu {}
onObjectAdded: (index, object) => {
menuBar.menus.push(object)
}
onObjectRemoved: (index, object) => {
menuBar.menus.length = 0;
}
}
Timer {
running: v < 2
interval: 1
repeat: true
onTriggered: {
instantiator.model = (++v % 2) ? 0 : 2
}
}
}

View File

@ -82,6 +82,7 @@ private slots:
void panMenuBar_data(); void panMenuBar_data();
void panMenuBar(); void panMenuBar();
void dontDeleteDelegates(); void dontDeleteDelegates();
void clearMenus();
private: private:
bool nativeMenuBarSupported = false; bool nativeMenuBarSupported = false;
@ -1896,6 +1897,16 @@ void tst_qquickmenubar::dontDeleteDelegates()
QVERIFY(delegateComponent2); QVERIFY(delegateComponent2);
} }
void tst_qquickmenubar::clearMenus()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("clearMenus.qml"));
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
QScopedPointer<QObject> o(c.create());
QVERIFY(!o.isNull());
QTRY_COMPARE(o->property("v").toInt(), 2);
}
QTEST_QUICKCONTROLS_MAIN(tst_qquickmenubar) QTEST_QUICKCONTROLS_MAIN(tst_qquickmenubar)
#include "tst_qquickmenubar.moc" #include "tst_qquickmenubar.moc"