目录
假设发送的信号带参数
信号是可以重载的,我用同一个函数名称,一个带参数,一个不带参数,在点击“切换到主窗口”按钮的时候,同时发射这两个信号。
subwidget.h
- #ifndef SUBWIDGET_H
- #define SUBWIDGET_H
-
- #include
- #include
-
- class Subwidget : public QWidget
- {
- Q_OBJECT
- public:
- explicit Subwidget(QWidget *parent = nullptr);
- void sendsignal();
- signals:
- /* 信号必须有signals关键字来声明
- * 信号没有返回值,但可以有参数
- * 信号就是函数的声明,只需声明,无需定义
- * 使用 emit mysignal();
- * 信号可以重载,取同一个名字,只是参数不同而已
- */
- void mysignal();
- // void mysignal(int a, QString str); // × 声明函数是不用写形参名,只写类型
- void mysignal(int, QString); // ▲ 新增的代码
-
- public slots:
-
- private:
- QPushButton b;
- };
-
- #endif // SUBWIDGET_H
subwidget.cpp
- #include "subwidget.h"
-
- Subwidget::Subwidget(QWidget *parent) : QWidget(parent)
- {
- this->setWindowTitle("子窗口");
- b.setParent(this);
- b.setText("切换到主窗口");
-
- connect(&b,&QPushButton::clicked,this,&Subwidget::sendsignal);
- resize(400,300);
- }
-
- void Subwidget::sendsignal(){
- emit mysignal();
- emit mysignal(250,"我是子窗口"); // 新增的代码
- }
信号函数与槽函数的参数和返回值要一致。因此,接收信号的主窗口,需要添加一个带参数的槽函数。
另外,由于mysignal是给重载的信号,存在二义性,所以不能延用原来的方式,需要定义函数指针。
mywidget.h
- #ifndef MYWIDGET_H
- #define MYWIDGET_H
-
- #include
- #include
- #include "subwidget.h"
-
- class MyWidget : public QWidget
- {
- Q_OBJECT
-
- public:
- MyWidget(QWidget *parent = nullptr);
- ~MyWidget();
- void changewin();
- void dealsub();
- void dealslot(int,QString); // ▲ 新增带参数的槽函数的声明
- private:
- QPushButton mainwinb;
- Subwidget subwin;
- };
- #endif // MYWIDGET_H
mywidget.cpp
- #include "mywidget.h"
- #include
- MyWidget::MyWidget(QWidget *parent)
- : QWidget(parent)
- {
- mainwinb.setParent(this);
- mainwinb.setText("切换到子窗口");
- mainwinb.move(100,100);
- this->setWindowTitle("主窗口");
-
- connect(&mainwinb,&QPushButton::released,this,&MyWidget::changewin);
-
-
- // connect(&subwin,&Subwidget::mysignal,this,&MyWidget::dealsub);
- // mysignal 是 Subwidget这个类自定义的信号
- // dealsub 是 MyWidget这个类自定义的槽函数
-
- // ▲ 注意!!!!
- // 由于mysignal是重载的,所以存在二义性,在connect函数中不能在使用原来的方式
- // 因此需要定义函数指针
-
- // 没参数的mysignal
- void (Subwidget::*mysignal_without_para)() = &Subwidget::mysignal;
- connect(&subwin,mysignal_without_para,this,&MyWidget::dealsub);
-
- // 有参数的mysignal
- void (Subwidget::*mysignal_with_para)(int, QString) = &Subwidget::mysignal;
- connect(&subwin,mysignal_with_para,this,&MyWidget::dealslot); // ▲ 新增的槽函数不是重载的,不存在二义性,所以可以延用原来的调用方式
-
- resize(400,300);
- }
-
- MyWidget::~MyWidget()
- {
- }
-
- void MyWidget::changewin(){
- // 子窗口显示
- subwin.show();
- this->hide();
-
- }
-
- void MyWidget::dealsub(){
- // 子窗口显示
- subwin.hide();
- this->show();
-
- }
-
- // ▲ 新增带参数的槽函数定义
- void MyWidget::dealslot(int a, QString str){
-
- qDebug() << a << str;
- }
运行结果
Lambda表达式,是C++11增加的新特性。在Qt配合信号一起使用,非常方便
要使用Lambda表达式,项目文件需要添加:CONFIG += C++11。
版本新点的Qt生成项目时自动会生成
Lambda表达式,可以理解成:匿名函数对象
新添加一个按钮来说明Lambda表达式的好处
mywidget.cpp
- #include "mywidget.h"
- #include
- MyWidget::MyWidget(QWidget *parent)
- : QWidget(parent)
- {
- mainwinb.setParent(this);
- mainwinb.setText("切换到子窗口");
- mainwinb.move(100,100);
- this->setWindowTitle("主窗口");
-
- connect(&mainwinb,&QPushButton::released,this,&MyWidget::changewin);
-
-
- // connect(&subwin,&Subwidget::mysignal,this,&MyWidget::dealsub);
- // mysignal 是 Subwidget这个类自定义的信号
- // dealsub 是 MyWidget这个类自定义的槽函数
-
- // 由于mysignal是重载的,所以存在二义性,在connect函数中不能在使用原来的方式
- // 因此需要定义函数指针
-
- // 没参数的mysignal
- void (Subwidget::*mysignal_without_para)() = &Subwidget::mysignal;
- connect(&subwin,mysignal_without_para,this,&MyWidget::dealsub);
-
- // 有参数的mysignal
- void (Subwidget::*mysignal_with_para)(int, QString) = &Subwidget::mysignal;
- connect(&subwin,mysignal_with_para,this,&MyWidget::dealslot);
-
- // ▲ 新增代码👇
-
- QPushButton *b = new QPushButton(this);
- b->setText("LambdaTest");
- b->move(100,150);
- connect(b,&QPushButton::clicked, // F1 clicked, 它是带参数的,但没有重载,不需要定义函数指针、
- // void QAbstractButton::clicked(bool checked = false), 参数是一个,bool类型
- // ()函数的参数, 和信号的传参保持一致就行了
- // {}函数体
- // []是什么作用呢?
- // 它的作用是把外部变量传进来,可以[b],可以[a,b]但参数多了,就不好写了。所以用[=]
- // [=] : 把外部所有局部变量、类中所有成员以值传递方式,局限性,read-only,无法修改。
- // : 如果要修改,就是这么写[=]() mutable
- // [this]:类中所有成员以值传递方式
- // [&] : 把外部所有局部变量,引用符号,最好少用。 就用[=],可能多消耗点资源,但是程序稳定
- [=](bool isChecked) mutable
- {
- qDebug() << isChecked;
-
- }
- );
-
- // 用lambda表达式,不用去.h声明一个新的槽函数, 也不用在.cpp定义这个新的槽函数, 关于参数的问题,直接放在()里面就可以了。 用起来非常方便。
- resize(400,300);
- }
-
- MyWidget::~MyWidget()
- {
- }
-
- void MyWidget::changewin(){
- // 子窗口显示
- subwin.show();
- this->hide();
-
- }
-
- void MyWidget::dealsub(){
- // 子窗口显示
- subwin.hide();
- this->show();
-
- }
-
- void MyWidget::dealslot(int a, QString str){
-
- qDebug() << a << str;
- }
运行结果
类似内容参考链接:QT5中Lamda表达式及Lamda表达式在槽函数中的使用_槽函数lambda表达式-CSDN博客
感谢您的阅读,欢迎留言讨论、收藏、点赞、分享。