Search code examples
c++qtbuttonqt-signalsslot

How to connect in Qt signal and slot in dynamically added buttons to get in slot index of added button?


I have list with pointers QPushButton:

QList<QPushButton*> listButtons;

In this code I am adding dynamically buttons

listButtons.push_back(new QPushButton("Cancel", this)); 
connect(listButtons.last(), SIGNAL (clicked(listButtons.size)), this, SLOT(handleButton(int))); //this doesn't work

How can I also save index of every button, so I can keep track, what button user clicked, because every button has to cancel specific task.

I use C++98, so I can not use Lambda function


Solution

  • You have to use sender() function in your slot. like this:

    void MainWindow::buttonClicked()
    {
        QObject *senderObj = sender(); // This will give Sender object
        QString senderObjName = senderObj->objectName();
        qDebug()<< "Button: " << senderObjName;
    }
    

    See a complete example that i made for you: Screenshot

    .cpp file:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        for(int i =0; i<10; i++)
        {
            listButtons.push_back(createNewButton());
            connect(listButtons[i], &QPushButton::clicked, this, &MainWindow::buttonClicked);
            QString text = listButtons[i]->text();
    
            ui->widget->layout()->addWidget(listButtons[i]);
        }
    }
    
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    QPushButton* MainWindow::createNewButton()
    {
        QPushButton* button = new QPushButton("ButtonText");
        button->setObjectName("ButtonName");
        return button;
    }
    
    void MainWindow::buttonClicked()
    {
        QObject *senderObj = sender(); // This will give Sender object
        QString senderObjName = senderObj->objectName();
        qDebug()<< "Button: " << senderObjName;
    }
    

    .h file:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QDebug>
    #include <QPushButton>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
        QList<QPushButton*> listButtons;
    
        QPushButton *createNewButton();
        void buttonClicked();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    

    More info:

    sender() function returns a pointer to the object that sent the signal, if called in a slot activated by a signal; otherwise it returns 0. The pointer is valid only during the execution of the slot that calls this function from this object's thread context.

    Warning: This function violates the object-oriented principle of modularity. However, getting access to the sender might be useful when many signals are connected to a single slot.