'How to make slot for multiple QPushButtons?

From Qvector is set the number of buttons and their names (text). After cliking on the button I need to reseave text on it and display in lineEdit.

The header file:

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QWidget>
#include <QVector>
#include <QLineEdit>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private slots:   
    void Buttons(QVector<QString>&);

private:
    QVector<QPushButton*>button;
    QString mline;
    QLineEdit *line;
    QVBoxLayout *layout;
    QAction *Clicked;

};

#endif // DIALOG_H

The source file:

#include "dialog.h"

    Dialog::Dialog(QWidget *parent): QDialog(parent)
    {
        this->setFixedSize(this->minimumSize());

        line = new QLineEdit(this);

        layout = new QVBoxLayout(this);

        layout->addWidget(line);

        QVector<QString>v;
        v.append("a");
        v.append("b");
        v.append("c");
        v.append("5");
        v.append("45");
        Buttons(v);

        for(int i=0;i<button.size();i++)
            layout->addWidget(button[i]);

        setLayout(layout);
    }

    Dialog::~Dialog(){}

    void Dialog::Buttons(QVector<QString>&vec)
    {
        if(!button.isEmpty())
            button.clear();

        for(int i=0; i<vec.size();i++)
        {
            button.append(new QPushButton(this));
            button[i]->setText(vec[i]);
            button[i]->show();
        }
    }

For it I'm not using user interface (ui), and couldn't make slots for all the buttons. How can it be done?

qt


Solution 1:[1]

  1. You can use QButtonGroup to id the buttons and consolidate the signals from all the buttons to a single slot

  2. Example

     QButtonGroup  myButtongroup;   
     connect(&myButtonGroup,SIGNAL(buttonClicked(QAbstractButton*),this, SLOT(myButtonClicked (QAbstractButton*)));
      for(int i=0; i<vec.size();i++)
       {   
        QString buttonName = vec[i];
        myButtonGroup.addButton(new QPushButton(buttonName,this),i);
        //Get the button using myButtonGroup.button(i) to add to your layout
        // You can add the buttons to the layout right here to elimate one         more loop
        layout.addWidget(myButtonGroup.button(i));
        }
    
     //Slot for button clicked
     void Dialog::myButtonClicked(QAbstractButton *myButton)
     {
        line->setText(myButton->text());// Adding the button name to line edit 
     }
    
  3. For more QButtonGroup signals refer the documentation

Solution 2:[2]

You can use signal/slot in your case. The signal/slot is related to QObject. It does not matter whether you use QT Designer or not. In your code,

 for(int i=0; i<vec.size();i++)
 {
     button.append(new QPushButton(this));
     connect(button[i], SIGNAL( clicked() ), this, SLOT(OnButtonClicked()));
     button[i]->setText(vec[i]);
     button[i]->show();
 }

Solution 3:[3]

Maintain a QList of QPushButton references that you add and use "signals and slots" to register the clicked() signal of each button to a single slot. Inside the function, iterate the QList of QPushButton by comparing with QObject::sender() and identify the source.

#include <QApplication>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>


class TestWidget: public QWidget
{
    Q_OBJECT
private:
    QLabel *label;
    QVBoxLayout *mainLayout;
    QList<QPushButton*> mButtonList;
public:
    TestWidget(QWidget *parent=nullptr) : QWidget(parent)
    {
        mainLayout = new QVBoxLayout(this);
        label = new QLabel;
        mainLayout->addWidget(label);
        this->setLayout(mainLayout);
    }

    void addButton(QString buttonName)
    {
        QPushButton *button = new QPushButton(buttonName);
        QObject::connect(button, SIGNAL(clicked(bool)), this, SLOT(buttonClicked(bool)));        
        mButtonList.append(button);
        mainLayout->addWidget(button);
    }

public slots:
    void buttonClicked(bool event)
    {
        Q_UNUSED(event)
        static_cast<QPushButton*>(QObject::sender())->setFocus();
        for (int i = 0; i < mButtonList.size(); ++i)
        {
            if (mButtonList.at(i) == sender())
            {
                label->setText(QString(mButtonList.at(i)->text()));
                break;
            }
        }
    }
};

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

    TestWidget wid;
    wid.addButton("First Button");
    wid.addButton("Second Button");
    wid.addButton("Third Button");
    wid.addButton("Fourth Button");
    wid.show();

    return a.exec();
}

#include "main.moc"

The above sample code along with *.pro file is available in github

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 hyun
Solution 3 Vinu Raja Kumar C