Qt项目文件以及对象树

"在哪里走散,你都会找到我~" 


        前篇,我们仅仅对Qt创建了第一个简单的项目。相比于使用其他IDE创建工程项目,Qt会为自动创建诸如:.pro、.h\.cpp、.iu等文件,这些文件到底是什么?我们在使用Qt时 应该怎样去看待?

——前言

Qt项目文件解析

(1) .pro文件        

        当我们将工程文件创建好了之后,在⼯程⽬录列表中有⼀个后缀为".pro" 的⽂件,这个“.pro”文件就是工程文件。它是由qmake自动产生的,用于生产makefile配置的文件。

什么是makefile?

一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。        

        makefile在Linux中使用得较为频繁,其工作目的就是完成源文件编译。在Qt Creator中已经把整个过程中的编译细节封装好了,对于使用者的我们来说,不用在意里面的内容:

(2) widget \main.cpp ⽂件解析

        当我们使用Qt Creator创建项目时,会自动为我们写好完整调用的main函数。

        在Qt中,着重强调类的封装。Qt ⼀个类对应⼀个头⽂件,类名 就是 头⽂件名。

QApplication 为应⽤程序类:
要想编写一个Qt的图形化界面程序,必须要有一个QApplication对象。

        除此之外,还会为我们创建在新建项目时,选择的“Widget”:

         

        这里提到了两个概念,一个是“Q_OBJECT”,另一个是“对象树”。

Q_OBJECT宏:

        这是一个Qt内置的一个宏。当代码被替换展开后,就是一堆代码块。Qt中一个很重要的机制就是“信号和槽”。如果想要使用这一个机制,就必须包含这个宏。

对象树:

        Qt中引入了“对象树”机制。这个树到底是做什么的呢?我们在这里就把它简单地认为是一个对象资源管理的机制。当我们创建一个Qt对象,就可以将它挂在对象树上,由它来控制这个资源的释放销毁。似乎同“垃圾回收”机制类似,但它对性能的影响很小。

                

(3) widget.ui ⽂件解析

        当我们点击这个文件时,Qt  Creator会为我们Qt Design上:

    当我们再次返回到编辑,点击这个.ui文件时,就会变成这样:

        如果你了解过前端,那么你看到这样神似的代码,似乎会联想到“.html”。不过,虽然它们极其相似,但.ui文件是由"xml"格式输写的。

        在xml中,有哪些标签,表示什么含义都是通过程序员自定义的。此处的xml中的标签,就是大佬们开发的专属Qt的标签。至于每个标签是啥含义呢,并不需要我们去关心,我们只需要知道.ui文件本质上是一个xml格式的文件即可。

        当我们对当前.ui文件进行编译,打开左上方项目的“展开Expoler”:
        找到同层目录下的新目录。这些以“build-xx”开头的新目录,这是我们将Qt程序启动后,自动生成的临时文件:
         我们打开ui文件:
        所以,ui文件的本质,最终会被Qt Creator翻译成C++文件,并编译到可执行程序之中。                  

        其中,我们还能看到由qmake自动生成的makefile。


Qt对象树

        在 Qt 中创建很多对象的时候会提供⼀个 Parent 对象指针,这些Parent指针都需要被进行构造,可是,为什么需要构造这些Parent指针呢?

        对于C\C++ 程序员而言,该语言为了追求性能,并没有提供类似“垃圾回收”的机制。所以,当使用程序申请堆上空间、或者是文件描述符、套接字等系统资源,需要由程序员手动回收。可是!只要是人工操作,就可能失误,就会出现申请的资源不能得到及时释放,从而让系统内的资源被占用,系统剩余资源越来越少,导致机器变卡甚至宕机……上述的种种,换句话说,也就是“资源泄露”。

(1) QObject

        在Qt中,QObject是对象模型的核心。它是以“对象树”的形式组织起来的。

🥪 当创建一个QObject对象时,会看到 QObject 的构造函数接收⼀个 QObject 指针作为参数,这个参数就是 parent,也就是⽗对象指针。

🥪 这相当于,在创建 QObject 对象时,可以提供⼀个其⽗对象,我们创建的这个 QObject 对象会⾃动添加到其⽗对象的 children() 列表。

🥪 当⽗对象析构的时候,这个列表中的所有对象也会被析构。

如何理解QWidget 是能够在屏幕上显⽰的⼀切组件的⽗类?                     

        QWidget 继承自QObject。当然不止QWidget,几乎所有的类对象都会去继承这个QObject。也是因为这种继承,也继承了这种对象树的关系。    

        使用对象树,把这些内容组织起来,等到合适的时机(窗口关闭\进程结束等等),把这些对象统一进行释放。

     

• Qt 引⼊对象树的概念,在⼀定程度上解决了内存问题。

释放规则:
🌯 当⼀个 QObject 对象在堆上创建的时候,Qt 会同时为其创建⼀个对象树,而对象树中对象的

顺序是没有定义的。
🌯  任何对象树中的 QObject 对象 delete 的时候,如果这个对象有 parent,则⾃动将其从 parent 的 children() 列表中删除;如果有孩⼦,则⾃动 delete 每⼀个孩⼦。

(2) 自定义类挂对象树        

        比如现如今,我们想要我们自定义的类MyLabel,继承QLabel,并尝试将其挂在对象树上:

         

 


Qt 窗⼝坐标体系 与 日志输出

        坐标体系:以左上⻆为原点(0,0),X向右增加,Y向下增加。其中(0,0)坐标的位置指的是Widget对象的左上角。

        我们在.ui文件中,能看到的“画板”,其本质上就是QWidget窗口:

         我们在这个窗口中添加一个"按钮Button":

        我们还可以通过代码的方式,创建一个Button,并把它显示在最终程序运行的窗口上:
 

         

