参考视频:黑马程序员https://www.bilibili.com/video/BV1XW411x7NU?p=4

1  新建工程

先创建一个控件基础工程,创建后的界面如下:

主函数我们不需要修改,就保持这样,对于C++的知识我不太理解。

上述代码中,执行到第7行的时候,会先去执行基类的构造函数,再执行MyWidget类的构造函数。我们只需要在构造函数中实现需要实现的功能。

构造函数对应在mywidget.cpp中:

2  测试代码

实例一:标准的信号处理

测试目的:在主窗口中,新建两个按钮,功能如下:

按钮一的功能:按下按钮,关闭主窗口;

按钮二的功能:释放按钮,更改按钮二的文本,并隐藏按钮一。

由于在实现过程中,会用到信号与槽的知识,就先简单介绍一下基本知识,可能不正确,这只是我个人的理解:

信号:某一事件发生时产生,用于表示一个事件发生了。

槽:就是信号处理函数,用于指示当信号发生时,需要做出什么动作。

其中,我们connect函数来连接信号与槽之间的关系,函数的原型如下:

connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection);

举例说明:

connect(&b1, &QPushButton::pressed, this, &MyWidget::close);

/* &b1:信号发出者,指针类型

* &QPushButton::pressed:处理的信号,&发送者的类名::信号名字

* this:信号接收者

* &MyWidget::close:槽函数,信号处理函数 &接收的类名::槽函数名字

*/

不同的控件有哪些信号,可通过帮助文档查看,以QPushButton为例进行说明(点QPushButton,再按F1):

这里没有看到signal函数,可能是从它的父类继承过来的,我们再看一下它的父类:

 实现的相关代码

先在MyWidget类中实现两个按钮(mywidget.h):

 1 #ifndef MYWIDGET_H
2 #define MYWIDGET_H
3
4 #include <QWidget>
5 #include <QPushButton>
6
7 class MyWidget : public QWidget
8 {
9 Q_OBJECT
10
11 public:
12 MyWidget(QWidget *parent = 0);
13 ~MyWidget();
14
15 private:
16 QPushButton b1;
17 QPushButton *b2;
18
19 void myslot();
20
21 };
22
23 #endif // MYWIDGET_H

再在构造函数中实现两个按钮的功能(mywidget.cpp):

 1 #include "mywidget.h"
2 #include <QPushButton>
3
4 MyWidget::MyWidget(QWidget *parent)
5 : QWidget(parent)
6 {
7 b1.setParent(this);
8 b1.setText("按钮一");
9 b1.move(100, 100);
10
11 b2 = new QPushButton(this);
12 b2->setText("按钮二");
13
14 connect(&b1, &QPushButton::pressed, this, &MyWidget::close);
15 /* &b1:信号发出者,指针类型
16 * &QPushButton::pressed:处理的信号,&发送者的类名::信号名字
17 * this:信号接收者
18 * &MyWidget::close:槽函数,信号处理函数 &接收的类名::槽函数名字
19 */
20
21 /*
22 * 自定义槽,普通函数的用法
23 * Qt5:任意的成员函数,普通全局函数,静态函数
24 * 槽函数需要和信号一致(参数、返回值)
25 * 由于信号都是没有返回值,所以槽函数一定没有返回值
26 */
27 connect(b2, &QPushButton::released, this, &MyWidget::myslot);
28
29 connect(b2, &QPushButton::released, &b1, &MyWidget::hide);
30 /*
31 * 信号:短信
32 * 槽函数:接收短信的手机
33 */
34 }
35
36 void MyWidget::myslot()
37 {
38 b2->setText("123");
39 }
40
41 MyWidget::~MyWidget()
42 {
43
44 }

运行,进行测试:

 实例二:自定义不带参数信号处理

目的:实现两个窗口,主窗口和子窗口,并且每个窗口都有一个按键,按键功能如下:

主窗口按键的功能:显示子窗口,关闭父窗口;

子窗口按键的功能:关闭子窗口,显示父窗口。

主窗口和子窗口的切换显示全部由主窗口控制,可以理解为:主窗口的权限大于子窗口,子窗口的按键按下去只是产生一个信号,主窗口再对信号进行处理。

新建一个工程,工程创建之后,有以下文件,其中,subwindown相关文件是通过点击signal_slot_2目录文件,选择添加新文件,选择C++ --> C++ Class,基类我们选择QWidget:

实现的代码如下:

widget.h是widget类所在同文件,主要实现:声明主窗口按键处理函数、声明子窗口信号接收处理函数、实例化一个subwindown类对象、实例化一个QPushButton类对象。

 1 #ifndef WIDGET_H
