Dasd
Dasd

Reputation: 111

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

Upvotes: 1

Views: 5115

Answers (3)

Kohill Yang
Kohill Yang

Reputation: 141

You can refer to this page https://doc.qt.io/archives/qq/qq16-dynamicqobject.html.

Or looks up the implementation of QWebChannel. It maps Qt signal to the v8 environment, based on the above technology.

Upvotes: 0

Farhad
Farhad

Reputation: 4181

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.

Upvotes: 2

Jesper Juhl
Jesper Juhl

Reputation: 31465

An easy way to do that would be to capture the index (or whatever you want to pass to the slot) in a lambda connected to the signal that then pass it on to the slot.

The general idea being like so:

auto button = new QPushButton("Cancel", this);
auto index = /* code to get what you want to pass */ ;
connect(button, &QPushButton::clicked,
    this, [index, this](bool){ this->handleButton(index); });

Upvotes: 0

Related Questions