Qt 5将带有参数的插槽分配给QPushButton



我在C++上有一个Qt应用程序,我想为QPushButton分配一个插槽。但我想传递一些参数,因为我有不止一个QPushButton在做类似的事情,所以我想要一个函数,但其中有一个参数,但Qt一直告诉我,没有这样的槽。有人能告诉我为什么以及该怎么做吗?

提前感谢

在.h文件中,我有:(一开始是私有的,但我在搜索问题时更改了它)

public slots:
void handleButton(int row, int col);

然后在.cpp:中

void fieldWindow::handleButton(int row, int col){
cout << row << " " << col << endl;
}

在同一个.cpp:中

connect(this->buttonsField[i][j], SIGNAL(released()), this, SLOT(handleButton(i,j)));

这是在两个嵌套循环中完成的,因此ij被很好地定义。

我的错误是:

QObject::connect: No such slot fieldWindow::handleButton(i,j) in ..Proj1fieldwindow.cpp:41
QObject::connect:  (receiver name: 'fieldWindow')

我在网上读到一些我应该说handleButton(int, int);的东西,但那我该如何通过这些争论呢?

遗憾的是,Qt信号插槽连接在调用信号时不接受任何要传递到插槽的参数。只有当信号本身提供了这些参数,但不能将它们添加到connect语句中时,这才有效。

但你并不是唯一想这样做的人,所以在Qt中有一个类可以几乎满足你的要求:QSignalMapper。该类的一个实例可以用作信号插槽连接的"代理":将(多个)按钮连接到该类的插槽,并将该类的信号连接到目标插槽。然后,对于每个"sender"实例(在您的例子中是按钮),您可以告诉类要向被调用的slot添加哪个值。示例:

QPushButton * button1 = ...;
QPushButton * button2 = ...;
QSignalMapper mapper;
connect(button1, SIGNAL(released()), &mapper, SLOT(map()));
mapper.setMapping(button1, 42); // Number to be passed in the slot
connect(button2, SIGNAL(released()), &mapper, SLOT(map()));
mapper.setMapping(button2, 1337); // Number to be passed in the slot
connect(&mapper, SIGNAL(mapped(int)), this, SLOT(handleButton(int)));

遗憾的是,正如您所看到的,这个类只能处理单个参数。对于您的情况,您应该选择一种不同的方法(我已经解释了上面的内容,以防您再次遇到类似的问题,但只有一个int参数)。

适合您问题的替代方案是依赖插槽中的sender()。记住你在这样的数据结构中的映射

QMap<QObject*,int> rows;
QMap<QObject*,int> cols;

并访问插槽中不需要任何参数的

void fieldWindow::handleButton(){
int row = rows[sender()];
int col = cols[sender()];
cout << row << " " << col << endl;
}

当然,在初始化UI时,您需要在这些映射中放入适当的值。或者,您可以在现有的数组buttonsField中搜索您的按钮。

自Qt5和C++11以来,还存在另一种方法:您可以处理lambda函数中的信号,而不是插槽。这看起来像这样(信号使用新语法命名):

connect(this->buttonsField[i][j], &QPushButton::released, [=]{
handleButton(i, j);
});

如果您不喜欢lambda语法,也可以使用标准库中的一些助手来组成函子而不是lambda,或者您可以编写自己的函子类,但我个人认为lambda非常可读。

最新更新