QT:【第一个QT程序】【信号和槽】

目录

一. 第一个QT程序

1.1纯代码实现

1.2可视化操作实现

1.3 项目文件解析

1.3.1 .pro文件解析

1.3.2 widget.h 文件解析

1.3.3 main.cpp文件解析

1.3.4 widget.cpp

1.3.5 widget.ui文件解析

1.4对象树

演示自动释放的过程

1.5 中文乱码

1.6 Qt窗口坐标系

二. 信号和槽

2.1 信号和槽的概念

2.2 信号和槽的使用

2.2.1 连接信号和槽

2.2.2 查看信号和槽

2.2.3 通过 Qt Creator生成信号槽代码

2.3 自定义信号和槽

2.3.1 基本语法

2.3.2 带参数的信号和槽

2.4其他说明

2.4.1 信号和槽的断开

2.4.2使用lambda定义槽函数

2.5 信号与槽的优缺点


一. 第一个QT程序

1.1纯代码实现

QString是什么?以前学习字符串的时候,在C语言中是以\0为结尾,C++中string类型标识字符串。很久之前,Qt诞生于1991年,当时的这些容器都不太好用,这里Qt就独自的实现了一系列的基础类,包括QString,QVector。。。当然现在是比较成熟了。都可以用

1.2可视化操作实现

(1)双击:"widget.ui"文件;

2)拖拽控件至ui 界面窗口并修改内容;

(3)构建并运行,效果如下所示:

在这个过程中,qmake在编译项目的时候,基于.ui里面的内容自动的生成一段C++代码,通过这个C++代码就能构建出内容了:

就是下面的.h文件:

里面其实就是创建一个label对象什么的:

1.3 项目文件解析

1.3.1 .pro文件解析

工程新建好之后,在工程目录列表中会有一个后缀为".pro"的文件。".pro"文件即工程文件(project),它是qmake自动生成的、用于生成makefile的配置文件。

进入之后:

".pro"文件的写法如下:

1. 注释:从"#"开始,到这一行结束。

2. QT += core gui //Qt包含的模块 Qt5包含的模块如下图所示:

3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 这条语句的含义是,如果 QT_MAJOR_VERSION 大于 4(也就是当前使用的 Qt5 及更高版本),需要增加 widgets 模块。如果项目仅需支持 Qt5,也可以直接添加"QT += widgets"一句。不过为了保持代码兼容,最好还是按照 QtCreator 生成的语句编写。

4. 指定生成的应用程序名:TARGET = QtDemo 5. TEMPLATE = app //模板。告诉 qmake 为这个应用程序生成哪种 makefile。下面是可供选择的模板:

⚫ app:建立一个应用程序的 makefile。这是默认值,所以如果模板没有被指定,这个将被使用。

⚫ lib:建立一个库的 makefile。

⚫ vcapp:建立一个应用程序的 VisualStudio 项目文件。

⚫ vclib:建立一个库的 VisualStudio 项目文件。

⚫ subdirs:这是一个特殊的模板,它可以创建一个能够进入特定目录的 makefile 并且为它调用 make 的 makefile。

6. 工程中包含的源文件:SOURCES += main.cpp/widget.cpp

7. 工程中包含的头文件:HEADERS += widget.h

8. 工程中包含的资源文件:RESOURCES += painter.qrc

9. 工程中包含的"ui"设计文件:FORMS += widget.ui

10. 配置信息:CONFIG += c++11 (使用 c++11 的特性) CONFIG 用来告诉 qmake 关于应用程序的配置信息。

1.3.2 widget.h 文件解析

在Qt中,如果要使用信号与槽(signal和slot)的机制,就必须加入Q_OBJECT宏; Ui::Widget *ui; 这个指针是用前面声明的namespace Ui里的Widget类定义的,所以指针ui是指向可视化设计的界面,后面要访问界面上的组件,都需要通过这个指针ui去访问。

1.3.3 main.cpp文件解析

1. Qt系统提供的标准类名声明头文件没有.h后缀;

2. Qt一个类对应一个头文件,类名就是头文件名;

3. QApplication为应用程序类;QApplication a;(a为应用程序对象,有且仅有一个。)

⚫ QApplication管理图形用户界面应用程序的控制流和主要设置。

⚫ QApplication是Qt的整个后台管理的命脉。它包含主事件循环,在其中来自窗口系统和其它资源的所有事件处理和调度。它也处理应用程序的初始化和结束,并且提供对话管理。

