对QT5信号与槽的认识

关键字参数理解:

在QT中,连接槽与信号的关键字是connect,它里面的参数如下:

 

按照我的理解,里面四个参数分别如下:

1、信号发送者

2、发送的信号

3、信号接收者

4、接收的信号

 

【拓】:

信号发送者和信号接收者传的参数都是相应对象的地址

扫描二维码关注公众号,回复: 2344795 查看本文章

如果声明对象的时候,使用的是指针,则不用加&,如果是直接声明的对象,则需要加&进行取址。

例如:

声明一个按钮对象

QPushButton button1;//直接声明的对象本身

调用相应函数时,使用“.”关键字

在connect中使用如下:

connect(&button1,参数2,参数3,参数4);

 

QpushButton *button2;//声明了一个指向该button对象的指针,指针表示的就是该对象的地址,加*表示该对象的内容

调用相应函数时,使用“->”关键字

在connect中使用如下:

connect(button2,参数2,参数3,参数4);

 

比如说,点击一个按钮a,点击之后,使另一个按钮b消失

那么按钮a就是信号发送者,点击按钮这个动作就是发送的信号;

按钮b就是信号的接收者,按钮b消失就是接收到的信号

内置的信号与槽函数:

根据前面讲的,点击一个按钮a,让按钮b消失,如果写的话,可以这样写:

QPushButton *a;

QPushBUtton *b;

a=new QPushButton("a",this);//使用指针需要使用new关键字申请控件

b=new QPushButton("b",this);

connect(a,&QPushButton::clicked,b,&QPushButton::hide);

 

如果我们查看QPushButton的API,会发现如下内容:

会发现QPushButton里已经有内置的槽函数了

其槽函数好像只有一个,showMenu(),但是仔细看,会发现,API里写着,有5个槽函数继承自QAbstractButton,有19个槽函数继承自QWidget,有1个槽函数继承自QObject。

但是又仔细看QPushButton的API,发现,它并没有内置的信号呀,但是再仔细看,会发现,QPushButton它继承自QAbstractButton,而查看QAbstractButton的API可以发现如下内容:

在这里我们发现了Signals,查看得:

如果再细心点,可以看到,QAbstractButton继承自QWidget,而QWidget也有信号

自定义槽函数:

这里依旧是举个例子,我们现在有个按钮QPushButton *a,它的父窗口是一个QWidget,

代码主要内容是这样的:

现在有三个文件:

mainWidget.h、mainWidget.cpp、main.cpp

mainWidget.h添加的内容如下,在这里我只是声明了一个按钮

private:

    QPushButton *button;

添加头文件

#include<QPushButton>

 

再加上我们自定义的槽函数:

mainWidget.cpp添加的内容如下:

resize(200,200);

setWindowTitle("Hello");

button=new QPushButton("button",this);

connect(button,&QPushButton::clicked,this,&mainWidget::mySLOT);

 

这里我定义了窗口的名称是Hello,当我按下button时,就会触发我们自定义的槽函数,我们自定义的槽函数内容就是改变窗口的名称:

这个时候,运行程序

当点击button后

窗口的名称发生了变化

自定义信号:

在前面的基础之上,我们来实现自定义信号

 

在自定义信号之前,我们需要知道:

信号必须要有signals关键字来声明,信号没有返回值,但可以有参数

信号实际上就是函数的声明,只需声明,无需定义,信号可以重载

使用emit关键字,发送信号。

 

我们再定义一个带有按钮的窗口subWidget,这时候在原先的代码基础上,又多了两个文件:

subWidget.h、subWidget.cpp

 

subWidget.h里面的内容如下:

这里定义了一个button按钮,然后定义了一个槽函数mySLOT(),在signals关键字下定义了一个函数mySignal();

subWidget.cpp里面的内容如下:

这里的意思是,当我们按下这里的button按钮时,就触发我们的槽函数,我们的槽函数里面的内容就是发送我们的信号

 

同时也在mainwidget.h文件里加入下面两句话:

在mainwidget.cpp文件里加入下面内容:

这里的意思就是说,当发出mySignal这个信号后,触发mySubSLOT这个槽函数,那么怎么才能发出mySignal这个信号呢,就需要点击上面我们说的button按钮,触发响应的槽函数,从而发出mySignal信号。

 

该程序的效果图如下:

点击button按钮后

出来这个界面

点击这个界面的button按钮后,将它的窗口名称改成subWidget

信号的重载:

前面我们已经知道了怎么写自定义的信号,也知道了信号可以重载,那我们这里就将我们刚才写的信号进行一次重载。

在subwidget.h文件中将mySignal()信号进行重载

【注】:信号参数只需声明,无需定义

 

在subwidget.cpp文件中,将重载的信号加入到槽函数中

传入了参数

 

点击按钮后,发出信号,但是这里我们并不知道我们接收到的是哪个信号,程序报错

 

【解决办法】:

通过函数指针来解决

这里,当点击按钮时,会触发响应的槽函数,槽函数里面是发出两个信号,一个是无参的mySingle()信号,一个是有参的mySingle(int,QString)信号

Qt4与Qt5信号与槽的区别:

我们看网上的教程,在信号与槽这个地方,我们可能会看到这样的单词:SIGNAL,SLOT

其实这里是QT4的用法,在QT5里面使用的是我们刚才的用法,这里简单介绍一下QT4里面的用法。

看我们使用SIGNAL关键字的时候,直接就可以选择不同的信号,这样就免去了QT5里面使用函数指针。

使用SLOT关键字,里面直接是槽函数,但是有一点要注意,在QT5里面,我们自定义的槽函数直接定义,但是在QT4里面,我们自定义的槽函数要有slots关键字修饰:

为什么QT5要对这个槽函数的写法进行修改呢,有两点原因,一方面,在QT4中,我们自定义的槽函数在定义时必须要用slots关键字修饰,在QT5中则不需要;另一方面,使用SIGNAL关键字,当我们手误把其中的信号单词写错时,在编译阶段并不会报错,只有在运行阶段才会报错,在大型的项目中,这样不太好,而使用QT5的写法,当手误写错时,编译阶段就已经报错了,能及时发现并定位到相应位置。

匿名函数:

有时候通过匿名函数实现对信号的操作会方便很多,其格式如下:

使用匿名函数之前,需要在项目文件中加上这样的一句话:

CONFIG+=C++11

匿名函数使用一个中括号[ ],一个小括号( ),一个花括号{ }组成,花括号里面放代码片段

这句话的效果是,每点击一次button按钮,就会输出1111.

如果我这个时候想要改变button的text值,只需在花括号里面写button->setText("Change")即可,但是在运行的时候发现报错了,报错理由是找不到button,没有声明button。

解决办法:

    [ ]里面可以传入外面的参数进来,所以只需要在[ ]里面把button传进去就行了,这里的参数传递是值传递。

    在[ ]里面写个“=”,就是把外部所有局部变量类中所有成员以值传递,但这种情况下,传递进去的值默认为只读形式,不能        修改,如果想要修改,就需要在()后面加一个关键字:mutable

    

 

    在[ ]里面写this,类中所有成员以值传递方式。

    在[ ]里面写“&”,引用符号,外部所有局部变量

 

这里查看clicked的API会发现,clicked函数是有参数的

那么这个参数我们要怎么使用呢?这里只需要将相应的参数传入到匿名函数的小括号内就可以了

每按一下,都会输出一个false。

猜你喜欢

转载自blog.csdn.net/Demiya/article/details/81173376