Как соединить в Qt сигнал и слот в динамически добавленных кнопках, чтобы попасть в индекс слота добавленной кнопки?

У меня есть список с указателями QPushButton:

QList<QPushButton*> listButtons;

В этом коде я добавляю динамически кнопки

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

Как я могу также сохранить индекс каждой кнопки, чтобы я мог отслеживать, какую кнопку пользователь нажал, потому что каждая кнопка должна отменить определенную задачу.

Я использую C++98, поэтому я не могу использовать функцию лямбда

3 ответа

Решение

Вы должны использовать sender() функция в вашем слоте. как это:

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

Смотрите полный пример, который я сделал для вас. ( Скриншот)

Файл.cpp:

#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 файл:

#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

Больше информации:

функция sender() возвращает указатель на объект, который отправил сигнал, если он вызывается в слоте, активированном сигналом; в противном случае он возвращает 0. Указатель действителен только во время выполнения слота, который вызывает эту функцию из контекста потока этого объекта.

Предупреждение: эта функция нарушает объектно-ориентированный принцип модульности. Однако получение доступа к отправителю может быть полезно, когда множество сигналов подключено к одному слоту.

Простой способ сделать это - захватить индекс (или все, что вы хотите передать в слот) в лямбду, подключенную к сигналу, который затем передает его в слот.

Общая идея такова:

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); });

Вы можете обратиться к этой странице https://doc.qt.io/archives/qq/qq16-dynamicqobject.html.

Или ищет реализацию QWebChannel. Он сопоставляет сигнал Qt со средой v8 на основе вышеуказанной технологии.

Другие вопросы по тегам