news 2026/6/10 15:16:44

初识QT -- 第一个QT程序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
初识QT -- 第一个QT程序

1.QT概述

什么是QT,QT是一个跨平台的C++图形用户界面应用程序框架。它可以为程序开发者提高建立图形化界面的所有功能。它是完全面向对象的,很容易进行扩展。QT为开发者提供了一种基于基础组件的开发模式,开发者可以通过简单的拖拽和组合来实现复杂的应用程序,同时也可以使用C++来进行更高级的开发。

图形化界面:指采用图像的方式显示计算机的用户操作界面,是计算机与使用者之间的对话接口。

2.设计一个QT程序

2.1使用图形化的方式实现一个按钮

这里在创建QT项目的时候要选择QWidegt,表示创建一个类来继承哪个类,这个创建出来的类就包含了基类的大部分功能。

创建项目以后进入到主界面是这样的

进入到图形设计界面,拖拽PushButton创建一个按键

回到主界面,编译代码并运行

2.2使用代码创建一个按钮

这里我们来到Widget.cpp的界面,为创建按钮写一部分代码

运行以后看到确实也出现了一个按钮。

虽然看起来两种方式不太一样,但本质上是一样的,我我们可以在项目文件夹种找到一个带有build开头加项目名称的文件,然后里面有一个ui_widget.h的文件

打开这个ui_widget.h的文件,可以看到系统已经为我们在ui_widget类中自动创建了一个PushButton的对象。这是QT的编译器使用qmake的方式根据xml来进行的一种元编程的方式,即通过一些代码帮我们自动生成C++代码的技术。

3.文件解析

在我们创建项目以后,QT自动为我们生成了许多文件,这里我们对其中的一些进行解析。

3.1widget.h文件解析

Q_OBJECT:这是一个QT的宏,这个宏允许使用信号和槽机制,后续我们会讲到。

QWidget:QWidget窗口类的头文件

UI::Widget *ui:通过这个指针可以访问UI设计界面中的任意控件。

在ui_widget.h文件中,UI::Widget是继承于UI_Widget这个UI设计界面类的,也就是代表UI::Widget能访问设计界面中公有的所有成员函数与成员变量。通过一个指针ui就能访问到UI设计界面的任意控件。

3.2widget.cpp解析

widget.cpp ⽂件是类 Widget 的实现代码,所有在窗体上要实现的功能添加在此⽂件中。

3.3widget.ui文件解析

widget.ui 是窗体界⾯定义⽂件,是⼀个 XML ⽂件,定义了窗⼝上的所有组件的属性设置、布局,及其信号与槽函数的关联等。⽤ UI 设计器可视化设计的界⾯都由 Qt ⾃动解析,并以 XML ⽂件的形式保存下来。在设计界⾯时,只需在 UI 设计器⾥进⾏可视化设计即可,⽽不⽤管 widget.ui ⽂件是怎么⽣成的。

4.认识对象模型(对象树)

4.1QObject 是以对象树的形式组织起来的。

在QT中创建很多对象的时候都要提供一个Parent对象指针,就例如:

这里传的this指针代表这两个对象将当前widget类作为他们的父对象了。为什么要创建一个父对象?

首先在我们创建PushButton这个按钮的时候我们并没有对它进行析构释放,这是否会造成内存泄漏?并不会,这就归咎于对象树的作用了。

当创建一个QObject对象的时候,QObject的构造函数会解释一个QObject指针作为参数初始化它的父对象指针。

也就是说在创建一个QObject对象的时候,显示的传递一个QObject指针,创建的这个对象就会自动被加入到父对象大的children()列表。

当整个程序执行完以后,窗口Widget会去释放自身,发现它还有子对象,就会先去调用子对象的析构函数。当所有子对象释放了,该父对象才会释放,也就保证了它的每一个子对象不需要显示的析构和释放。

这种机制在 GUI 程序设计中相当有⽤。例如,⼀个按钮有⼀个 QShortcut(快捷键)对象作为其⼦对象。当删除按钮的时候,这个快捷键理应被删除。这是合理的。

QPushButton源码中的构造:

4.2QWidget 是能够在屏幕上显⽰的⼀切组件的⽗类。

QWidget继承自QObject,因此它也继承了这种对象树的关系。一个孩子还自动成为父组件的一个子组件。因此,它会显⽰在⽗组件的坐标系统中,被⽗组件的边界剪裁。例如,当⽤⼾关闭⼀个对话框的时候,应⽤程序将其删除,那么,我们希望属于这个对话框的按钮、图标等应该⼀起被删除。事实就是如此,因为这些都是对话框的⼦组件。

当然,我们也可以⾃⼰删除⼦对象,它们会⾃动从其⽗对象列表中删除。⽐如,当我们删除了⼀个⼯具栏时,其所在的主窗⼝会⾃动将该⼯具栏从其⼦对象列表中删除,并且⾃动调整屏幕显⽰。

QWigdet的声明:

4.3QT引入对象树的概念,在一定程度上解决了内存泄漏的问题

