c++qtqt5qt-signalsqt-slot

Connecting signal and slot not working Qt


I mostly copied, pasted the code from Here, and implemented them in a small new program like this:
In mybutton.h:

class MyButton : public QPushButton
{
 Q_OBJECT

public:
    MyButton(QWidget *parent = Q_NULLPTR);

    QVector<MyButton*> buttons;

private slots:
    void mousePressEvent(QMouseEvent *e) {
        if(e->button()==Qt::RightButton) {
            emit btnRightClicked();
            qDebug() << "Emitted";
        }
    }

signals:
    void btnRightClicked();
};

And in mainwindow.cpp:

MyButton mButtons;

QWidget *mWidget = new QWidget(this);
QGridLayout *gLayout = new QGridLayout(mWidget);

mButtons.buttons.resize(5);
for(int i = 0; i < 5; i++) {
    mButtons.buttons[i] = new MyButton(mWidget);
    gLayout->addWidget(mButtons.buttons[i], 0, i);
}

mWidget->setLayout(gLayout);
setCentralWidget(mWidget);

connect(&mButtons, SIGNAL(btnRightClicked()), this, SLOT(onRightClicked()));

And the onRightClicked slot is like this:

void MainWindow::onRightClicked() 
{
    qDebug() << "clicked";
}

But the debug out come only has this: Emitted.
I do not know where is wrong here. So how can I solve the problem?

Thanks.


Solution

  • It's just what I was thinking, you have created a called mButtons, and that you have connected to your signal, but that button has no parent is not visualized since it is deleted when you finish executing the constructor, that does not mean that the pointers that you save in QVector are deleted from memory but they subsist and emit the signals, but these are not connected to any slot.

    What you have to do is create a button that only emits the signal:

    #ifndef MYBUTTON_H
    #define MYBUTTON_H
    
    #include <QMouseEvent>
    #include <QPushButton>
    #include <QDebug>
    
    class MyButton : public QPushButton
    {
     Q_OBJECT
    
    public:
        MyButton(QWidget *parent = Q_NULLPTR):QPushButton(parent){
    
        }
    
    protected:
        void mousePressEvent(QMouseEvent *e) {
            if(e->button()==Qt::RightButton) {
                emit btnRightClicked();
                qDebug() << "Emitted";
            }
        }
    
    signals:
        void btnRightClicked();
    };
    #endif // MYBUTTON_H
    

    Then you create a container of buttons, and in the loop you create the buttons and connect it:

    *.h

    private slots:
        void onRightClicked();
    
    private:
        QVector<MyButton *> mButtons;
    };
    

    *.cpp

    QWidget *mWidget = new QWidget(this);
    QGridLayout *gLayout = new QGridLayout(mWidget);
    for(int i = 0; i < 5; i++) {
        MyButton *btn = new MyButton(mWidget);
        gLayout->addWidget(btn, 0, i);
        connect(btn, &MyButton::btnRightClicked, this, &MainWindow::onRightClicked);
        mButtons << btn;
    }
    
    mWidget->setLayout(gLayout);
    setCentralWidget(mWidget);
    

    You can download the example in the following link