【Qt】信号和槽机制

【Qt】信号和槽机制


文章目录


前言

本篇文章将讲到.pro文件,main函数中的相关代码,以及按钮,信号和槽的机制,以及Lambda表达式


一、.pro文件

在使用Qt向导生成的应用程序.pro文件格式如下:

二、main函数中

QApplication a 应用程序对象 在Qt中 有且仅有一个

Widget w 窗口对象

w.show() 函数显示窗口

return a.exec()进入消息循环机制,阻塞功能

三、第一个Qt小程序

按钮的创建

cpp 复制代码
MWidget::MWidget(QWidget *parent)
    : QWidget(parent)
{
    //按钮
    QPushButton *btn = new QPushButton;
    //设置父亲
    btn->setParent(this);
    //设置文字
    btn->setText("古娜拉黑暗之神");
    //移动位置
    btn->move(100,100);

    //第二种创建
    QPushButton * btn2 = new QPushButton("巴啦啦能量",this);
    //重新指定窗口大小
    this->resize(600,400);
    //设置窗口标题
    this->setWindowTitle("第一个项目");
    //限制窗口大小
    this->setFixedSize(600,400);
}

上面代码中,一个按钮其实就是一个QPushButton类下的对象,如果只是创建出对象,是无法显示到窗口中的,所以我们需要依赖一个父窗口,也就是指定一个父亲利用setParent函数即可,如果想设置按钮上显示的文字利用setText,移动按钮位置用move

对于窗口而言,我们可以修改左上角窗口的标题setWindowTitle,重新指定窗口大小:resize,或者设置固定的窗口大小setFixedSize;

运行结果

对象模型(对象树)

Qt窗口坐标体系

坐标体系:

以左上角为原点(0,0),X向右增加,Y向下增加。

四、信号和槽机制

信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后 ,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal) 。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣 ,它就会使用连接(connect)函数 ,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号 。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。
系统自带的信号和槽

下面我们完成一个小功能,上面我们已经学习了按钮的创建,但是还没有体现出按钮的功能,按钮最大的功能也就是点击后触发一些事情,比如我们点击按钮,就把当前的窗口给关闭掉,那么在Qt中,这样的功能如何实现呢?

connect()函数最常用的一般形式:

connect(sender, signal, receiver, slot);

sender:发出信号的对象

signal:发送对象发出的信号

receiver:接收信号的对象

slot:接收对象在接收到信号之后所需要调用的函数(槽函数)

cpp 复制代码
 QPushButton * quitBtn = new QPushButton("关闭窗口",this);
  connect(quitBtn,&QPushButton::clicked,this,&MWidget::close);

自定义信号和槽

使用connect()可以让我们连接系统提供的信号和槽。但是,Qt 的信号槽机制并不仅仅是使用系统提供的那部分,还会允许我们自己设计自己的信号和槽。

下面我们看看使用 Qt 的信号槽:

cpp 复制代码
//首先定义一个学生类和老师类:
	//老师类中声明信号 饿了 hungry
signals:
       void hungury();
	//学生类中声明槽   请客 treat
	public slots:
       void treat();
	//在窗口中声明一个公共方法下课,这个方法的调用会触发老师饿了这个信号,而响应槽函数学生请客
	void MyWidget::ClassIsOver()
{
    //发送信号
    emit teacher->hungury();
}
	//学生响应了槽函数,并且打印信息
//自定义槽函数 实现
void Student::eat()
{
       qDebug() << "该吃饭了!";
}
//在窗口中连接信号槽
    teacher = new Teacher(this);
    student = new Student(this);

    connect(teacher,&Teacher::hungury,student,&Student::treat);
//并且调用下课函数,测试打印出 "该吃饭了"
//---------------------------------------------------------------------
//自定义的信号 hungry带参数,需要提供重载的自定义信号和 自定义槽
void hungury(QString name);  自定义信号
void treat(QString name );    自定义槽
//但是由于有两个重名的自定义信号和自定义的槽,直接连接会报错,所以需要利用函数指针来指向函数地址, 然后在做连接
void (Teacher:: * teacherSingal)(QString) = &Teacher::hungury;
void (Student:: * studentSlot)(QString) = &Student::treat;
connect(teacher,teacherSingal,student,studentSlot);

将QString 转为 char *

.toUtf8()转为 QByteArray数据类型

.data() 转为 char * 类型
信号和槽拓展

1.信号是可以连接信号

2.可以断开信号和槽 disconnect

3.一个信号可以响应多个槽函数

4.多个信号可以连接同一个槽函数

5.信号和槽函数的参数类型 必须一一对应,信号的参数个数 可以多余槽函数的参数个数,反之不可以 , 参数类型要一一对应

五、Lambda表达式

C++11中的Lambda表达式用于定义并创建匿名的函数对象 ,以简化编程工作。首先看一下Lambda表达式的基本构成:
<>mutable -> type {}组成

\[\]中可以加 = & a &a ... 推荐 使用 =

() 形参列表

{} 实现体

mutable可以修改按值传递进来的拷贝

-> type 代表lambda表达式返回值类型


总结

到这里这篇文章的内容就结束了,谢谢大家的观看,如果有好的建议可以留言喔,谢谢大家啦!

相关推荐
Frank_refuel8 小时前
【C++项目】手撕JRpc框架(单机怎么优化到分布式思想)
开发语言·c++
geats人山人海8 小时前
linux 1.目录结构
linux·运维·服务器
ShineWinsu8 小时前
对于Redis:Hash类型的解析
c++·redis·分布式·缓存·面试·hash·哈希表
wuminyu8 小时前
JEP491中synchronized关键字引发的平台线程钉住解决方法简介
java·linux·c语言·jvm·c++
All for pursuit.8 小时前
【贪心-4】581.最短无序连续子数组
数据结构·c++·算法·leetcode
应用市场9 小时前
嵌入式Linux从裸板到产品(一):全景地图与交叉编译环境,从四个上板翻车现场说
linux·运维·服务器
皓月盈江9 小时前
Linux系统PC与Linux系统服务器通过scp上传与下载文件
linux·运维·服务器·scp·文件上传·文件下载
Ruiery9 小时前
Linux 6.6内核 CPU 启动深度解析(二):AP 拉起 — BSP 如何用 INIT-SIPI 唤醒其余 CPU
linux·运维·服务器
无名猿9 小时前
list 与 forward_list:链表真的比 vector 快吗
c++·性能优化·stl·内存管理·标准库
笑鸿的学习笔记9 小时前
C++笔记之SIMD与SSE指令集
开发语言·c++·笔记