10

我在 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)));

这是在两个嵌套循环中完成的,因此i定义 j明确。

我的错误是:

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

我在互联网上读到一些我应该说的东西,handleButton(int, int);但是我应该如何传递论点?

4

1 回答 1

15

可悲的是,当调用信号时,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 语法,也可以使用标准库中的一些帮助程序来组成函子而不是 lambda,或者您可以编写自己的函子类,但我个人认为 lambda 非常易读。

于 2014-01-16T00:27:40.043 回答