首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
【Qt】Qt编程须知
📅 2026/10/8 18:34:12
✍️ 爱科研究院
👁 阅读 3,247
个人主页 Mercury 学习方向 C/C方向学习者⭐ 人生格言给时光以生命而不是给生命以时光 目录一、Qt 中的命名规范二、Qt Creator 中的常用快捷键三、学会使用帮助文档3.1 打开帮助文档的三种方式3.2 帮助文档使用示例四、认识对象模型对象树4.1 什么是对象树4.2 QWidget 与对象树4.3 对象树如何解决内存问题4.4 两个代码片段一个正确一个崩溃4.5 代码示例亲手验证对象树五、Qt 窗口坐标体系总结一、Qt 中的命名规范Qt 对类名、函数名和变量名有一套统一的命名风格类名首字母大写单词和单词之间的首字母也大写函数名及变量名首字母小写单词和单词之间的首字母大写。Qt 偏好驼峰命名法类名用大驼峰如QPushButton、MyLabel函数和变量用小驼峰如setText、btn1。这一点不像咱们之前课堂上偏好的蛇形命名set_text。写 Qt 代码时建议跟着它的风格走。二、Qt Creator 中的常用快捷键Qt Creator 提供了一批常用快捷键熟练使用能明显提升开发效率功能快捷键注释 / 取消注释Ctrl /运行Ctrl R编译构建Ctrl B字体缩放Ctrl 鼠标滚轮查找Ctrl F整行上移 / 下移Ctrl Shift ↑ / ↓帮助文档F1自动对齐格式化Ctrl i同名 .h 和 .cpp 切换F4生成函数声明的对应定义Alt Enter两个最该先记住的Alt Enter在头文件里写好函数声明光标放上去按它就能自动在 .cpp 里生成函数定义骨架Ctrl i代码排版乱了全选后按它自动对齐。三、学会使用帮助文档Qt 自带非常完善的帮助文档实际编程中遇到不熟悉的类或方法查文档是最直接的办法。3.1 打开帮助文档的三种方式方式 1光标定位 F1把光标放到要查询的类名 / 方法名上直接按F1就会跳转到对应的文档页面。方式 2点击左侧边栏的帮助按钮在 Qt Creator 左侧边栏中用鼠标单击帮助按钮点击帮助之后会进入帮助界面。左上角有个查找框Look for在那里输入要查找的类或方法即可方式 3直接运行 assistant.exe找到 Qt 的安装路径在bin文件夹下找到assistant.exe双击打开打开后就是 Qt 助手的界面它和方式 2 看到的是同一套文档3.2 帮助文档使用示例下面以查询QPushButton按钮控件为例演示怎么读一个类的文档。第 1 步新建一个项目准备使用 QPushButton 控件第 2 步打开帮助手册在索引中输入QPushButton。用索引查找的小技巧选择索引查找时只需输入前缀后面的内容会自动补齐。比如输入Qpush列表里就会过滤出 QPushButton鼠标左键双击即可进入。进入 QPushButton 的文档页面后页面开头有几条最关键的信息Header头文件#include QPushButton使用这个类需要包含的头文件qmake模块QT widgets使用这个类需要在 .pro 中引入的模块Inherits继承自QAbstractButton该控件继承自哪个类Inherited By被谁继承QCommandLinkButton该控件又被哪些类继承。⚠️建议不要使用中文文档阅读英文文档是每个程序员必备的专业技能必须练不能退缩。Qt 的文档从通俗易懂的角度来说是技术类文档中非常出类拔萃的只要稍微有点耐心基本都能读懂个八九不离十。咱们后续学习中也会经常翻阅文档。四、认识对象模型对象树在 Qt 中创建很多对象时都会让我们提供一个 Parent父对象指针。这个 parent 到底是干什么的这就要理解 Qt 的对象树机制。4.1 什么是对象树QObject 是以对象树的形式组织起来的当创建一个 QObject 对象时它的构造函数会接收一个 QObject 指针作为参数这个参数就是parent父对象指针这相当于在创建对象时提供一个父对象我们创建的这个对象会自动添加到父对象的children()列表中当父对象析构时这个列表中的所有对象也会被析构。注意这里的父对象不是继承意义上的父类对象树里的 parent 指的是对象之间的包含/归属关系和 C 语法上的父类基类完全是两回事。一个是运行时对象的树形组织一个是类的继承体系。这种机制在 GUI 程序设计中相当有用。例如一个按钮有一个 QShortcut快捷键对象作为它的子对象当删除按钮的时候这个快捷键理应也被删除这是合理的。4.2 QWidget 与对象树QWidget 是能够在屏幕上显示的一切组件的父类这里指继承意义上的父类QWidget 继承自 QObject因此也继承了这种对象树关系一个孩子自动成为父组件的一个子组件它会显示在父组件的坐标系统中被父组件的边界剪裁例如用户关闭一个对话框时应用程序将其删除那么属于这个对话框的按钮、图标等也应该一起被删除——事实就是如此因为它们都是对话框的子组件当然我们也可以自己删除子对象它们会自动从其父对象列表中删除。比如删除一个工具栏时其所在的主窗口会自动把它从子对象列表删除并自动调整屏幕显示。4.3 对象树如何解决内存问题Qt 引入对象树的概念在一定程度上解决了内存问题当一个 QObject 对象在堆上创建时Qt 会同时为其创建一个对象树。不过对象树中对象的顺序是没有定义的销毁这些对象的顺序也未定义任何对象树中的 QObject 对象 delete 时如果这个对象有 parent则自动将其从 parent 的children()列表中删除如果该对象有孩子则自动 delete 每一个孩子Qt 保证没有 QObject 会被 delete 两次这是由析构顺序决定的。如果 QObject 在栈上创建Qt 保持同样的行为正常情况下也不会发生什么问题。4.4 两个代码片段一个正确一个崩溃片段 1正确{QWidget window;QPushButtonquit(Quit,window);}作为父组件的 window 和作为子组件的 quit 都是 QObject 的子类事实上它们都是 QWidget 的子类而 QWidget 是 QObject 的子类。这段代码是正确的标准 C 要求局部对象的析构顺序按照创建顺序的相反过程所以在超出作用域时会先调用 quit 的析构函数将其从父对象 window 的子对象列表中删除然后才调用 window 的析构函数。quit 的析构函数不会被调用两次。片段 2崩溃{QPushButtonquit(Quit);QWidget window;quit.setParent(window);}这段代码的析构顺序就出了问题作为父对象的 window 是最后一个创建的所以会首先被析构在 window 析构过程中会调用子对象列表中每个对象的析构函数于是quit 此时被析构了但 quit 也是一个局部变量在超出作用域时它当然也需要析构这已经是第二次调用 quit 的析构函数了C 不允许调用两次析构函数因此程序崩溃。养成良好习惯重要对象树虽然在一定程度上解决了内存问题但也引入了一些值得注意的细节今后开发中很可能时不时跳出来烦你一下。所以最好从一开始就记住在 Qt 中尽量在构造的时候就指定 parent 对象并且大胆在堆上创建。Qt 对象树的整体结构如图4.5 代码示例亲手验证对象树下面通过一个完整示例观察构造、析构函数的调用顺序。第 1 步创建一个QWidget新项目第 2 步再添加新文件第 3 步在弹出的窗口中左侧选择 “C”中间选择 “C Class”点击 “Choose…”第 4 步在 Define Class 界面填写信息Class name类名输入要创建的类名Base class基类选择要继承的基类下方的 Include 选项会根据基类自动勾选Header file / Source file自动生成的头文件名和源文件名Path文件存放路径。第 5 步点击下一步进入 Project Management 界面确认文件会被添加到当前 .pro 工程中点击完成第 6 步点击完成后手动创建的头文件和源文件会自动添加到目标工程中第 7 步修改头文件。把包含的头文件改成QPushButton把继承的基类改成 QPushButton并手动添加析构函数声明#ifndefMYPUSHBUTTON_H#defineMYPUSHBUTTON_H#includeQPushButton// 修改头文件classMyPushButton:publicQPushButton// 修改所继承的基类{Q_OBJECTpublic:explicitMyPushButton(QWidget*parentnullptr);// 默认提供的构造函数~MyPushButton();// 手动添加的析构函数};#endif// MYPUSHBUTTON_H第 8 步编写源文件。包含QDebug在构造、析构函数中分别打印日志#includemypushbutton.h#includeQDebug// Qt 中用来在屏幕输出信息的头文件MyPushButton::MyPushButton(QWidget*parent):QPushButton(parent){qDebug()我的按钮的构造函数被调用;}MyPushButton::~MyPushButton(){qDebug()我的按钮的析构函数被调用;}第 9 步编译并运行。弹出窗口的同时应用程序输出栏会打印构造函数中的信息第 10 步关闭弹出的对话框就会自动调用按钮的析构函数打印析构信息第 11 步在widget.cpp中创建按钮对象、命名并通过setParent(this)挂到对象树上同时给 Widget 的析构函数加上日志#includewidget.h#includemypushbutton.h// 包含自己创建类的头文件#includeQDebugWidget::Widget(QWidget*parent):QWidget(parent){MyPushButton*btnnewMyPushButton;// 创建按钮对象btn-setText(我的按钮);// 给按钮命名btn-setParent(this);// 设置到对象树中窗口关闭时自动调用其析构函数}Widget::~Widget(){qDebug()Widget的析构函数被调用;}第 12 步观察执行结果。结果分析对象树确保的是先释放子节点的内存再释放父节点的内存而析构函数的调用顺序不一定遵守上述要求因此可能看到子节点的析构执行顺序反而在父节点析构顺序之后调用析构函数 ≠ 释放内存注意调用析构函数和释放内存并非是同一件事情。对象树保证的是内存释放的先后先子后父而析构函数体的打印顺序可能与之不同不要把两者混为一谈。五、Qt 窗口坐标体系Qt 的窗口使用一套统一的坐标规则坐标规则以窗口左上角为原点 (0,0)X 向右增加Y 向下增加。这和数学课本里 Y 轴向上的习惯相反要特别注意。对于嵌套窗口其坐标是相对于父窗口来说的。示例使用坐标设置控件位置在widget.cpp中创建两个按钮按钮 1 通过move(200, 300)设置坐标按钮 2 不做设置然后用x()、y()打印它们的坐标#includewidget.h#includeui_widget.h#includeQPushButton// 添加按钮头文件#includeQDebugWidget::Widget(QWidget*parent):QWidget(parent),ui(newUi::Widget){ui-setupUi(this);QPushButton*btn1newQPushButton(按钮1,this);// 创建按钮1btn1-move(200,300);// 设置按钮1的坐标QPushButton*btn2newQPushButton(按钮2,this);// 创建按钮2qDebug()按钮1的坐标为[btn1-x(),btn1-y()];qDebug()按钮2的坐标为[btn2-x(),btn2-y()];}Widget::~Widget(){deleteui;}运行结果按钮 1 出现在 (200, 300) 的位置按钮 2 没有移动、默认在左上角 (0, 0)总结本文整理了 Qt 编程中需要尽早养成的几个习惯和基础知识命名规范类名大驼峰、函数和变量小驼峰Qt 整体偏好驼峰命名常用快捷键注释Ctrl/、运行CtrlR、编译CtrlB、帮助F1、自动对齐Ctrli、切换 .h/.cppF4、生成定义AltEnter帮助文档可通过 F1、左侧帮助按钮、运行 assistant.exe 三种方式打开查类时重点看 Header、qmake、Inherits、Inherited By坚持读英文文档对象树QObject 通过 parent 组织成树对象自动加入父对象的 children() 列表父对象析构时子对象一并析构Qt 保证对象不会被 delete 两次栈上对象要注意创建/析构顺序否则可能像片段 2 一样崩溃最佳实践是构造时就指定 parent、尽量在堆上创建析构函数调用和内存释放不是同一件事坐标体系左上角为原点X 向右、Y 向下嵌套窗口坐标相对于父窗口可用move()设置、x()/y()读取。这些细节看起来零碎但都是后面写任何 Qt 程序都会反复用到的基本功建议跟着示例亲手敲一遍。如果对你有帮助欢迎点赞收藏关注~ 有问题欢迎在评论区交流
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/8 18:34:12
vivado添加dcp网表文件到工程中的方法
2026/10/8 18:34:12
LitePan 备份与恢复:重装和多设备迁移更省心
2026/10/8 18:34:12
一卷3D打印PETG线材,为什么登上了巴黎时装周?
2026/10/8 19:24:21
gsd-2 技能库实战:React 最佳实践中“延迟 await“(Defer Await Until Needed)消除非必要异步阻塞
2026/10/8 19:24:21
趣博思AI官网在做一个“反直觉”的决定:不让你一键生成
2026/10/8 19:24:21
趣博思AI官网,像一个把论文写作拆成“零件”的工具箱
2026/10/8 19:24:21
趣博思 AI 科普|避开终稿排版五大隐形陷阱,用 AI 完成论文全稿规范审查
2026/10/8 19:24:20
DO-160G 流体敏感性试验:机载设备抗油液侵蚀的适航验证
2026/10/8 19:19:20
Quartz.NET + .NET Aspire AppHost 实战:声明式编排、持久化 Postgres 作业库与密码固定策略
2026/10/8 0:04:11
Agent Skills 完全指南:原理、写法、安装与实战避坑
2026/10/8 0:04:11
Agent Skills 实战:从 Genkit 定义到 GKE 部署与排查
2026/10/8 0:04:11
Agent Skills 实战:从设计到调试的完整指南
2026/10/8 5:02:14
Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化
2026/10/7 9:55:49
多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系
2026/10/7 14:02:03
hindsight:面向LLM应用的事后可观测性工程实践
2026/10/8 4:30:43
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/8 2:46:15
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/8 4:32:33
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)