⚫ 对于任何一个使用Qt的图形用户界面应用程序,都正好存在一个QApplication对象,而不论这个应用程序在同一时间内是不是有0、1、2或更多个窗口。

4. myWidget w; //实例化窗口对象

5. w.show();//调用show函数显示窗口

6. a.exec():程序进入消息循环,等待对用户输入进行响应。这里main()把控制权转交给Qt,Qt完成事件处理工作,当应用程序退出的时候exec()的值就会返回。在exec()中,Qt接受并处理用户和系统的事件并且把它们传递给适当的窗口部件。

1.3.4 widget.cpp

1.3.5 widget.ui文件解析

widget.ui 是窗体界面定义文件,是一个XML文件,定义了窗口上的所有组件的属性设置、布局,及其信号与槽函数的关联等。用UI设计器可视化设计的界面都由Qt自动解析,并以XML文件的形式保存下来。在设计界面时,只需在UI设计器里进行可视化设计即可,而不用管widget.ui文件是怎么生成的。

1.4对象树

在1.1写的那个代码,我是没有释放的,会导致内存泄漏吗?不会的

如果我不去new呢?在栈上创建,不显示hello world?此时的label对象随着构造函数的结束就销毁了。

所以把label对象交给对象树是最合理的。

演示自动释放的过程

重新创建一个项目,并创建新的class

这里就会多出来两个:

这里的目的就是在析构函数中我们要看到的确是被析构了,这里在主函数调用之后:

被打印出来就说明析构函数确实的执行了,虽然没有显示的delete,但是挂到了对象树中,窗口被销毁的时候,就会自动的销毁所有的对象。

1.5 中文乱码

这里使用qDebug代替cout

cout对编码的处理不太好,这里在qDebug内部直接就帮我们调试好了。

1.6 Qt窗口坐标系

坐标体系:以左上角为原点(0,0),X向右增加,Y向下增加。

对于嵌套窗口,其坐标是相对于父窗口来说的。

示例:使用Qt中的坐标系设置控件的位置;

二. 信号和槽

2.1 信号和槽的概念

在 Qt 中,用户和控件的每次交互过程称为一个事件。比如 "用户点击按钮" 是一个事件,"用户关闭窗口" 也是一个事件。每个事件都会发出一个信号,例如用户点击按钮会发出 "按钮被点击" 的信号,用户关闭窗口会发出 "窗口被关闭" 的信号。

Qt 中的所有控件都具有接收信号的能力,一个控件还可以接收多个不同的信号。对于接收到的每个信号,控件都会做出相应的响应动作。例如,按钮所在的窗口接收到 "按钮被点击" 的信号后,会做出 "关闭自己" 的响应动作;再比如输入框自己接收到 "输入框被点击" 的信号后,会做出 "显示闪烁的光标,等待用户输入数据" 的响应动作。在 Qt 中,对信号做出的响应动作就称之为槽。

信号和槽是 Qt 特有的消息传输机制,它能将相互独立的控件关联起来。比如,"按钮" 和 "窗口" 本身是两个独立的控件,点击 "按钮" 并不会对 "窗口" 造成任何影响。通过信号和槽机制,可以将 "按钮" 和 "窗口" 关联起来,实现 "点击按钮会使窗口关闭" 的效果。

信号是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定事件,这时 Qt 对应的窗口类会发出某个信号,以此对用户的操作做出反应。因此,信号的本质就是事件。如:

・按钮单击、双击・窗口刷新
・鼠标移动、鼠标按下、鼠标释放
・键盘输入


那么在 Qt 中信号是通过什么形式呈现给使用者的呢?

・我们对哪个窗口进行操作,哪个窗口就可以捕捉到这些被触发的事件。
・对于使用者来说触发了一个事件我们就可以得到 Qt 框架给我们发出的某个特定信号。
・信号的呈现形式就是函数,也就是说某个事件产生了,Qt 框架就会调用某个对应的信号函数,通知使用者。
在 Qt 中信号的发出者是某个实例化的类对象。

槽的本质

槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的 C++ 函数是一样的,可以定义在类的任何位置(public、protected 或 private),可以具有任何参数,可以被重载,也可以被直接调用(但是不能有默认参数)。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

