Why does this slot get called twice?
Asked Answered
D

2

7

My problem is that when I click on an item in a QMenuBar, the corresponding slot gets called twice. I'm using Qt 4.8.1. I'm not using Qt Designer nor the "auto-connection" feature. Here is my code snippet :

#include <iostream>
#include <QWidget>
#include <QMenuBar>

class MyWidget : public QWidget
{
        Q_OBJECT
        public:
                MyWidget(QWidget *parent = 0) : QWidget(parent)
                {
                        QMenuBar *menu = new QMenuBar(this);
                        menu->addAction("Click here");
                        menu->addAction("Or here");
                        connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(handleAction(QAction*)));
                }

        public slots:
                void handleAction(QAction *action)
                {
                        std::cout << "Triggered" << std::endl;
                }

};

And the main function :

#include "main.h"
#include <QApplication>

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    MyWidget w;
    w.show();

    return app.exec();
}

If you compile this (with the MOC file), you'll see that clicking on "Click here" will print "Triggered" once, and "Or here" twice. I don't understand why.

What am I doing wrong ?

Distefano answered 6/5, 2012 at 19:50 Comment(5)
Sorry i did not compile your code and am not a qt wizard. But i looked over the example from nokia's qt pages ( qt-project.org/doc/qt-4.8/mainwindows-menus.html ) and it seems to me that they connect the triggered signal to some slot in a different way: while you connect SIGNAL(triggered(QAction*)) they connect SIGNAL(triggered()). Can't tell if it makes a difference but this is a comment and not an answer :-)Trauner
@Matthias: they connect the actions to the slots directly in those examples, pintoch is connection QMenuBar's signal, which is supposed to work as he intends it to. (Creating & connecting the actions directly would be a workaround, but not nice - he/she would need more slots or a signal mapper...)Heuer
It's unclear what you're trying to do here, but I suspect it's something different that you think - This won't actually even produce a menubar on OSX. You should be creating QMenu objects and adding them to the QMenuBar. I suspect it's just sending the entire list of actions to your slot.Bellbird
@BrianRoach: it's not. The same action is triggered twice on the second menu (on Linux/Qt 4.7 anyway). Same sender too.Heuer
Related to pyQt: radioButton.isChecked() is executed twiceIndeterminate
R
2

I get the same incorrect result as you on Windows 7 x64 using Qt 4.8.1. This certainly seems like a bug.

There was a bug reported and fixed for what appears to be the same behavior on Mac OS X. Although it has been closed, there is a single comment on it that they observed this problem on Windows 7.

I think filing a new bug report would be a good idea.

Reshape answered 6/5, 2012 at 21:3 Comment(1)
I create a new issue on the bug tracker. Thanks for your confirmation.Distefano
A
5

Use Qt::UniqueConnection to solve:

connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(handleAction(QAction*)), Qt::UniqueConnection);

http://doc.qt.io/qt-4.8/qt.html#ConnectionType-enum

Ahern answered 30/7, 2014 at 18:2 Comment(0)
R
2

I get the same incorrect result as you on Windows 7 x64 using Qt 4.8.1. This certainly seems like a bug.

There was a bug reported and fixed for what appears to be the same behavior on Mac OS X. Although it has been closed, there is a single comment on it that they observed this problem on Windows 7.

I think filing a new bug report would be a good idea.

Reshape answered 6/5, 2012 at 21:3 Comment(1)
I create a new issue on the bug tracker. Thanks for your confirmation.Distefano

© 2022 - 2024 — McMap. All rights reserved.