如何将参数从构造函数转移到槽中
How to transfer parameter from constructor into slot?
我正在用Qt做一个小练习,据我所知,插槽save_clicked
只带来参数类型。那么我如何将userid
转移到MyClass.cpp
文件中的save_clicked
插槽中进行下面的处理呢?
MyClass.h
class MyClass : public QWidget
{
Q_OBJECT
public:
MyClass(QString userid, QString lastname, QString firstname, QWidget *parent = 0);
~MyClass();
public slots:
void save_clicked(QString userid);
private:
Ui::MyClass ui;
};
#endif // MYCLASS_H
MyClass.cpp
MyClass::MyClass(QString userid, QString lastname, QString firstname, QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
...........
...........
connect(ui.save, SIGNAL(clicked()), this, SLOT(save_clicked(QString)));
}
void MyClass::save_clicked(QString userid)
{
// process userid here
}
首先,已经有人建议不需要将userid
传递给插槽。将其声明为MyClass
的成员并在MyClass::save_clicked()
中简单地使用它就可以了。
如果你仍然想知道如何处理你需要传递参数到信号不提供的插槽的情况,有多种方法可以实现这一点,它们取决于你正在使用的Qt版本。
一般来说,Qt5文档中的下列内容适用于Qt5和Qt4:
信号的签名必须与接收方的签名匹配槽。(事实上,一个插槽的签名可能比它发出的信号短接收,因为它可以忽略额外的参数)
考虑到这个事实,你必须要么使用信号提供的东西(或者不使用——取决于你是否需要它),要么从其他地方获取数据。slot
只是一个常规函数(在Qt4中稍微受限,但在Qt5中,您基本上可以连接任何可调用的信号),并且在该函数中,您可以从设计允许的任何地方获得所需的数据。成员变量方法很常见,但是您也可以调用任何其他对象的另一个成员函数、自由函数或简单地计算槽内所需的任何内容。
注意:处理信号并不一定意味着你需要任何数据-这是常见的,是的,但你也可以做一些简单的事情,如带一些硬编码文本的QMessageBox
或简单地清除一些文本编辑(想想像按钮做Clear Console
)或执行一些外部进程或你有什么。
如果您需要您的插槽在调用时实际接收数据,您有多个选项:
- 使用信号提供的所有内容或子集
- 使用QSignalMapper建立一个映射,对您的槽参数进行有限的控制
- 使用更高级的方法,使用一个函数对象来存储你需要的东西,也就是说,要么是一个你直接提供的函子,要么是一个lambda或一个从
std::bind
返回的函数对象。
对于后者的工作,您需要C++11
支持,但到目前为止,这应该不是问题。
在上面的例子中,你可以用最基本的方法做这样的事情(未经测试的 -请报告编译错误,以便我可以修复答案):
MyClass::MyClass(QString userid, QString lastname, QString firstname, QWidget *parent)
: QWidget(parent)
{
...
connect (
ui.save,
&QPushButton::clicked,
std::bind (&MyClass::save_clicked, this, userid)
);
...
}
在上面的例子中,当ui.save
发出clicked()
时,将调用std::bind
返回的函数调用包装器,该包装器将在MyClass
的this
实例上调用MyClass::save_clicked
,并将userid
传递给save_clicked()
。
以上基本上是你最初想要实现的。然而,这只是冰山一角。您可以更进一步,例如,绑定任何您想要的 。
例如,假设您连接到按钮toggled(bool checked)
提供的另一个信号。如果您希望同时接收作为bool 和的检查状态(您自己提供的一些参数,例如userid
),则可以使用适当的占位符将上述调用扩展到std::bind
:
connect (
ui.save,
&QPushButton::toggled,
std::bind (&MyClass::save_clicked, this, _1, userid /*, ... more args here*/)
);
现在您将拥有save_clicked()
的以下签名:
save_clicked(bool, QString);
在ui.save
发出toggled(bool)
时,std::bind
返回的函数调用包装器将调用MyClass::save_clicked
,并将bool值替换为_1
和(作为std::bind
的第四个参数提供的QString
)。
使用变量比使用信号/插槽更好。这是一门课的目标。添加如下内容:
private:
QString userId;
并在构造函数中添加:
MyClass::MyClass(QString userid, QString lastname, QString firstname, QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
this.userId=userid;
}
就像这样,你可以随心所欲地在类的任何地方使用userId。
编辑:添加你的。h
private slots:
void on_saveButton_clicked();
和。cpp
void MyClass::on_saveButton_clicked()
{
// you can use userId here
}
如果你使用Qt Creator,这些功能可以自动添加到UI设计界面
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 具有默认模板类型的默认构造函数的类型推导
- 复制构造函数以转移unique_ptr的所有权
- 具有责任转移的转换构造函数
- 如何将参数从构造函数转移到槽中