Fix QStatusBar::removeWidget to hide the right widget

`QStatusBar::removeWidget` was hiding the wrong widget (the next one),
since the `removeAt` call changed the item that the `item` variable
is referencing.

This fixes a regression in Qt 6.3.0 (7166a82844500238a4dad91857384479c7).

Change-Id: I9977b47e6208f8d451ff1037bcb9f4e8414cb431
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Thorbjørn Lindeijer <bjorn@lindeijer.nl>
(cherry picked from commit 3e7226f10702828eaaf2fa939efc2ac476e8a2b4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Thorbjørn Lindeijer 2023-02-14 11:43:23 +01:00 committed by Qt Cherry-pick Bot
parent c450780358
commit 25ece74bfe
2 changed files with 47 additions and 12 deletions

View File

@ -355,19 +355,10 @@ void QStatusBar::removeWidget(QWidget *widget)
return;
Q_D(QStatusBar);
bool found = false;
for (int i = 0; i < d->items.size(); ++i) {
const auto &item = d->items.at(i);
if (item.widget == widget) {
d->items.removeAt(i);
item.widget->hide();
found = true;
break;
}
}
if (found)
if (d->items.removeIf([widget](const auto &item) { return item.widget == widget; })) {
widget->hide();
reformat();
}
#if defined(QT_DEBUG)
else
qDebug("QStatusBar::removeWidget(): Widget not found.");

View File

@ -23,6 +23,7 @@ private slots:
void tempMessage();
void insertWidget();
void insertPermanentWidget();
void removeWidget();
void setSizeGripEnabled();
void task194017_hiddenWidget();
void QTBUG4334_hiddenOnMaximizedWindow();
@ -104,6 +105,49 @@ void tst_QStatusBar::insertPermanentWidget()
QCOMPARE(sb.insertPermanentWidget(1, new QLabel("foo")), 6);
}
void tst_QStatusBar::removeWidget()
{
QStatusBar sb;
std::vector<std::unique_ptr<QLabel>> widgets;
std::vector<bool> states;
for (int i = 0; i < 10; ++i) {
const QString text = i > 5 ? QString("p_%1").arg(i) : QString::number(i);
widgets.push_back(std::make_unique<QLabel>(text));
states.push_back(true);
}
for (auto &&widget : widgets) {
if (widget->text().startsWith("p_"))
sb.addPermanentWidget(widget.get());
else
sb.addWidget(widget.get());
}
sb.show();
QVERIFY(QTest::qWaitForWindowExposed(&sb));
auto checkStates = [&]{
for (size_t index = 0; index < std::size(widgets); ++index) {
if (widgets.at(index)->isVisible() != states.at(index)) {
qCritical("Mismatch for widget at index %zu\n"
"\tActual : %s\n"
"\tExpected: %s",
index, widgets.at(index)->isVisible() ? "true" : "false",
states.at(index) ? "true" : "false");
return false;
}
}
return true;
};
QVERIFY(checkStates());
// remove every widget except the first to trigger unstable reference
for (size_t i = 2; i < std::size(widgets); ++i) {
sb.removeWidget(widgets[i].get());
states[i] = false;
QVERIFY2(checkStates(), qPrintable(QString("Failure at index %1").arg(i)));
}
}
void tst_QStatusBar::setSizeGripEnabled()
{
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))