• QT学习_02_Lambda表达式——槽函数的正确打开方式


    目录

    1 带参数的信号

    2 Lambda表达式——槽函数的正确打开方式


    1 带参数的信号

    假设发送的信号带参数

    信号是可以重载的,我用同一个函数名称,一个带参数,一个不带参数,在点击“切换到主窗口”按钮的时候,同时发射这两个信号。

    subwidget.h

    1. #ifndef SUBWIDGET_H
    2. #define SUBWIDGET_H
    3. #include
    4. #include
    5. class Subwidget : public QWidget
    6. {
    7. Q_OBJECT
    8. public:
    9. explicit Subwidget(QWidget *parent = nullptr);
    10. void sendsignal();
    11. signals:
    12. /* 信号必须有signals关键字来声明
    13. * 信号没有返回值,但可以有参数
    14. * 信号就是函数的声明,只需声明,无需定义
    15. * 使用 emit mysignal();
    16. * 信号可以重载,取同一个名字,只是参数不同而已
    17. */
    18. void mysignal();
    19. // void mysignal(int a, QString str); // × 声明函数是不用写形参名,只写类型
    20. void mysignal(int, QString); // ▲ 新增的代码
    21. public slots:
    22. private:
    23. QPushButton b;
    24. };
    25. #endif // SUBWIDGET_H

    subwidget.cpp

    1. #include "subwidget.h"
    2. Subwidget::Subwidget(QWidget *parent) : QWidget(parent)
    3. {
    4. this->setWindowTitle("子窗口");
    5. b.setParent(this);
    6. b.setText("切换到主窗口");
    7. connect(&b,&QPushButton::clicked,this,&Subwidget::sendsignal);
    8. resize(400,300);
    9. }
    10. void Subwidget::sendsignal(){
    11. emit mysignal();
    12. emit mysignal(250,"我是子窗口"); // 新增的代码
    13. }

    信号函数与槽函数的参数和返回值要一致因此,接收信号的主窗口,需要添加一个带参数的槽函数。

    另外,由于mysignal是给重载的信号,存在二义性,所以不能延用原来的方式,需要定义函数指针。

    mywidget.h

    1. #ifndef MYWIDGET_H
    2. #define MYWIDGET_H
    3. #include
    4. #include
    5. #include "subwidget.h"
    6. class MyWidget : public QWidget
    7. {
    8. Q_OBJECT
    9. public:
    10. MyWidget(QWidget *parent = nullptr);
    11. ~MyWidget();
    12. void changewin();
    13. void dealsub();
    14. void dealslot(int,QString); // ▲ 新增带参数的槽函数的声明
    15. private:
    16. QPushButton mainwinb;
    17. Subwidget subwin;
    18. };
    19. #endif // MYWIDGET_H

    mywidget.cpp

    1. #include "mywidget.h"
    2. #include
    3. MyWidget::MyWidget(QWidget *parent)
    4. : QWidget(parent)
    5. {
    6. mainwinb.setParent(this);
    7. mainwinb.setText("切换到子窗口");
    8. mainwinb.move(100,100);
    9. this->setWindowTitle("主窗口");
    10. connect(&mainwinb,&QPushButton::released,this,&MyWidget::changewin);
    11. // connect(&subwin,&Subwidget::mysignal,this,&MyWidget::dealsub);
    12. // mysignal 是 Subwidget这个类自定义的信号
    13. // dealsub 是 MyWidget这个类自定义的槽函数
    14. // ▲ 注意!!!!
    15. // 由于mysignal是重载的,所以存在二义性,在connect函数中不能在使用原来的方式
    16. // 因此需要定义函数指针
    17. // 没参数的mysignal
    18. void (Subwidget::*mysignal_without_para)() = &Subwidget::mysignal;
    19. connect(&subwin,mysignal_without_para,this,&MyWidget::dealsub);
    20. // 有参数的mysignal
    21. void (Subwidget::*mysignal_with_para)(int, QString) = &Subwidget::mysignal;
    22. connect(&subwin,mysignal_with_para,this,&MyWidget::dealslot); // ▲ 新增的槽函数不是重载的,不存在二义性,所以可以延用原来的调用方式
    23. resize(400,300);
    24. }
    25. MyWidget::~MyWidget()
    26. {
    27. }
    28. void MyWidget::changewin(){
    29. // 子窗口显示
    30. subwin.show();
    31. this->hide();
    32. }
    33. void MyWidget::dealsub(){
    34. // 子窗口显示
    35. subwin.hide();
    36. this->show();
    37. }
    38. // ▲ 新增带参数的槽函数定义
    39. void MyWidget::dealslot(int a, QString str){
    40. qDebug() << a << str;
    41. }

    运行结果

    2 Lambda表达式——槽函数的正确打开方式

    Lambda表达式,是C++11增加的新特性。在Qt配合信号一起使用,非常方便

    要使用Lambda表达式,项目文件需要添加:CONFIG += C++11。

    版本新点的Qt生成项目时自动会生成

     Lambda表达式,可以理解成:匿名函数对象

    新添加一个按钮来说明Lambda表达式的好处

    mywidget.cpp

    1. #include "mywidget.h"
    2. #include
    3. MyWidget::MyWidget(QWidget *parent)
    4. : QWidget(parent)
    5. {
    6. mainwinb.setParent(this);
    7. mainwinb.setText("切换到子窗口");
    8. mainwinb.move(100,100);
    9. this->setWindowTitle("主窗口");
    10. connect(&mainwinb,&QPushButton::released,this,&MyWidget::changewin);
    11. // connect(&subwin,&Subwidget::mysignal,this,&MyWidget::dealsub);
    12. // mysignal 是 Subwidget这个类自定义的信号
    13. // dealsub 是 MyWidget这个类自定义的槽函数
    14. // 由于mysignal是重载的,所以存在二义性,在connect函数中不能在使用原来的方式
    15. // 因此需要定义函数指针
    16. // 没参数的mysignal
    17. void (Subwidget::*mysignal_without_para)() = &Subwidget::mysignal;
    18. connect(&subwin,mysignal_without_para,this,&MyWidget::dealsub);
    19. // 有参数的mysignal
    20. void (Subwidget::*mysignal_with_para)(int, QString) = &Subwidget::mysignal;
    21. connect(&subwin,mysignal_with_para,this,&MyWidget::dealslot);
    22. // ▲ 新增代码👇
    23. QPushButton *b = new QPushButton(this);
    24. b->setText("LambdaTest");
    25. b->move(100,150);
    26. connect(b,&QPushButton::clicked, // F1 clicked, 它是带参数的,但没有重载,不需要定义函数指针、
    27. // void QAbstractButton::clicked(bool checked = false), 参数是一个,bool类型
    28. // ()函数的参数, 和信号的传参保持一致就行了
    29. // {}函数体
    30. // []是什么作用呢?
    31. // 它的作用是把外部变量传进来,可以[b],可以[a,b]但参数多了,就不好写了。所以用[=]
    32. // [=] : 把外部所有局部变量、类中所有成员以值传递方式,局限性,read-only,无法修改。
    33. // : 如果要修改,就是这么写[=]() mutable
    34. // [this]:类中所有成员以值传递方式
    35. // [&] : 把外部所有局部变量,引用符号,最好少用。 就用[=],可能多消耗点资源,但是程序稳定
    36. [=](bool isChecked) mutable
    37. {
    38. qDebug() << isChecked;
    39. }
    40. );
    41. // 用lambda表达式,不用去.h声明一个新的槽函数, 也不用在.cpp定义这个新的槽函数, 关于参数的问题,直接放在()里面就可以了。 用起来非常方便。
    42. resize(400,300);
    43. }
    44. MyWidget::~MyWidget()
    45. {
    46. }
    47. void MyWidget::changewin(){
    48. // 子窗口显示
    49. subwin.show();
    50. this->hide();
    51. }
    52. void MyWidget::dealsub(){
    53. // 子窗口显示
    54. subwin.hide();
    55. this->show();
    56. }
    57. void MyWidget::dealslot(int a, QString str){
    58. qDebug() << a << str;
    59. }

    运行结果

    类似内容参考链接:QT5中Lamda表达式及Lamda表达式在槽函数中的使用_槽函数lambda表达式-CSDN博客

     感谢您的阅读,欢迎留言讨论、收藏、点赞、分享。

  • 相关阅读:
    Web前端开发涉及的一些技术
    为区块链提速,多层扩容方案
    技术转型项目PM,如何做好项目管理?
    使用frp+nginx内网穿透并配置https
    Greetings(状压DP,枚举子集转移)
    【多线程案例】定时器应用及实现
    计算机毕设 SpringBoot+Vue幼儿园管理系统 幼儿园信息管理系统 智慧幼儿园管理系统Java Vue MySQL数据库 远程调试 代码讲解
    立创ERP仓库管理模块字段说明书
    事实分布式与价值集中式
    IDEA的Terminal光标太粗了如何调细
  • 原文地址:https://blog.csdn.net/heqiunong/article/details/127570233