QPushButton with a menu remains in sunken state after menu closed

Regression fix, introduced in:
7199498fb9cbfb5afc043ddb0e630c8ffad5240b

QPushButton with a menu will have a sunken state, QStyle::State_Sunken,
when the menu has been closed. Expected behavior is that the sunken
style is to be removed when the menu is closed.

A boolean called "menuOpen" is never set to false after being set to
true in the popupPressed() method. When this boolean is true, a sunken
state is painted.

Fixes: QTBUG-120976
Change-Id: I3e721da5dfbb6db200aa2de7366ac5dc73c873e0
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
(cherry picked from commit 343551ffae66048599e5360085d1b77f64b9336e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit cb6cdad0789c641811542354bf1a4b1093cd5742)
This commit is contained in:
Ed Cooke 2024-01-18 13:57:00 +01:00 committed by Qt Cherry-pick Bot
parent d01654ffb0
commit a9d5e1efa5
2 changed files with 49 additions and 1 deletions

View File

@ -581,7 +581,7 @@ void QPushButtonPrivate::_q_popupPressed()
//menu visibility to avoid flicker on button release
menuOpen = true;
QObject::connect(menu, &QMenu::aboutToHide,
q, [q]{ q->setDown(false); }, Qt::SingleShotConnection);
q, [q, this]{ menuOpen = false; q->setDown(false); }, Qt::SingleShotConnection);
menu->popup(menuPos);
}

View File

@ -15,6 +15,7 @@
#include <QGridLayout>
#include <QStyleFactory>
#include <QTabWidget>
#include <QStyleOption>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
@ -54,6 +55,7 @@ private slots:
void hitButton();
void iconOnlyStyleSheet();
void mousePressAndMove();
void reactToMenuClosed();
protected slots:
void resetCounters();
@ -760,5 +762,51 @@ void tst_QPushButton::mousePressAndMove()
QCOMPARE(releaseSpy.size(), 1);
}
/*
Test checking that a QPushButton with a QMenu has a sunken style only
when the menu is open
QTBUG-120976
*/
void tst_QPushButton::reactToMenuClosed()
{
// create a subclass of QPushButton to expose the initStyleOption method
class PushButton : public QPushButton {
public:
virtual void initStyleOption(QStyleOptionButton *option) const override
{
QPushButton::initStyleOption(option);
}
};
PushButton button;
QStyleOptionButton opt;
QMenu menu;
// add a menu to the button
menu.addAction(tr("string"));
button.setMenu(&menu);
// give the button a size and show it
button.setGeometry(0, 0, 50, 50);
button.show();
QVERIFY(QTest::qWaitForWindowExposed(&button));
// click the button to open the menu
QTest::mouseClick(&button, Qt::LeftButton);
// check the menu is visible and the button style is sunken
QTRY_VERIFY(menu.isVisible());
button.initStyleOption(&opt);
QVERIFY(opt.state.testFlag(QStyle::StateFlag::State_Sunken));
// close the menu
menu.close();
// check the menu isn't visible and the style isn't sunken
QTRY_VERIFY(!menu.isVisible());
button.initStyleOption(&opt);
QVERIFY(!opt.state.testFlag(QStyle::StateFlag::State_Sunken));
}
QTEST_MAIN(tst_QPushButton)
#include "tst_qpushbutton.moc"