编码问题:

        现在,我们想使用std::cout 作为日志输出打印在Qt Creator中的观察台中:

        我们会发现,从屏幕输出的文字完完全全是乱码!

        关于乱码的问题,有且仅有一个原因,就是编码方式不匹配!目前汉字字符集最常见的两种方式就是:UTF-8(utf8) 和 GBK。我们Windows简体中文版自带的就是按照GBK的编码方式,对汉字进行翻译的。相反Linux中,使用的汉字编码集为utf8。

GBK. 使用两个字节表示一个汉字。

UTF-8/utf8 变长编码。表示一个符号,使用的字节数有变化,2~4。但汉字一般又3个字节表示。

        因此,在Qt中如果想要通过打印日志的方式,观察程序、调试信息,最好使用Qt提供的qDebug。虽然cout也不是不能用,但是std::cout内部不会对编码作任何处理,在持有不同编码集中使用,会导致乱码;

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

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

相关文章

机器人顶会IROS,ICRA论文模板下载及投稿须知,以及机器人各大会议查询

一、背景 机器人方向,不止期刊TRO,TASE,RAM,RAL上的成果被认可,机器人顶会上的成果也是非常好的,一般来说一篇机器人顶会顶一篇trans。当决定要写一篇IROS论文时,结果IROS论文模板和投稿须知找…

Spring boot + Azure OpenAI 服务 1.使用 GPT-35-Turbo

Azure OpenAI 服务使用 GPT-35-Turbo 先决条件 maven 注意 beta.6 版本 <dependency><groupId>com.azure</groupId><artifactId>azure-ai-openai</artifactId><version>1.0.0-beta.6</version></dependency>问答工具类 pack…

从零学习Hession RPC

为什么学习Hessian RPC&#xff1f; 存粹的RPC&#xff0c;只解决PRC的四个核心问题&#xff08;1.网络通信2.协议 3.序列化 4.代理&#xff09;Java写的HessianRPC落伍了&#xff0c;但是它的序列化方式还保存着&#xff0c;被Dubbo(Hessian Lite)使用。 被落伍&#xff0c;只…

微信小程序(十三)生命周期-更新应用提醒

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.onLaunch用法 2.onShow用法 3.onHide用法 4.应用更新API的调用模板 源码&#xff1a; App({//小程序初始化时触发&#xff0c;全局只触发一次onLaunch(option) {//可以获取场景值和启动参数&#xff0c;eg.opt…

字符串相关的函数和内存块相关函数

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…

手势识别MATLAB代码

手势识别是智能设备常用的需求, 下面我们用MATLAB来识别手部的形态: 主程序main.m clc;clear all;close all;%清除命令行和窗口 imimread(DSC05815.JPG); [skin,bwycbcr,w,h] hand_segmentation(im); im1bwycbcr; % se strel(ball,[1 1 1;1 1 1;1 1 1]); im1 imdilate(im…

Go的基准测试

基准测试&#xff08;Benchmark&#xff09;是一项用于测量和评估软件性能指标的方法&#xff0c;主要用于评估你写的代码的性能。 基准测试的代码文件必须以_test.go结尾基准测试的函数必须以Benchmark开头&#xff0c;必须是可导出的基准测试函数必须接受一个指向Benchmark类…

【Docker】nacos集群搭建Nginx负载均衡

目录 一、mysql安装与基操 1.1 数据准备 1.2 创建mysql与数据表 二、Nacos集群部署 2.1 创建nacos及配置 2.2 创建Nginx容器 一、mysql安装与基操 1.1 数据准备 拉取mysql docker pull mysql:5.7(版本) 定义挂载目录 mkdir -p /mysql/{conf,data,script} 配置my.c…

37、WEB攻防——通用漏洞XSS跨站权限维持捆绑钓鱼浏览器漏洞

文章目录 XSS——后台植入Cookie&表单劫持&#xff08;获取明文密码&#xff09;XSS——Flash钓鱼配合MSF捆绑上线XSS——浏览器网马配合MSF访问上线 要想获取有效的cookie&#xff0c;需要&#xff1a;1、网站本身采用cookie进行验证&#xff1b;2、网站未做http-only等的…

[AG32VF407]国产MCU+FPGA 使用I2C测试陀螺仪MPU6050

视频讲解 [AG32VF407]国产MCUFPGA 使用I2C测试陀螺仪MPU6050 实验过程 查看原理图中定义的I2C的管脚&#xff0c;PB0和PB1 在board.ve中定义的引脚功能 I2C0_SDA PIN_36 I2C0_SCL PIN_35新建工程 测试代码 #include "board.h"#define MIN_IRQ_PRIORITY 1 #define …

一行命令在 wsl-ubuntu 中使用 Docker 启动 Windows

在 wsl-ubuntu 中使用 Docker 启动 Windows 0. 背景1. 验证我的系统是否支持 KVM&#xff1f;2. 使用 Docker 启动 Windows3. 访问 Docker 启动的 Windows4. Docker Hub 地址5. Github 地址 0. 背景 我们可以在 Windows 系统使用安装 wsl-ubuntu&#xff0c;今天玩玩在 wsl-ub…

Ubuntu系统中部署C++环境与Visual Studio Code软件

本文介绍在Linux Ubuntu操作系统下,配置Visual Studio Code软件与C++代码开发环境的方法。 在文章VMware虚拟机部署Linux Ubuntu系统的方法中,我们介绍了Linux Ubuntu操作系统的下载、安装方法;本文则基于前述基础,继续介绍在Linux Ubuntu操作系统中配置Visual Studio Code…