说明
(1)信号和槽机制底层是通过函数间的相互调用实现的。每个信号都可以用函数来表示,称为信号函数;每个槽也可以用函数表示,称为槽函数。例如:"按钮被按下" 这个信号可以用 clicked () 函数表示,"窗口关闭" 这个槽可以用 close () 函数表示,假如使用信号和槽机制实现:"点击按钮会关闭窗口" 的功能,其实就是 clicked () 函数调用 close () 函数的效果。
(2)信号函数和槽函数通常位于某个类中,和普通的成员函数相比,它们的特别之处在于:
・信号函数用 signals 关键字修饰,槽函数用 public slots、protected slots 或者 private slots 修饰。signals 和 slots 是 Qt 在 C++ 的基础上扩展的关键字,专门用来指明信号函数和槽函数;
・信号函数只需要声明,不需要定义(实现),而槽函数需要定义(实现)。

信号函数的定义是 Qt 自动在编译程序之前生成的。编写 Qt 应用程序的程序员无需关注。

这种自动生成代码的机制称为元编程(Meta Programming)。这种操作在很多场景中都能见到。

2.2 信号和槽的使用

2.2.1 连接信号和槽

在 Qt 中,QObject 类提供了一个静态成员函数 connect() ,该函数专门用来关联指定的信号函数和槽 函数。

关于 QObject
QObject 是 Qt 内置的父类。Qt 中提供的很多类都是直接或者间接继承自 QObject。

这一点的设定和 Java 是非常相似的。

简单的使用代码

点击就会关闭

这里就需要注意一个东西了,第二个和第三个参数是const char*类型,但是我们传的都是函数指针类型,这在C++中肯定是不行的。在原来的QT肯定是不行的,需要传入宏对函数指针做解析,转换成const char*类型:

connect(button,SIGNAL(&QPushButton::clicked),this,SLOT(&Widget::close));

Qt5开始就对这种写法做了简化,给connect提供了重载版本,第二个第四个参数成为了泛型,允许传入任意指针的类型了。

2.2.2 查看信号和槽

系统自带的信号和槽通常是通过 “Qt 帮助文档” 来查询。

如上述示例,要查询 “按钮” 的信号,在帮助文档中输入:QPushButton,

  • 首先可以在 “Contents” 中寻找关键字 signals,
  • 如果没有找到,继续去父类中查找。因此我们去它的父类 QAbstractButton 中继续查找关键字 signals。

这里的clicked()就是要找的信号。槽函数的寻找方式和信号一样,只不过它的关键字是slot。

2.2.3 通过 Qt Creator生成信号槽代码

在 UI 设计窗口中拖入一个 "按钮" ,并且修改 "按钮" 的名称及字体大小等;

可视化生成槽函数:

当单击 "转到槽..." 之后,出现如下界面:对于按钮来说,当点击时发送的信号是:clicked (),所以此处选择:clicked ()

在"widget.h"头文件中自动添加槽函数的声明;

在"widget.cpp"中自动生成槽函数定义.

在槽函数函数定义中添加要实现的功能.实现关闭窗口的效果.

注意如果用这种方式的话,是不需要去显示的connect的,可以根据名字on_pushButton_clicked就可以直接关联号新号和槽了,因为pushButton是名字,clicked是信号(可以根据名字搜索),这个函数本身就是槽

2.3 自定义信号和槽

2.3.1 基本语法

在 Qt 中,允许自定义信号的发送方以及接收方,即可以自定义信号函数和槽函数。但是对于自定义的信号函数和槽函数有一定的书写规范。

1、自定义信号函数书写规范
(1)自定义信号函数必须写到 "signals" 下;
(2)返回值为 void,只需要声明,不需要实现
(3)可以有参数,也可以发生重载;

2、自定义槽函数书写规范
(1)早期的 Qt 版本要求槽函数必须写到 "public slots" 下,但是现在高级版本的 Qt 允许写到类的 "public" 作用域中或者全局下;
(2)返回值为 void,需要声明,也需要实现
(3)可以有参数,可以发生重载;

3、发送信号
使用 "emit" 关键字发送信号。"emit" 是一个空的宏。"emit" 其实是可选的,没有什么含义,只是为了提醒开发人员。

Widget.h中:

Widget.cpp中,注意要使用emit发送信号:

这里的标题也就变了:

还可以利用ui来创建一个按钮,用点击按钮的信号来发送我们自己的信号:

可以通过名字on_pushButton_clicked自动建立connect,不用我们去connect:

点击之后:

2.3.2 带参数的信号和槽

Qt 的信号和槽也支持带有参数,同时也可以支持重载。

此处我们要求,信号函数的参数列表要和对应连接的槽函数参数列表一致。

此时信号触发,调用到槽函数的时候,信号函数中的实参就能够被传递到槽函数的形参当中。

