Как соединить в 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 на основе вышеуказанной технологии.