【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表达式返回值类型


总结

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

相关推荐
cv操作贼61 小时前
c++ 多线程知识汇总
服务器·c++·算法
为啥不吃肉捏1 小时前
《我在技术交流群算命》(三):QML的Button为什么有个蓝框去不掉啊(QtQuick.Controls由Qt5升级到Qt6的异常)
开发语言·c++·qt·开源
熬夜写代码的小蔡3 小时前
链表的‘跑酷’:C++ list 如何在数据中自由穿梭?
开发语言·数据结构·c++·visualstudio·list
Source.Liu3 小时前
【CXX】0 Rust与C 互操作利器:CXX库介绍与示例
c++·rust·cxx
虾球xz3 小时前
游戏引擎学习第98天
c++·学习·游戏引擎
*TQK*3 小时前
ZZNUOJ(C/C++)基础练习1091——1100(详解版)⭐
c语言·c++
陈老师还在写代码3 小时前
在服务器部署JVM后,如何评估JVM的工作能力,比如吞吐量
运维·服务器·jvm
脆皮炸鸡7553 小时前
STL中list的模拟实现
c++·windows·list
蜗牛沐雨4 小时前
在 Go 中实现事件溯源:构建高效且可扩展的系统
服务器·golang·ddd·事件驱动·领域驱动