通过这样的机制,就可以让信号给槽传递数据了

槽函数实现:

2.4其他说明

2.4.1 信号和槽的断开

ui中创建两个按钮,一个按钮专门负责断开另一个按钮的连接:

        注意如果不去disconnect的话,这里的信号就会绑定两个槽,都会执行。

2.4.2使用lambda定义槽函数

button是new出来的对象,直到窗口关闭才会释放。

2.5 信号与槽的优缺点

优点:松散耦合
信号发送者不需要知道发出的信号被哪个对象的槽函数接收,槽函数也不需要知道哪些信号关联了自己,Qt 的信号槽机制保证了信号与槽函数的调用。支持信号槽机制的类或者父类必须继承于 QObject 类。

缺点:效率较低
与回调函数相比,信号和槽稍微慢一些,因为它们提供了更高的灵活性,尽管在实际应用程序中差别不大。通过信号调用的槽函数比直接调用的速度慢约 10 倍(这是定位信号的接收对象所需的开销;遍历所有关联;编组 / 解组传递的参数;多线程时,信号可能需要排队),这种调用速度对性能要求不是非常高的场景是可以忽略的,是可以满足绝大部分场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/94876.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/94876.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

河南萌新联赛2025第(七)场:郑州轻工业大学

河南萌新联赛2025第(七)场:郑州轻工业大学 If I only could, Id be running up that hill!郑轻有品!背景终于不是二次元了… 是Stranger Things!希望我能像主题曲里那样,勇攀高峰,R…

Java 获取淘宝商品详情(item get)API 接口实战指南

在电商领域,获取商品详情数据对于市场分析、价格监控、用户体验优化等场景具有重要意义。淘宝作为国内领先的电商平台,提供了丰富的 API 接口供开发者使用,其中 taobao.item.get 和 taobao.item.get_pro 接口可以用来获取商品的详细信息。本文…

配送算法17 AFramework for Multi-stage Bonus Allocation in meal delivery Platform

AFramework for Multi-stage Bonus Allocation in meal delivery Platform本文针对美团每日数十万单因无人接单而被取消的痛点,提出“多阶段动态奖金分配”框架:先用半黑盒模型预估奖金—接单概率关系,再用拉格朗日对偶动态规划离线算出阶段乘…

Python DELL Logo

写在前面 Python绘制Android Studio标志的完整代码。 系列文章 序号文章目录直达链接炫酷系列1无法拒绝的表白界面https://want595.blog.csdn.net/article/details/1347448942满屏飘字表白代码https://want595.blog.csdn.net/article/details/1350373883无限弹窗表白代码http…

【架构师干货】软件工程

1. 软件工程概述 软件工程基本原理 软件工程基本原理:通过划分生命周期阶段的方式严格管理、坚持进行阶段评审、实现严格的产品控制、采用现代程序设计技术、结果应能清楚地审查、开发小组的人员应少而精、承认不断改进软件工程实践的必要性。 软件开发生命周期 软件…

3.渗透-.IP地址-详解

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于:易锦网校 上一个内容:2.渗透-.WEB运行原理-ZBlog安装(进一步理解数据库) ip地址是互联网中的门牌号…

【数字投影】简单介绍数字展厅内投影融合技术的原理

投影融合技术 https://www.bmcyzs.com/ 是一种将多台投影机的画面无缝拼接成一个完整、统一的高分辨率大画面的技术。它的核心原理在于通过几何校正与边缘羽化等处理,消除设备间的物理缝隙与亮度差异,从而实现视觉上的完美一体化。这一过程高度依赖于专业…

UML状态图中entry/do/exit动作的深入解析与C/C++实现

<摘要> 本文将深入探讨UML状态图中entry、do和exit动作的概念、作用及实现方式&#xff0c;通过astah工具展示如何专业地建模这些元素&#xff0c;并提供完整的C/C代码实现解析。文章包含具体案例和最佳实践&#xff0c;帮助开发者掌握状态机设计的精髓。 <解析> U…

Vue3 Pinia 中 store.$dispose()的用法说明

在 Vue 3 的 Pinia 中&#xff0c;store.$dispose()方法用于手动销毁一个 store 实例&#xff0c;它会重置该 store 的状态并移除所有订阅&#xff08;如通过 $subscribe或 $onAction添加的监听器&#xff09;。如果你发现调用 store.$dispose()后没有达到预期效果&#xff0c;…

Java自定义程序使用Ollama实现本地ai调用