2 #define WIDGET_H
3
4 #include <QWidget>
5 #include <QPushButton>
6 #include "subwindown.h"
7
8 class Widget : public QWidget
9 {
10 Q_OBJECT
11
12 public:
13 Widget(QWidget *parent = 0);
14 ~Widget();
15
16 void my_slot();
17 void dealsub();
18
19 private:
20 QPushButton b_main;
21
22 subwindown sw;
23 };
24
25 #endif // WIDGET_H

subwindown.h是subwindown类所在头文件,主要实现:声明子窗口按键处理函数、声明一个信号、实例化一个QPushButton类对象。

 1 #ifndef SUBWINDOWN_H
2 #define SUBWINDOWN_H
3
4 #include <QWidget>
5 #include <QPushButton>
6
7 class subwindown : public QWidget
8 {
9 Q_OBJECT
10 public:
11 explicit subwindown(QWidget *parent = nullptr);
12 //定义槽函数
13 void sendslot();
14
15 signals:
16 /*
17 * 信号必须有signals关键字声明
18 * 信号没有返回值,但可以有参数
19 * 信号就是函数的声明,只需声明,无需定义
20 * 使用:emit mysignal();
21 */
22 void mysignal();
23
24 public slots:
25
26 private:
27 QPushButton b_sub;
28
29 };
30
31 #endif // SUBWINDOWN_H

main.cpp中的代码不改动,就使用生成的代码:

 1 #include "widget.h"
2 #include <QApplication>
3
4 int main(int argc, char *argv[])
5 {
6 QApplication a(argc, argv);
7 Widget w;
8 w.show();
9
10 return a.exec();
11 }

widget.cpp中实现的是主窗口的构造函数,主要实现:接收主窗口按键的信号并处理、接收子窗口发送的信号并处理。

 1 #include "widget.h"
2
3 Widget::Widget(QWidget *parent)
4 : QWidget(parent)
5 {
6 setWindowTitle("主窗口");
7
8 //设置按钮相关属性
9 b_main.setParent(this);
10 b_main.setText("切换子窗口");
11 b_main.move(50, 50);
12 //处理主窗口的按钮所产生的信号
13 connect(&b_main, &QPushButton::clicked, this, Widget::my_slot);
14
15 //接收子窗口信号,并进行处理
16 connect(&sw, &subwindown::mysignal, this, &Widget::dealsub);
17 resize(400, 300);
18 }
19
20 void Widget::my_slot()
21 {
22 //显示子窗口
23 sw.show();
24 //父窗口隐藏
25 this->hide();
26 }
27
28 void Widget::dealsub()
29 {
30 //主窗口显示
31 this->show();
32 //子窗口隐藏
33 sw.hide();
34 }
35
36 Widget::~Widget()
37 {
38
39 }

subwindown.cpp中实现的是子窗口的构造函数,主要实现:接收子进程按键的信号并处理,处理方式为发送一个自定义信号。

 1 #include "subwindown.h"
2
3 subwindown::subwindown(QWidget *parent) : QWidget(parent)
4 {
5 setWindowTitle("子窗口");
6
7 //按键属性设置
8 b_sub.setText("切换主窗口");
9 b_sub.setParent(this);
10 b_sub.move(50, 50);
11
12 //接收按键信号并处理
13 connect(&b_sub, &QPushButton::clicked, this, &subwindown::sendslot);
14 resize(400, 300);
15 }
16
17 void subwindown::sendslot()
18 {
19 //发送信号
20 emit mysignal();
21 }

运行测试:

点击“切换子窗口”按键:

实例三:自定义带参数信号处理

功能:在空白窗口中定义一个按钮,点击按钮发送一个自定义的带参数的信号,然后由本窗口接收信号并将参数打印出来。

首先,创建一个控件基类工程,创建后包含的文件如下:

在widget.h中,实现的功能有:声明一个发送信号函数、声明一个接收信号函数、自定义一个带参数的信号、实例化一个QPushButton对象。

 1 #ifndef WIDGET_H
2 #define WIDGET_H
3
4 #include <QWidget>
5 #include <QPushButton>
6
7 class Widget : public QWidget
8 {
9 Q_OBJECT
10
11 public:
12 Widget(QWidget *parent = 0);
13 ~Widget();
14
15 //点击按钮,发送信号函数
16 void send_signal();
17 //接收信号处理函数
18 void recv_signal(int, QString);
19
20 signals:
21 //自定义一个带参数的信号
22 void mysignal(int, QString);
23
24 private:
25 QPushButton b_main;
26
27 };
28
29 #endif // WIDGET_H

在widget.cpp中,实现的功能有:接收点击按键的信号并进行处理,接收自定义的信号并进行处理。

 1 #include "widget.h"
