0

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.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Theodore Tang
  • 831
  • 2
  • 21
  • 42
  • First, stop using the old signal slot syntax and switch to the [new syntax](https://wiki.qt.io/New_Signal_Slot_Syntax). This raises errors at compile time instead of at run time, which makes them far easier to spot. Second, I'm not sure there's enough code here to say for certain what's going wrong. Third, your `MyButton` class contains a vector of pointers to more `MyButton` objects -- while that may not be related to the issue, it's certainly a strange way to program a GUI. – MrEricSir Nov 25 '17 at 03:20
  • @MrEricSir But I think I provided all the code in that small program to test if the right click event works. I don't know what else code I can provide because that's all of them. And what is a better way to make more button objects? – Theodore Tang Nov 25 '17 at 03:26
  • The problem is that you have created MyButton mButtons; within a function. The variables created in a function only exist during the function and after they are eliminated, I recommend you to make mButtons a member of the class. – eyllanesc Nov 25 '17 at 03:34
  • @eyllanesc Before I tested it, I make mButtons a member of the class, but for the brevity of my question, I just put mButton object to there. So I think that's not where the problem is. – Theodore Tang Nov 25 '17 at 03:39
  • Why do you create a QVector buttons inside MyButton? – – eyllanesc Nov 25 '17 at 03:40
  • I agree with @eyllanesc, `btnRightClicked` may be triggered as a member of the buttons, not of `mButtons` which you connected to `mainwindow` – Shihe Zhang Nov 25 '17 at 03:44
  • @eyllanesc I just want a vector to contain many buttons, I don't really get the difference of creating this vector to different class, so I thought that would just do the same thing wherever I create that. So I created that in MyButton class. – Theodore Tang Nov 25 '17 at 03:44
  • @TheodoreTang which is totally not.Better to make button vector in mainwindow – Shihe Zhang Nov 25 '17 at 03:45
  • How many buttons are you visually seeing in your GUI? – eyllanesc Nov 25 '17 at 03:45
  • @eyllanesc I resized that to 5, so I saw 5 buttons there. – Theodore Tang Nov 25 '17 at 03:46
  • I think that the button that you have connected is not visible since it does not have a parent, besides you are creating many buttons QVector, it seems an infinite loop. – eyllanesc Nov 25 '17 at 03:47
  • I recommend creating QVector inside MainWindow as a member of the class, then add the buttons, and make the connection inside the loop. – eyllanesc Nov 25 '17 at 03:51

1 Answers1

1

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

eyllanesc
  • 235,170
  • 19
  • 170
  • 241