Ollama 提供 两套核心接口、三种常见输入风格、两种输出模式&#xff0c;你可以按需组合。 一、两套核心接口 /api/generate • 一问一答&#xff0c;无对话历史。 • 输入&#xff1a;单次 prompt&#xff0c;可选参数&#xff08;temperature、top_p、max_tokens …&#xff…

操作系统中的死锁是什么意思

问题操作系统中的死锁是什么意思我的回答死锁是指在操作系统中&#xff0c;两个或多个进程互相等待对方释放资源&#xff0c;导致这些进程都无法继续执行的一种状态。简单来说&#xff0c;就像两个人相互礼让过马路&#xff0c;结果谁也不肯先走&#xff0c;最后都卡在那里一样…

DA14531(Cortex-M0+)之Wake-up Interrupt Controller (WIC)

Wake-up Interrupt Controller (WIC) to allow the processor to be powered down during sleep, while interrupt sources are still allowed to wake up the system. 唤醒中断中断器&#xff0c;允许处理器休眠时关闭电源和时钟&#xff0c;但中断源可以唤醒系统。具备独立的…

实战演练(一):从零构建一个功能完备的Todo List应用

实战演练&#xff08;一&#xff09;&#xff1a;从零构建一个功能完备的Todo List应用 作者&#xff1a;码力无边各位React探险家&#xff0c;欢迎集结&#xff01;我是你们的向导码力无边&#xff0c;这里是《React奇妙之旅》的第六站&#xff0c;也是我们基础阶段的“毕业大…

GitHub 宕机自救指南:确保开发工作不间断

1.1 GitHub 宕机事件回顾 在 2025 年 8 月&#xff0c;GitHub 经历了一次全球性的重大故障事件&#xff0c;此次宕机持续了数小时&#xff0c;对全球范围内依赖 GitHub 进行代码托管、协作开发的团队和个人造成了严重影响。众多开源项目的代码提交陷入停滞&#xff0c;企业级开…

RK3588 android12 DDR开发指南相关记录

一&#xff0c;DDR打印信息 DDR 打印信息包括 loader 中的打印和 kernel 中的打印&#xff0c;loader 中打印的解析如下&#xff1a;DDR Version 1.05 20170712// DDR 初始化代码的版本信息&#xff0c;用于核对版本。从这行开始&#xff0c;已经进入DDR初始化代码 In SRX // 有…

Docker 部署 GitLab 并开启 SSH 使用详解

在日常使用 GitLab 时&#xff0c;很多人习惯通过 SSH 协议 而不是 HTTPS 来拉取与推送代码。但是在使用 Docker 部署 GitLab 的过程中&#xff0c;经常遇到 SSH 端口未开放、只能本地访问、客户端无法连接 等问题。本文将从零开始&#xff0c;详细讲解如何在 Docker 中正确开启…

C/C++---前缀和(Prefix Sum)

在C算法与数据结构领域&#xff0c;前缀和是一种时间复杂度优化利器&#xff0c;尤其适用于频繁查询数组区间和的场景。它通过预先计算“前缀累积和”&#xff0c;将原本O(n)时间的区间和查询压缩至O(1)&#xff0c;是面试、竞赛及工程开发中高频使用的基础技巧。 一、前缀和的…

[n8n] 全文检索(FTS)集成 | Mermaid图表生成

第5章&#xff1a;全文检索(FTS)集成 在前一章中&#xff0c;我们构建了REST API服务作为数据访问入口。 本章将介绍全文检索(FTS)集成&#xff0c;它如同智能搜索引擎&#xff0c;为工作流系统提供高效灵活的检索能力。 核心架构 前文传送&#xff1a; 技术选型 SQLite …

用户模式与内核模式:操作系统的“权限双轨制”

要理解用户模式与内核模式&#xff0c;首先需要明确一个核心概念——进程&#xff08;Process&#xff09;。我们日常用C语言编译生成的.exe文件&#xff0c;本质是“存储在磁盘上的静态程序”&#xff1b;当它被加载到内存并开始运行时&#xff0c;就转化为“动态活动的进程”…

探索 Vertex AI 与 Elasticsearch

作者&#xff1a;来自 Elastic Jhon Guzmn 了解如何将 Vertex AI 与 Elasticsearch 集成来创建 RAG 应用。按照本教程配置一个 Gemini 模型并在 Kibana 的 Playground 中使用它。 更多阅读&#xff1a; Elasticsearch&#xff1a;在 Elastic 中玩转 DeepSeek R1 来实现 RAG …