diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2023-02-14 11:43:23 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-02-16 11:40:17 +0000 |
commit | 25ece74bfe8de716d437c7266b22e93ae9cd37a5 (patch) | |
tree | b9ddc5fab7d099e2a89211739e73f9b6e50fcf53 | |
parent | Android: use test QFileInfo fileName() instead of completeBaseName() (diff) | |
download | qtbase-25ece74bfe8de716d437c7266b22e93ae9cd37a5.tar.xz qtbase-25ece74bfe8de716d437c7266b22e93ae9cd37a5.zip |
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>
-rw-r--r-- | src/widgets/widgets/qstatusbar.cpp | 15 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp | 44 |
2 files changed, 47 insertions, 12 deletions
diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp index 9a9879a48d..2cd3ac3036 100644 --- a/src/widgets/widgets/qstatusbar.cpp +++ b/src/widgets/widgets/qstatusbar.cpp @@ -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."); diff --git a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp index 418dd1c0f9..15007e8a90 100644 --- a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp +++ b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp @@ -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)) |