How to get which QradioButton invoke the SLOT

2019-07-18 07:49发布

问题:

I create several QradioButton and connect to the same SLOT. In the slot, I want to know which QradioButton invoke the slot and do the related action. I found there is a way by using qobject_cast and QObject::sender(), but it seems not work. Here is the code:

header file:

class dialoginput : public QDialog
{
    Q_OBJECT

public:
    dialoginput(QWidget *parent = 0);
    QRadioButton *radio1;
    QRadioButton *radio2;
    QRadioButton *radio3;
private slots:
    void setText_2();
private:
    QLabel *label_0_0;
    QLabel *label_1;
};

main file:

dialoginput::dialoginput(QWidget *parent): QDialog(parent){

    label_0_0 = new QLabel("label_1:");
    label_1 = new QLabel;  

    QWidget *window = new QWidget;
    QVBoxLayout *windowLayout = new QVBoxLayout;

    QGroupBox *box = new QGroupBox("Display Type");
    radio1 = new QRadioButton("3");
    radio2 = new QRadioButton("5");
    radio3 = new QRadioButton("9");
    QVBoxLayout *radioLayout = new QVBoxLayout;

    connect(radio1,SIGNAL(clicked()),this,SLOT(setText_2()));
    connect(radio2,SIGNAL(clicked()),this,SLOT(setText_2()));
    connect(radio3,SIGNAL(clicked()),this,SLOT(setText_2()));

    radioLayout->addWidget(radio1);
    radioLayout->addWidget(radio2);
    radioLayout->addWidget(radio3);

    box->setLayout(radioLayout);

    windowLayout->addWidget(box);
    windowLayout->addWidget(label_0_0);
    windowLayout->addWidget(label_1);

    window->setLayout(windowLayout);
    window->show();

}
void dialoginput::setText_2(){

    QObject *object = QObject::sender();
    QRadioButton* pbtn = qobject_cast<QRadioButton*>(object);
    QString name = pbtn->objectName();

    label_1->setText(name);

    if(!QString::compare(name, "3")){       
    }
    else if(!QString::compare(name, "5")){
    }
    else if(!QString::compare(name, "9")){
    }

}
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    dialoginput *input = new dialoginput();

    return a.exec();
}

回答1:

You could create separate wrapper slots for each radio button, which then passes the information to the function you want to call. Something like this: -

class dialoginput : public QDialog
{
    Q_OBJECT

public:
    QRadioButton *radio1;
    QRadioButton *radio2;
    QRadioButton *radio3;

private slots:
   void Radio1Selected() { setText_2(1); }
   void Radio2Selected() { setText_2(2); }
   void Radio3Selected() { setText_2(3); }

private:
   void setText_2(int id);

};

Then connect each radio button: -

connect(radio1,SIGNAL(clicked()),this,SLOT(Radio1Selected()));
connect(radio2,SIGNAL(clicked()),this,SLOT(Radio2Selected()));
connect(radio3,SIGNAL(clicked()),this,SLOT(Radio3Selected()));

Now when setText_2 is called, the id will represent the selected radio button.



回答2:

Even though using the sender() method solves your problem, i do not recommend using it. The problem is, signals and slots are designed to seperate the emitter and the receiver. A receiver does not need to know which objects, even what types of objects can trigger its slot. When you use sender(), you are relying on the fact that the receiver has knowledge of all of the objects that triggers its slot. What if this changes in the future?

You should take a look at QSignalMapper, it is designed specifically for this kind of needs. There are good examples about it in the docs.



回答3:

You are getting sender Object correctly on setText_2(), But you are not setting objectName property of radio1, radio2 and radio3. Please use "setObjectName( )" API.



回答4:

write single argument custom signal for radiobuttons and then emit it .catch that argument in slot.check for corresponding radio button



回答5:

You could also create a QButtonGroup and use lambda expression (c++11)

class dialoginput : public QDialog
{
    Q_OBJECT

public:

private:
   void setText_2(int id);
   QRadioButton *radio1;
   QRadioButton *radio2;
   QRadioButton *radio3;
   QButtonGroup _btnGroup; 
};

After add the 3 QRadioButton to the QButtonGroup

_btnGroup.addButton(radio1, 1);
_btnGroup.addButton(radio2, 2);
_btnGroup.addButton(radio3, 3);

connect(&_btnGroup, static_cast<void(QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), [=](int id){
            setText_2(id);});


标签: c++ qt qt4