2 #include <QDebug>
3
4 Widget::Widget(QWidget *parent)
5 : QWidget(parent)
6 {
7 b_main.setParent(this);
8 b_main.setText("发送");
9 b_main.move(100, 100);
10
11 //点击按钮,发送信号
12 connect(&b_main, &QPushButton::clicked, this, &Widget::send_signal);
13
14 //接收点击按钮,发送的信号
15 void (Widget::*testsignal)(int, QString) = &Widget::mysignal;
16 connect(this, testsignal, this, &Widget::recv_signal);
17
18 this->resize(300, 300);
19 }
20
21 void Widget::send_signal()
22 {
23 emit mysignal(100, "我已经发送信号");
24 }
25
26 void Widget::recv_signal(int a, QString str)
27 {
28 qDebug() << a << str;
29 }
30
31 Widget::~Widget()
32 {
33
34 }

运行,并进行测试,点击一次发送按钮,就会发送一个自定义信号,并接收到了它:

实例四:lambda表达式的使用

功能:创建一个按钮,点击按钮发送一个信号,不需要指定信号接收函数和信号接收者,直接使用匿名函数(lambda表达式)实现。

先新建一个工程,新建后的工程文件如下:

由于lambda是C++11支持的特性,所以我们需要在lambda_test.pro文件末尾添加一句:CONFIG += C++11

先把代码放上,再说明lambda表达式的作用。

widget.h文件:

 1 #ifndef WIDGET_H
2 #define WIDGET_H
3
4 #include <QWidget>
5 #include <QPushButton>
6
7 class Widget : public QWidget
8 {
9 Q_OBJECT
10
11 public:
12 Widget(QWidget *parent = 0);
13 ~Widget();
14
15 private:
16 //定义一个类中成员变量
17 int a = 10;
18
19 };
20
21 #endif // WIDGET_H

widget.cpp文件:

 1 #include "widget.h"
2 #include <QDebug>
3
4 Widget::Widget(QWidget *parent)
5 : QWidget(parent)
6 {
7 QPushButton *b_main = new QPushButton(this);
8 b_main->setParent(this);
9 b_main->setText("开始");
10 b_main->move(100, 100);
11
12 //定义一个外部局部变量
13 int b = 12;
14 //Lambda表达式,匿名函数对象
15 //C++11增加的新特性,项目文件: CONFIG += C++11
16 //Qt配合信号一起使用,非常方便
17 connect(b_main, &QPushButton::clicked,
18 // =:把外部所有局部变量、类中所有成员以值方式传进来
19 // this:类中所有成员以值传递方式
20 // &:引用符号,外部所有局部变量
21 [=](bool isCheck)mutable
22 {
23 b_main->setText("lambda表达式");
24 qDebug() << "已经进入lambda表达式";
25 qDebug() << a << b;
26 a += 10;
27 b += 20;
28 qDebug() << isCheck;
29 }
30 );
31
32 this->resize(300, 300);
33 }
34
35 Widget::~Widget()
36 {
37
38 }

下面就简单的说明lambda表达式的语法,我也不是很懂,根据测试结果进行说明。

参考了这篇博客:https://www.cnblogs.com/rainbow70626/p/10328143.html

格式:[capture](parameters) mutable ->return-type{statement};

capture:捕捉列表,也单独代表函数的开始,主要有以下使用方式:

  • 单独传递外部变量,如:[b_main]
  • =:把外部所有局部变量、类中所有成员以值方式传进来(widget.c和widget.h文件中的成员)
  • this:类中所有成员以值传递方式(widget.h文件中的成员)
  • &:引用符号,外部所有局部变量(widget.c文件中的成员),当变量是指针时,最好别用这个。

parameters:参数列表,信号的参数。

mutable :值传递时,默认变量为只读的,如果需要在匿名函数中改变它,需要这个参数

运行代码进行测试:

