news 2026/5/26 2:09:38

初识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/5/25 11:57:49

关于2025年银行业保险业信息科技非现场监管报表报送工作的通知 金科通〔2024〕162号

金融监管总局科技监管司关于2025年银行业保险业信息科技非现场监管报表报送工作的通知 金科通〔2024〕162号 各金融监管局,各政策性银行、大型银行、股份制银行、外资银行、直销银行、金融资产管理公司、理财公司,各保险集团(控股)公司、保险公司、保险资产管理公司:

作者头像 李华
网站建设 2026/5/26 5:35:52

接到紧急项目?XinServer 帮我稳住了现场

接到紧急项目?XinServer 帮我稳住了现场 上周三下午,我正喝着咖啡摸鱼,老板一个电话打过来:“老王,有个紧急的客户项目,两周后要演示,后台管理系统得搞定,你带人顶一下?”…

作者头像 李华
网站建设 2026/5/26 5:35:50

9、数据工作流管理与探索指南

数据工作流管理与探索指南 1. 数据工作流管理 1.1 工作流基础 在数据处理中,有时一个步骤可能会花费很长时间,或者你希望继续使用相同的数据,又或者数据来自有速率限制的 API。这时,让一个步骤将数据保存到文件,后续步骤对该文件进行操作是个不错的选择,这样可以避免冗…

作者头像 李华
网站建设 2026/5/25 6:22:43

12、分布式处理与数据建模实战

分布式处理与数据建模实战 1. 分布式处理基础 在分布式处理中,我们可以通过不同方式利用远程机器来完成任务,主要包括在远程机器上运行普通命令、直接在远程机器间分发本地数据以及将文件发送到远程机器进行处理并取回结果。 1.1 获取运行中的 AWS EC2 实例列表 若使用 A…

作者头像 李华
网站建设 2026/5/26 5:47:11

Python爬取ZLibrary元数据实战

技术文章大纲:用Python抓取ZLibrary元数据 概述 简要介绍ZLibrary及其元数据的价值,包括书名、作者、ISBN、出版日期等信息。说明Python在数据抓取中的优势,如高效、灵活和丰富的库支持。 准备工作 列出必要的工具和库: Pyth…

作者头像 李华
网站建设 2026/5/26 6:56:11

pyOCD又升级了,发布V0.42版本,月更(2025-12-18)

https://github.com/pyocd/pyOCD/releases 新功能 运行子命令: 1、引入新的运行子命令,支持按时间限制或直至文件结束符运行目标(适用于CI/CD工作流) 2、支持半主机控制台输出/输入及SWV输出 改进 标准I/O: 1、新增抽…

作者头像 李华