当⼀个 QObject 对象在堆上创建的时候,Qt 会同时为其创建⼀个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。

任何对象树中的 QObject 对象 delete 的时候,如果这个对象有 parent,则⾃动将其从 parent 的children() 列表中删除;如果有孩⼦,则⾃动 delete 每⼀个孩⼦。Qt 保证没有 QObject 会被delete 两次,这是由析构顺序决定的。

如果在像在这样栈上创建两个对象,正常情况下不会发生什么问题

在C++中局部对象的析构顺序是按照创建顺序的相反顺序来的,此处quit先析构,将自己从qwindow的子对象列表删除,然后qwindow再析构,这是没有问题的。

但是如果是一下这种情况,就会出现析构两次quit的问题:

qwindow先定义首先会析构,然后去调用自己子对象中quit的析构,等quit析构完以后,此时quit还会进行一次它自己原本应该进行的析构,结果就会程序就崩溃了,quit析构了两次。

所以在QT中创建对象尽量在构造的时候就指定父对象,然后在堆上创建。

QT对象图

4.4代码演示-父对象自动析构子对象

创建一个新的类

指定继承的类

修改继承类和增加一个析构函数

定义析构函数和显示调试信息

在widget.h中创建一个按键并显示

编译与运行代码

这里MyPushButto继承QPushButton,使用了其父类的成员函数创建了一个按钮

关闭窗口的时候wiget先被析构,button被自动释放了。对象树确保的是先释放⼦节点的内存, 后释放⽗节点的内存。⽽析构函数的调⽤顺序则不⼀定遵守上述要求.。因此看到⼦节点的析构执⾏顺序反⽽在⽗节点析构顺序之后。

5.总结

通过本文的学习,我们正式推开了 Qt 开发的大门。我们不仅认识了 Qt 这个强大的跨平台 C++ 图形用户界面框架,还通过实战掌握了构建 Qt 程序的两个核心维度:

  1. 开发模式:无论是直观的 UI 设计器拖拽,还是灵活的纯代码编写,我们通过解析ui_widget.h等底层文件,明白了它们本质上殊途同归,最终都由 Qt 的元编程机制转化为标准的 C++ 代码。

  2. 核心机制:文章重点剖析了 Qt 的对象树(Object Tree)模型。这是 Qt 区别于普通 C++ 开发的重要特性,通过QObject的父子关系链,Qt 巧妙地实现了内存的自动回收,极大地降低了内存泄漏的风险。

理解对象树与文件结构,是成为一名合格 Qt 开发者的基石。掌握了这些基础,我们便有了构建更复杂、更健壮的 GUI 应用程序的能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 6:37:58

结合 AI 视觉:使用 OCR 识别企业微信聊天记录中的图片信息

一、 引言(Introduction) 业务背景: 许多关键业务信息(如:客户发送的转账截图、入群申请说明、包含联系方式的海报)都以图片形式存在于聊天记录中。 技术痛点: 传统的 UI 自动化只能获取“这是…

作者头像 李华
网站建设 2026/6/10 13:44:56

从零开始:Obsidian数据导入工具的完全掌握指南

从零开始:Obsidian数据导入工具的完全掌握指南 【免费下载链接】obsidian-importer Obsidian Importer lets you import notes from other apps and file formats into your Obsidian vault. 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-importer …

作者头像 李华
网站建设 2026/6/10 13:45:10

7、数据清洗与转换:从文本到结构化数据

数据清洗与转换:从文本到结构化数据 在数据处理过程中,清洗和转换数据是至关重要的步骤。本文将介绍一些常见的数据处理操作,包括过滤行、提取值、替换和删除值,以及处理不同格式的数据,如 CSV、HTML/XML 和 JSON。 过滤行 过滤行是数据清洗的第一步,它可以根据行的位…

作者头像 李华
网站建设 2026/6/10 15:03:52

11、并行管道:提升数据处理效率的利器

并行管道:提升数据处理效率的利器 在数据处理和分析的过程中,我们常常会遇到需要多次运行相同命令或管道的任务。例如,抓取数百个网页、进行数十次 API 调用并转换其输出、为一系列参数值训练分类器,或者为数据集中的每对特征生成散点图等。这些任务都涉及到一定形式的重复…

作者头像 李华
网站建设 2026/6/10 13:48:46

跨境电商深水区:价值增长新范式,重构出海增长逻辑

当亚马逊全球开店进入中国第十年,中国跨境电商的叙事已经彻底改写,行业从早期的规模铺货、中期的精细运营,迈入以价值创新与全球深耕为核心的高质量发展阶段,增长引擎,正从流量红利转向产品、市场、技术与本土化的深度…

作者头像 李华
网站建设 2026/6/10 15:03:38

Web图像标注解决方案:构建下一代交互式图像应用

Web图像标注解决方案:构建下一代交互式图像应用 【免费下载链接】annotorious Add image annotation functionality to any web page with a few lines of JavaScript. 项目地址: https://gitcode.com/gh_mirrors/an/annotorious 在数字化浪潮席卷各行各业的…

作者头像 李华