summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2023-02-14 11:43:23 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-02-16 11:40:17 +0000
commit25ece74bfe8de716d437c7266b22e93ae9cd37a5 (patch)
treeb9ddc5fab7d099e2a89211739e73f9b6e50fcf53
parentAndroid: use test QFileInfo fileName() instead of completeBaseName() (diff)
downloadqtbase-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.cpp15
-rw-r--r--tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp44
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))