QMenuBar: Fix repetitive emission of triggered() when using addAction(QString)
The action which added by QMenuBar::addAction(const QString &text) already connected relevant signals and slots implicitly, however, while QMenuBarPrivate::updateGeometry -ing, it reconnects them if there's a extension button associated with a hidden popup menu. In that case the QMenuBar::triggered would be fired twice. Since the QAction's ownership may be changed or added dynamically, there are still very rare cases like several widgets share the same QAction object to result in this problem. [ChangeLog][QtWidgets][QMenu] Fixed a bug in QMenu that caused QMenuBar::triggered to be fired multiple times. Task-number: QTBUG-25669 Change-Id: I4d52e82a2136a992e0b37118e41237d96a2c5d22 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
This commit is contained in:
parent
b3e7e9b182
commit
4d898a73e6
@ -3534,9 +3534,13 @@ void QMenu::actionEvent(QActionEvent *e)
|
||||
if (d->tornPopup)
|
||||
d->tornPopup->syncWithMenu(this, e);
|
||||
if (e->type() == QEvent::ActionAdded) {
|
||||
if(!d->tornoff) {
|
||||
connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()));
|
||||
connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()));
|
||||
|
||||
if (!d->tornoff
|
||||
&& !qobject_cast<QMenuBar*>(e->action()->parent())) {
|
||||
// Only connect if the action was not directly added by QMenuBar::addAction(const QString &text)
|
||||
// to avoid the signal being emitted twice
|
||||
connect(e->action(), SIGNAL(triggered()), this, SLOT(_q_actionTriggered()), Qt::UniqueConnection);
|
||||
connect(e->action(), SIGNAL(hovered()), this, SLOT(_q_actionHovered()), Qt::UniqueConnection);
|
||||
}
|
||||
if (QWidgetAction *wa = qobject_cast<QWidgetAction *>(e->action())) {
|
||||
QWidget *widget = wa->requestWidget(this);
|
||||
|
@ -148,11 +148,10 @@ private slots:
|
||||
void taskQTBUG56275_reinsertMenuInParentlessQMenuBar();
|
||||
void QTBUG_57404_existingMenuItemException();
|
||||
#endif
|
||||
void QTBUG_25669_menubarActionDoubleTriggered();
|
||||
void taskQTBUG55966_subMenuRemoved();
|
||||
void QTBUG_58344_invalidIcon();
|
||||
|
||||
void platformMenu();
|
||||
|
||||
void addActionQt5connect();
|
||||
|
||||
protected slots:
|
||||
@ -1633,6 +1632,31 @@ void tst_QMenuBar::addActionQt5connect()
|
||||
QVERIFY(flag);
|
||||
}
|
||||
|
||||
void tst_QMenuBar::QTBUG_25669_menubarActionDoubleTriggered()
|
||||
{
|
||||
QMainWindow win;
|
||||
win.menuBar()->setNativeMenuBar(false);
|
||||
QAction *act1 = win.menuBar()->addAction("Action1");
|
||||
QAction *act2 = win.menuBar()->addAction("Action2");
|
||||
QSignalSpy spy(win.menuBar(), &QMenuBar::triggered);
|
||||
|
||||
win.show();
|
||||
QApplication::setActiveWindow(&win);
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&win));
|
||||
|
||||
QPoint posAct1 = menuBarActionWindowPos(win.menuBar(), act1);
|
||||
QPoint posAct2 = menuBarActionWindowPos(win.menuBar(), act2);
|
||||
|
||||
QTest::mouseClick(win.windowHandle(), Qt::LeftButton, Qt::NoModifier, posAct1);
|
||||
QTRY_COMPARE(spy.count(), 1);
|
||||
|
||||
QTest::mouseClick(win.windowHandle(), Qt::LeftButton, Qt::NoModifier, posAct2);
|
||||
QTRY_COMPARE(spy.count(), 2);
|
||||
|
||||
QTest::mouseClick(win.windowHandle(), Qt::LeftButton, Qt::NoModifier, posAct2);
|
||||
QTRY_COMPARE(spy.count(), 3);
|
||||
}
|
||||
|
||||
void tst_QMenuBar::slotForTaskQTBUG53205()
|
||||
{
|
||||
QWidget *parent = taskQTBUG53205MenuBar->parentWidget();
|
||||
|
Loading…
Reference in New Issue
Block a user