我们可以在官网的文档中读到一些组件的用法以及信号和槽,但是这些组件可能并不能满足我们的需求,于是我们就需要自己编写符合自己需求的组件。
0x00.本节课你将学到:
0x01.如何新建组件
在左侧文件浏览窗口中对某个文件夹右键,点击“Add New”
选择C++ Class,并点击Choose
然后我们就会发现,左侧的文件窗口中多了这个类的头文件和cpp文件
至此,我们自己的Qt组件已经创建好了,由于ClickableLabel继承于QLabel,因此ClickableLabel具有QLabel所有功能,但是由于我们还没有为ClickableLabel添加新的功能,因此到目前为止ClickableLabel并没有QLabel不具有的功能。
0x02.如何使用自己的组件
首先打开设计界面,然后对于想要修改的组件右键,提升为
输入自己组件的名称和头文件名,点击添加,再点击提升。
我们可以发现在组件层级这里,我们刚刚选中的这个Label已经变成了ClickableLabel。
此时已经修改完成了,但是我们会发现无法运行,我们阅读报错
我们可以发现是ClickableLabel的构造函数出了问题,无法传入QWidget*,那么问题来了,为什么要传入QWidget*呢?
这里涉及到Qt中父组件和子组件的问题,在Qt中,组件有父子关系,倘若一个QLabel a是QWidget b的子组件,则程序运行时,我们可以发现a显示在b中;再举一个例子,如果QWidget c是QWidget b的子组件,则程序运行时,我们可以发现c也显示在b中。如果c的父组件(parent)为nullptr,则c可以独立显示,组成一个独立的窗口。那么Qt如何确定组件间的父子关系呢?Qt在组件的构造函数中传入父组件的指针,以此来确定父子关系。
让我们回到刚刚的问题上来,Qt传给ClickableLabel的QWidget是ClickableLabel的父组件,但是我们看看刚刚生成的clickablelabel.h和clickablelabel.cpp,构造函数中并没有参数,因此出现了问题,对于此,我们要自己编辑一下构造函数。
这样,我们就为ClickableLabel的构造函数添加了parent参数,再运行,是不是就没有问题啦?而且测试一下,功能也正常。
0x03.如何编写信号
在Qt中,信号其实也是一种函数,但是这种函数并没有具体的作用(除了触发槽函数之外),因此只需要在clickablelabel.h中声明有这个信号即可。
现在程序可以运行,但是我们并未将clicked和任何槽函数连接起来,并且,我们也没有为ClickableLabel编写触发这个信号的条件,Qt没有那么智能,仅凭名字是clicked就判断应该是点击后触发。因此我们还需要编辑触发的条件。
首先我们在clickablelabel.h中添加mousePressEvent函数,这个函数是Qt组件内置的,由于我们继承自QLabel而可以重载此函数,当鼠标点击后后调用此函数。
接下来我们在clickablelabel.cpp中编写函数体,在其中触发信号
这样当我们点击该Label的时候,这个信号就会被触发。但是还没有能接收该信号的槽函数,我们还不能检查这个信号的效果。
0x04.如何编写槽函数
槽,也是一种函数,我们只需要在头文件和cpp文件中新建并实现即可,这个在讲信号和槽的时候有提到过,这里再稍微回顾一下。
编写好槽函数后,我们就可以将其连接起来啦,我是在firstwidget.cpp中将其连接起来的
我们接着来运行试一下