关键字参数理解:
在QT中,连接槽与信号的关键字是connect,它里面的参数如下:
按照我的理解,里面四个参数分别如下:
1、信号发送者
2、发送的信号
3、信号接收者
4、接收的信号
【拓】:
信号发送者和信号接收者传的参数都是相应对象的地址
如果声明对象的时候,使用的是指针,则不用加&,如果是直接声明的对象,则需要加&进行取址。
例如:
声明一个按钮对象
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。