如何在动态添加的按钮中连接 Qt 信号和插槽以获取添加按钮的插槽索引?
How to connect in Qt signal and slot in dynamically added buttons to get in slot index of added button?
我有带指针的列表 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,所以不能用Lambda函数
一个简单的方法是在连接到信号的 lambda 中捕获索引(或任何您想传递给插槽的内容),然后将其传递给插槽。
大致思路是这样的:
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); });
您必须在插槽中使用 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() 函数 returns 指向发送信号的对象的指针,如果在由信号激活的槽中调用;否则它 returns 0。指针仅在从该对象的线程上下文调用该函数的槽执行期间有效。
警告:该函数违反了面向对象的模块化原则。但是,当许多信号连接到单个插槽时,访问发送器可能会很有用。
你可以参考这个页面https://doc.qt.io/archives/qq/qq16-dynamicqobject.html。
或者查找QWebChannel的实现。它基于上述技术将Qt信号映射到v8环境。
我有带指针的列表 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,所以不能用Lambda函数
一个简单的方法是在连接到信号的 lambda 中捕获索引(或任何您想传递给插槽的内容),然后将其传递给插槽。
大致思路是这样的:
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); });
您必须在插槽中使用 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() 函数 returns 指向发送信号的对象的指针,如果在由信号激活的槽中调用;否则它 returns 0。指针仅在从该对象的线程上下文调用该函数的槽执行期间有效。
警告:该函数违反了面向对象的模块化原则。但是,当许多信号连接到单个插槽时,访问发送器可能会很有用。
你可以参考这个页面https://doc.qt.io/archives/qq/qq16-dynamicqobject.html。
或者查找QWebChannel的实现。它基于上述技术将Qt信号映射到v8环境。