Qt信号与槽的使用的更多相关文章

  1. QT 信号与槽connect

    QT 信号与槽connect QT 信号与槽connect connect函数调用几个限制 connect函数代码 QT中信号与槽的连接使用的connect函数是一个静态函数,在类QObject中定义 ...

  2. Qt 信号与槽

    Qt信号与槽的理解 信号和槽机制是 QT 的核心机制,要精通 QT 编程就必须对信号和槽有所了解.信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重 ...

  3. QT信号和槽

    QT信号和槽 ============ 信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性.要正确的处理信号和槽,必须借助一个称为 moc(Meta Object Compiler) ...

  4. Qt信号与槽自动关联机制

    参考链接1:http://blog.csdn.net/skyhawk452/article/details/6121407 参考链接2:http://blog.csdn.net/memory_exce ...

  5. Qt信号与槽应用实例一

    ..... connect(m_pGlobelWidget,signal(globeControlClick(object,object)),this,slot(globeControlClick(o ...

  6. Qt 信号和槽函数

    信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性.当某个信号被发射,就需要调用与之相绑定的槽函数.这与Windows下的消息机制类似,消息机制是基于回调函数.一个回调即是一个函数的 ...

  7. QT 信号与槽连接

    转帖 http://www.cnblogs.com/cnhome/archive/2009/10/01/1577277.html 信号(SIGNAL)和槽(SLOT)是Qt编程的一个重要部分.这个机制 ...

  8. Qt信号和槽的个人总结

    1.connect connect(sender,SIGNAL(signal()),receiver,SLOT(slot())); 这里用到了两个宏:SIGNAL() 和SLOT():通过connec ...

  9. QT 信号与槽 QT简单加法器的实现

    信号与槽 背景: 面向过程 模块之间低耦合设计(高内聚). 函数调用: 直接调用 回调调用(低耦合) 面向对象 模块之间低耦合设计(高内聚) 对象调用 直接调用 接口调用 QT: 信号与槽解决问题: ...

  10. 关于Qt信号与槽机制的传递方向性研究(结论其实是错误的,但是可以看看分析过程)

    最近由于项目的需求,一直在研究Qt.信号与槽机制是Qt的一大特色,该机制允许两者间传递参数,依次来实现对象间的通信.这个参数会分别存在于信号的参数列表和槽函数的参数列表中.需要注意的是,若将槽函数绑定 ...

随机推荐

  1. python将日志生成到文件和控制台

    # 日志收集设置import logging, osfrom logging.handlers import TimedRotatingFileHandlerimport datetimecurren ...

  2. python实现不同颜色气球隔开摆放,并且提示不能摆放的情况

    这个是一位隐秘人物让我做的一道题(如标题),我也分享出来了. 首先是成品展示(暂时没有做成可视化界面的样子): 我做的是把所有的气球录入进来,然后利用基础数据结构(字典,数据等)排序等,由于我是初学, ...

  3. 大数据ETL开发之图解Kettle工具入门到精通(经典转载)

    大数据ETL开发之图解Kettle工具(入门到精通) 置顶 袁袁袁袁满 文章目录 第0章 ETL简介 第1章 Kettle简介 1.1 Kettle是什么 1.2 Kettle的两种设计 1.3 Ke ...

  4. 企业实施定制鞋厂ERP软件需要注意哪些问题?

    企业实施定制ERP软件是个复杂的管理系统工程,为了成功地为企业定制实施ERP软件,需要注意和解决几个关键的问题: (1) . 确立ERP系统实施和定制的决策者: (2) . 做好前期咨询与调研工作: ...

  5. EasyNLP集成K-BERT算法,借助知识图谱实现更优Finetune

    导读 知识图谱(Knowledge Graph)的概念⾸次出现2012年,由Google提出,它作为⼀种⼤规模语义⽹络, 准确地描述了实体以及实体之间的关系.知识图谱最早应⽤于搜索引擎,⽤于准备返回⽤ ...

  6. 使用 Databricks 进行营销效果归因分析的应用实践【Databricks 数据洞察公开课】

    简介: 本文介绍如何使用Databricks进行广告效果归因分析,完成一站式的部署机器学习,包括数据ETL.数据校验.模型训练/评测/应用等全流程. 作者:冯加亮   阿里云开源大数据平台技术工程师 ...

  7. 流批一体生产应用!Bigo 实时计算平台建设实践

    简介: 本文由 Bigo 计算平台负责人徐帅分享,主要介绍 Bigo 实时计算平台建设实践的介绍 本文由 Bigo 计算平台负责人徐帅分享,主要介绍 Bigo 实时计算平台建设实践的介绍.内容包括: ...

  8. 为什么Spring仍然会是云原生时代最佳平台之一?

    简介: 基于Java语言的Spring生态,还能否适应新的开发方式,比如Cloud Native.Serverless.Faas等,它还会是云原生时代的最佳平台的选择吗?本文将从5个角度来为你分析一下 ...

  9. 性能提升3倍、时延降低70%,阿里云企业级存储ESSD云盘再升级!

    9月22日,阿里云存储年度新品发布会上,阿里云基础产品资深产品总监陈起鲲发布了其全球领先的旗舰级块存储产品ESSD的两款新规格(ESSD Auto PL.ESSD PL-X),并宣布了新增的多项企业级 ...

  10. [FAQ] 部署二进制运行时 go-ego/gse 如何正确加载分词字典

    运行Golang编译后二进制运行时,此时运行二进制时所在目录就是Golang源码程序认为的根目录了. 所以只需要把字典文件拷贝到与二进制所在同一目录内,然后使用 seg.LoadDict('dicti ...