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

时间:2014-01-16 00:03:23

标签: c++ qt qt5 qobject 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 ..\Proj1\fieldwindow.cpp:41
QObject::connect:  (receiver name: 'fieldWindow')

我在互联网上读到了一些我应该说handleButton(int, int);但我应该如何传递参数的内容?

1 个答案:

答案 0 :(得分:11)

可悲的是,Qt信号槽连接不接受在调用信号时传递给槽的任何参数。这仅在信号本身提供这些参数时有效,但您无法在connect语句中添加它们。

但是你不是唯一一个想要这样做的人,所以在Qt中有一个类几乎你想做什么:QSignalMapper。此类的实例可用作信号槽连接的“代理”:将(多个)按钮连接到此类的插槽,并将此类的信号连接到目标插槽。然后,对于每个“发送者”实例(在您的情况下按钮),您可以告诉该类要添加到被调用插槽的值。例如:

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语法,也可以使用标准库中的一些帮助器来组成一个functor而不是lambda,或者你可以编写自己的functor类,但我个人觉得lambda非常易读