我正在尝试将按钮连接到某个功能,因此当我按下该按钮时,将使用特定参数调用该功能。我有
class FieldGridWidget : public QWidget
{
Q_OBJECT
public:
FieldGridWidget(QWidget *parent=0);
~FieldGridWidget();
public slots:
void resizeGrid(int n);
private:
QGridLayout* _gridLayout;
QVector<QPushButton*> _buttonGrid;
};
然后是按钮
_button3 = new QPushButton("3x3", this);
并且我正在尝试连接它,因此如果单击,则使用参数3调用resizeGrid
函数。为此,我正在尝试
connect(_button3, SIGNAL(clicked()), _fieldGrid, SLOT(resizeGrid(3))); //this is line 21
但是我得到了运行时错误
QObject::connect: No such slot FieldGridWidget::resizeGrid(3) in ../filename.cpp:21
我做错了什么?或者,如果我按下按钮,我怎么能这样做,resizeGrid(3)
被调用?
谢谢!
答案 0 :(得分:6)
您无法直接将值传递到Qt中的插槽,如SLOT(resizeGrid(3))
中所示。 SLOT
的参数应该只是方法的签名(resizeGrid()
)。
如何向插槽添加参数有两种方法。关于how to pass arguments to a slot的这个问题显示了一些解决方案,在此重复。 (去投票吧!)
而不是连接广告位,请连接到仿函数,如Kuba Ober中的this answer所述:
connect(action1, &QAction::triggered, this, [this]{ onStepIncreased(1); });
connect(action5, &QAction::triggered, this, [this]{ onStepIncreased(5); });
connect(action10, &QAction::triggered, this, [this]{ onStepIncreased(10); });
connect(action25, &QAction::triggered, this, [this]{ onStepIncreased(25); });
connect(action50, &QAction::triggered, this, [this]{ onStepIncreased(50); });
您可以使用QSignalMapper
执行所需内容,如TonyK中this answer所述:
QSignalMapper* signalMapper = new QSignalMapper (this) ;
connect (action1, SIGNAL(triggered()), signalMapper, SLOT(map())) ;
connect (action5, SIGNAL(triggered()), signalMapper, SLOT(map())) ;
connect (action10, SIGNAL(triggered()), signalMapper, SLOT(map())) ;
connect (action25, SIGNAL(triggered()), signalMapper, SLOT(map())) ;
connect (action50, SIGNAL(triggered()), signalMapper, SLOT(map())) ;
signalMapper -> setMapping (action1, 1) ;
signalMapper -> setMapping (action5, 5) ;
signalMapper -> setMapping (action10, 10) ;
signalMapper -> setMapping (action25, 25) ;
signalMapper -> setMapping (action50, 50) ;
connect (signalMapper, SIGNAL(mapped(int)), this, SLOT(resizeGrid(int))) ;
答案 1 :(得分:2)
信号和插槽的签名必须匹配 - 如果不完全,则至少部分匹配。
例如,您可以将signal(int, float)
与slot(int)
相关联,但无法将signal(void)
与slot(int)
相关联。
如果您使用的是Qt 5,那么在连接语法中指定一个槽参数是“有可能的”:
connect(_button3, &QPushButton::clicked, [=](){ _fieldGrid->resizeGrid(3); });
当然,你可以在这种特殊情况下使用信号映射器,但它是一个相当笨拙的解决方案 - 额外的冗长,仅限于一个int,string,widget或QObject
参数。对于lambdas,这些限制不适用。
答案 2 :(得分:1)
clicked()
和resizeGrid()
签名应该相同,因此您可以创建函数,例如resizeGridForButton()
,其中resizeGrid(3)
将被执行,或者更改{{1签名并将resizeGrid()
转移到其中。
并且不可能(在 vsimkus 的答案中的例子)在int n = 3
中发送参数。您也可以通过信号参数在connect(...)
部分发送它们。
Here是关于广告位和信号的好文章。