一、Qt 背景介绍
1、什么是 Qt
Qt 是一个跨平台的 C++ 图形用户界面应用程序框架。
它为应用程序开发者提供了建立艺术级图形界面所需的所有功能。它是完全面向对象的,很容易扩展。Qt 为开发者提供了一种基于组件的开发模式,开发者可以通过简单的拖拽和组合来实现复杂的应用程序,同时也可以使用 C++ 语言进行高级开发。
图形用户界面:指采用图形方式显示的计算机操作用户界面,是计算机与其使用者之间的对话接口,是计算机系统的重要组成部分。
如下是 Android 手机图形用户界面和 IOS 手机图形用户界面:
Android 桌面应用:
IOS 桌面应用:
2、Qt 的发展史
-
1991 年 Qt 最早由奇趣科技开发;。
-
1996 年进⼊商业领域,它也是目前流行的 Linux 桌面环境 KDE 的基础。
-
2008 年奇趣科技被诺基亚公司收购,Qt 成为诺基亚旗下的编程工具。
-
2012 年 Qt 又被 Digia 公司收购。
-
2014 年 4 月 跨平台的集成开发环境 Qt Creator3.1.0 发布,同年 5 月 20 日发布了 Qt 5.3 正式版,至此 Qt 实现了对 IOS、Android、Embedded 等各平台的全面支持。
3、Qt 支持的平台
- Windows —— XP、Vista、Win7、Win8、Win2008、Win10
- Unix / X11 —— Linux(主要是给服务器使用,服务器不需要图形化界面)、Sun Solaris、HP-UX、Compaq Tru64 UNIX、IBM AIX、SGI IRIX、FreeBSD、BSD/OS、和其他很多 X11 平台
- Macintosh —— Mac OS X
- Embedded —— 有帧缓冲支持的嵌入式 Linux 平台,Windows CE
- Android
4、Qt 版本
目前最新的版本是 Qt 6,但是相对来说 Qt 6 和 Qt 5 之间的核心功能区别不大,并且企业中也仍然有大量的项目在使用 Qt 5。因此后面我也仍然使用 Qt 5 版本来进行学习。
另外 Qt 在发布的时候还提供了两种许可证:
- 商业许可:开发者以商业目的使用 Qt 框架进行开发和发布软件的许可,开发者需要购买商业许可并按照相关规定使用 Qt 框架。商业许可提供了更多的功能和服务,适合于商业软件开发。
- 开源许可:开发者以非商业目的使用 Qt 框架进行开发和发布软件的许可,开发者可以免费使用 Qt 框架,但需要遵守开源许可协议的要求,如在软件中包含 Qt 许可协议的声明等。
5、Qt 的优点
-
跨平台,几乎支持所有的平台。
-
接口简单,容易上手,学习 QT 框架对学习其他框架有参考意义。
-
一定程度上简化了内存回收机制(半自动的垃圾回收,能够简化内存释放,也能够尽可能小的影响程序的运行效率)。
-
开发效率高,能够快速的构建应用程序。
-
有很好的社区氛围,市场份额在缓慢上升。
-
可以进行嵌入式开发。
6、Qt 的应用场景
(1)桌面应用程序
Qt 能够创建各种类型的桌面应用程序,包括文件管理器、媒体播放器、绘图程序等。Qt 应用程序支持多种操作系统,可以运行在 Windows、Linux、MacOS 等桌面操作系统上。
(2)移动应用程序
Qt 支持 Android 和 IOS 移动操作系统,为应用程序提供了强大的跨平台能力。可以使用 Qt 构建各种移动应用程序,例如社交应用、游戏、娱乐等。
(3)嵌入式系统
Qt 在嵌入式领域应用非常广泛,它可以构建面向各种设备的图形应用程序,在机顶盒、车载娱乐系统、安防监控设备等领域具有广泛的应用。
7、Qt 的成功案例
(1)Linux 桌面环境 KDE
Linux 桌面环境中存在好几套桌面环境:
- GNOME(基于 GTK 创建)
- KDE(基于 Qt 创建)
(2)WPS Office 办公软件
(3)Skype 网络电话
Skype 是一款即时通讯软件,其具备 IM 所需的功能,比如视频聊天、多人语音会议、多人聊天、传送文件、文字聊天等功能。它可以高清晰与其他用户语音对话,也可以拨打国内国际电话,无论固定电话、手机均可直接拨打,并且可以实现呼叫转移、短信发送等功能。
(4)Google Earth 谷歌地图
(5)VLC 多媒体播放器
(6)VirtualBox 虚拟机软件(VirtualBox 号称是最强的免费虚拟机软件)
8、Qt 的发展前景及就业分析
Qt 是一个强大且广泛应用于跨平台软件开发的框架。它提供了丰富的工具和库,可用于开发高质量、高效率的图形用户界面(GUI)应用程序。并且可以在 Windows、linux、macOS 等多种操作系统上运行。随着行业的发展,Qt 的重要性也逐渐体现出来,下面从行业发展方向、就业方面的发展前景以及就业薪资分析 Qt 的发展前景。
(1)行业发展方向
- 物联网(IoT)和嵌⼊式系统的发展:在当下的嵌入式和物联网行业中,Qt 的作用逐渐得到了体现,因为可以用它来开发具有 GUI 界面的嵌入式应用程序,这对于智能家居、汽车以及医疗设备等领域来说,具有非常重要的作用。
- 自动驾驶和智能交通领域:现在很多的汽车都引入了自动驾驶的技术,而 Qt 在其中也有着广泛的应用,它可以开发车载嵌入式系统和用户界面程序。随着未来⾃动驾驶技术的发展,Qt 在这方面的需求也会不断地增多。
- 游戏开发:Qt 有⼀些非常重要的功能模块,例如 Qt 3D Studio,可以应用于游戏开发。未来游戏行业的持续发展,Qt 在游戏行业的发展将会越来越多。
(2)就业方面的发展前景
A. 广泛的就业机会
Qt 在各个行业的应用逐渐广泛起来,对于掌握 Qt 开发能力的人员需求也在不断增加,因此在就业方面,相对比于其他行业来说,Qt 就业面更广,选择性更多。
B. 高薪水和职业发展机会
Qt 作为⼀项专业技能,掌握此项技术的开发者获得的薪资报酬也是非常可观的,具有更多的职业发展机会。总之就是,如果掌握了 Qt 开发技术,未来的发展前景还是非常不错的。
(3)就业薪资
二、搭建 Qt 开发环境
1、Qt 的开发工具概述
Qt 支持多种开发工具,其中比较常用的开发工具有:Qt Creator、Visual Studio、Eclipse。
(1)Qt Creator
Qt Creator 是一个轻量级的跨平台集成开发环境(IDE),专为使用 Qt 框架进行应用程序开发而设计。它是一个功能强大、易于使用、快速且高效的工具,被广泛用于编写各种类型的应用程序,如桌面应用程序、移动应用程序和嵌入式系统等。
Qt Creator 提供了一个可视化的界面设计器和代码编辑器,可以帮助开发者更快捷地创建复杂的用用界面和处理各种事件。它还包含了调试工具、版本控制工具、自动完成和智能提示等功能,以及⽀持多语言和跨平台的开发环境。
Qt Creator 的主要特点包括:
紧密集成的 Qt 框架:Qt Creator 专门为 Qt 开发而设计,因此它与 Qt 框架集成得非常紧密,使开发者可以更容易地管理和部署他们的应用程序。
强大的编辑器:Qt Creator 具有⼀些先进的编辑器功能,如语法高亮、代码折叠、智能提示、自动完成和代码重构。
集成的调试器:Qt Creator 内置了调试器,允许开发人员在代码中设置断点以及检查变量、堆栈和调用树等信息。
高效的构建系统:Qt Creator 提供了一个高效的构建系统,可以自动构建和部署应⽤程序,同时支持使用不同的编译器和平台。
可视化界面设计器:Qt Creator 具有⼀个可视化界面设计器,它允许开发人员在没有编写代码的情况下创建复杂的用户界面。
多语言支持:Qt Creator 支持多种编程语⾔,包括 C++、QML、JavaScript 等。
Qt Creator 是一个功能齐全、易于使用且高效的跨平台 IDE,适用于各种类型的应用程序开发,特别是那些使用 Qt 框架的开发者。
(2)Visual Studio
Visual Studio 是由微软公司开发的集成开发环境(IDE)。它可以用来开发多种类型的应用程序。包括 Windows 桌面应用程序、Web 应用程序、移动应用程序、游戏等。Visual Studio 提供了丰富的开发工具和功能,包括代码编辑器、调试器、自动完成、代码重构、版本控制等等。它支持多种编程语言,如:C++、C#、Visual Basic、F#、Python等。Visual Studio 还可以与其他开发工具和服务集成,如 Azure 云服务、GitHub、Jenkins 等。
Visual Studio 具有以下⼀些主要特点:
- 多语言支持:Visual Studio 支持多种编程语言,包括 C++、C#、Visual Basic、F#、Python、JavaScript 等。
- 丰富的工具集:VS 提供了各种开发工具,包括代码编辑器、调试器、代码分析工具等,以提高开发人员的效率。
- 可视化设计:VS 提供了可视化的设计工具,如窗体设计器、WPF 设计器等,使开发人员可以直观地设计用户界面。
- 跨平台开发:VS 支持跨平台开发,可以开发适用于 Windows、Linux 和 MacOS 等多个平台的应用程序;
- 集成的调试器:VS 集成了强大的调试器,可以进行代码的单步调试、断点调试等操作来帮助开发人员查找和修复错误。
- 丰富的扩展性:VS 可以通过安装扩展来扩展其功能,开发人员可以根据自己的需求选择并安装适合的扩展。
(3)Eclipse
Eclipse 是著名的跨平台的自由集成开发环境(IDE)。最初主要用来 Java 语言开发,但是目前亦有人通过插件使其作为其他计算机语言比如 C++ 和 Python 的开发工具。Eclipse 的本身只是一个框架平台,但是众多插件的支持使得 Eclipse 拥有其他功能相对固定的 IDE 软件很难具有的灵活性。许多软件开发商以 Eclipse 为框架开发自己的 IDE。Qt 框架可以与 Eclipse 集成,使开发者可以使用 Eclipse 的强大功能来开发 Qt 应用程序。
2、Qt SDK 的下载和安装
(1)Qt SDK 的下载
Qt 下载官网:Index of /archive/qt
国内清华源:Index of /qt/archive/qt/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror
进入官网,按如下图示进行相应的系统版本下载即可。
A. 打开官网链接
选择需要下载的版本(我以 5.14 版本为例)
现在点击之后是会出现 "Download from your IP address is not allowed",是因为 Qt5 离线安装包目前在国内已经被墙了,下载不了,只能下载在线安装包,直接访问就会显示上面的提示。(可以去网上找找资源)
B. 选择需要下载的版本
所选具体版本为:5.14.2
C. 选择 Windows 桌面应用程序
(2)Qt SDK 的安装
如果不想注册账号,那就在在双击之前先断网,否则需要注册 Qt 账号登录后才能进入下一步安装。
注意:选择安装路径时不能出现中文路径,否则即使安装上也无法正常使用。
3、Qt 环境变量配置
(1)找到 Qt 的安装路径,复制 "bin" 路径
(2)"此电脑" ——> 鼠标右键, "属性" ——> "高级系统设置" ——> "环境变量"
注意 :在关掉所有窗口时,⼀定要点击 “确定”,否则上述配置无效。
为什么要设置环境变量?
环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序将要使用到的信息。
例如 Windows 和 DOS 操作系统中的 path 环境变量,当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还会到 path 中指定的路径去找。
在 Windows 上设置 Qt 的环境变量是为了能够在命令行或其他应用程序中直接访问 Qt 相关的命令和工具。
4、验证 Qt SDK 安装是否成功
(1)双击打开 Qt Creator 工具,并进入到 “欢迎模式” 下的 “示例” 界面
(2)在 “示例” 中任选其中一个,单击打开该示例。在单击之后会弹出一个窗口,关闭即可
如果能构建并运行,说明安装无误。
运行结果如下图:
三、认识 Qt Creator
1、Qt Creator 概览
从开始菜单 / 快捷方式打开 Qt Creator 集成开发环境,启动之后看到类似下面的界面:
① 菜单栏
菜单栏一共有 8 个菜单选项,包含了常用的功能菜单:
② 模式选择
③ 构建套件选择器
构建套件选择器包含了目标选择器(Target selector)、运行按钮(Run)、调试按钮(Debug)和构建按钮(Building)四个图标。
④ 欢迎模式下的窗口工作方式
⑤ 定位器
使用定位器来快速定位项目、文件、类、方法、帮助文档以及文件系统。可以使用过滤器来更加准确地定位要查找的结果。
⑥ 输出窗格
输出窗格包含了问题、搜索结果(Search Results)、应用程序输出、编译输出、Debugger Console、概要信息、测试结果(Test Results)7 个选项,它们分别对应一个输出窗口,响应的快捷键依次是 Alt + 数字 1~7。
⑦ 会话记录
可以对会话进行管理,包括 Clone。如果没打开工程,则显示的是最后⼀次打开的(会话)工程,否则,显示当前的会话(工程)。
⑧ 新建项目
⑨ 打开已有项目
2、使用 Qt Creator 新建项目
(1)新建项目
打开 Qt Creator ,在菜单栏中选中: "文件" ——> "新建文件或项目" ;或者使用快捷键:Ctrl + n;或者直接点击:"new"
在欢迎模式下,直接点击 New,如下图所示:
(2)选择项目模板
弹出如下对话框:
新建项目对话框里有五类项目模板:
常用的只有第⼀类 Application,选择它之后,在右侧会看到 Qt 应用程序的五个子模板:
- Qt Widgets Application:普通窗体模板,传统基于部件的窗体界面程序。(如果使用 Qt 写一个 GUI 程序,就选择这个)
- Qt Console Application:Qt 控制台应用程序。因为 Qt 主要用于图形界面设计,这个控制台项目模板基本不用。
- Qt for Python:在 Python 下用 LGPL 的许可来开发闭源 Qt 软件。(不仅支持 C++,还支持 Python)
- Qt Quick Application:Qt 提供的⼀种高级用户界面技术,使用它可以方便快速的为移动以及嵌入式设备开发流畅美观的用户界面。Qt Quick 模块是开发 QML 应用的标准库,提供了使用 QML 创建用户界面所需的⼀切,包括可视化、交互、动画、模型、视图、粒⼦效果以及着色效果等。
选择不同的项目模板,Qt Creator 就会在后续项目创建好了之后生成不同的基础代码。
(3)选择项目路径
给 Qt 项目命名及选择保存项目的路径:
(4)选择构建系统
选择 Qt 项目的构建系统,通过 Qt 写的程序,涉及到一系列的 “元编程” 技术,通过代码来生成代码。
使用默认的 "qmake" 即可:
- qmake: qmake 是⼀个构建工具(build tool),用于自动生成 makefile 文件。qmake 支持跨平台构建。qmake 编辑的是⼀个后缀名为 .pro 的文件。
- CMake:CMake 是⼀个跨平台的构建工具。CMake 本身不是⼀个编译器,其实就是生成⼀个让编译器能读懂编译流程的⽂件工具。让 CMake 自动生成构建系统,例如 Makefile 和 Visual Studio 项目文件。CMake 是⼀个第三方工具,有自己的文档。(实际上 CMake 并非 Qt 专属,很多开源项目都会使用 CMake)
- Qbs:Qbs(Qt Build Suite:Qt构建套件)同 qmake、CMake ⼀样都是构建工具。Qbs 号称是新一代的构建⼯具,比 qmake 编译速度更快。Qbs 没有绑定 Qt 版本,它从项目文件的高级项目描述中生成⼀个正确的依赖表。而传统的 MakeFile 生成工具如 qmake 和 CMake ,其在生成 MakeFile 文件后将实际的命令交给 Make 工具去执行。
Qt 框架会在编译时自动先调用一系列的生成工具,基于我们自己写的代码生成一系列其它的 C++ 代码,最终编译的代码也是最后生成的这些代码。
Qt 官方声明:因市场原因,弃用 Qbs(新一代的 Qt 构造工具,但实际上使用的人很少)。
对于 Qt 用户来说,qmake 是当前使用最广泛的构建工具,CMake 其次。
(5)填写类信息设置界面
使用 Qt Creator 创建项目会自动生成一些代码出来,生成的代码就包含一个类,此处就是要选择这个自动生成的类的父类是什么。
对于基类的选择,目前有三种基类:
这里生成的文件名是和类名关联的,这样的关联并非是强制的(但推荐这么做)。
这个 Form file 非常关键,Qt 中创建图形化界面的程序有两种方式:
- 直接通过 C++ 代码的方式创建界面。
- 通过 Form file,以图形化的方式来生成界面。此时就可以使用 Qt Designer 或者直接使用 Qt Creator 来编辑这个 ui 文件,从而以图形化的方式快速方便的生成图像界面。
Qt 内置的类都是以 Q 为前缀开头的。
上述三个类之间的关系如下图:
(6)选择语言和翻译文件
点击 “下⼀步” 进入如下界面:
此处选择翻译文件(对应语言)是:“汉语”,“英语” 这样的语言,而不是 “编程语言”
由于我们暂时不考虑国际化问题,直接点击 “下一步” 即可。
(7)选择 Qt 套件
选择一下基于哪个编译器的 Qt SDK来构建后续代码。默认只有第一个 "Desktop Qt 5.14.2 MinGW 64-bit",如果安装配置了多个 Qt 套件,就可以都选择上。
Qt 套件是指:Qt 程序从编译链接到运行环境的全部工具和 Qt 类库的集合,对于 MinGW 版本 Qt 程序生成和调试,至少需要 MinGW 中的编译器 g++(自动调用链接器)、g++ 配套的基础库、调试器 gdb 还有使用 MinGW 环境编译而成的 Qt 类库自身。默认情况下,在上面 Kit Selection 里选中全部套件。
(8)选择版本控制系统
点击 “下⼀步” 进入项目管理界面。在项目管理界面可以设置作为子项目,以及加⼊版本控制系统管理。这两个功能暂时用不到,都用默认的 <None> ,然后点击 “完成”。
(9)最终效果
通过上述 8 个步骤,完成了项目的创建。项目创建完成之后,Qt Creator 会直接进入代码编辑模式,可以看到类似下图界面:
3、认识 Qt Creator 界面
(1)左边栏
在编辑模式下,左边竖排的两个窗口叫做 “边栏” 。
① 项目文件管理窗口,② 打开文件列表窗口。
在 QtCreator 菜单 “控件” ——> "Show Left Sidebar",或者使用快捷键:"Alt + 0" 可以控制边栏的显示和隐藏。
边栏里的窗口数码可以增加,边栏子窗口标题栏有一排小按钮,最右边的是关闭按钮,倒数第二个是增加分栏按钮,可以添加多个边栏子窗口。
边栏子窗口标题栏第一个控件是组合框,可以选择该子窗口的功能视图类型,目前可以选择 8 个视图类型:
(2)代码编辑区
- ① 和 ②:导航按钮 “返回” 和 “前进”,这与网页浏览器的前进和后退按钮类似,可以在之前浏览的多个代码文件或⼀个代码文件里多个位置之间快速切换。
- ③:标识当前显示的文件是只读还是可写,⼀般都是可写的。
- ④:文件类型图标,当前显示文件的类型,这个控件其实是⼀个菜单按钮,点击可以弹出丰富的文件处理功能菜单。
- ⑤:打开的文件名,可以在多个打开的文件之间选择切换,与边栏的 “打开文档” 视图是对应的。
- ⑥:关闭当前显示的文档。
- ⑦:为当前显示的文件添加额外的 C++ 预处理指令(⼀般用不到)。
- ⑧:选择符号,可以在当前显示的文件里多个函数、类、成员变量等之前快速切换,与边栏 “大纲” 视图是对应的。
- ⑨:编辑区光标的行号和列号。
- ⑩:代码编辑区分栏,可以增加多个编辑器窗口,显示多个打开的文档或显示较大源码文件的多个位置。
行首区:主要用来显示代码行号,以及调试断点标志和代码书签标志。右击行首区可以弹出右键菜单,菜单里可以切换书签、编辑书签以及设置或取消断点。
同⼀行是既可以打断点也可以设置书签的,二者不冲突(其实它们根本就没关系)。单击行号前面的浅灰色空白区可以直接打断点,再次单击可以取消断点,另外也可以用快捷键 F9 设置或取消断点。代码书签⼀般用右键菜单来设置,也可以⽤快捷键 Ctrl+M 设置或取消书签。
编辑区:写代码的区域。
(3)UI 设计界面
双击 widget.ui 文件,Qt Creator 会自动进入设计模式,可以对图形界面进行可视化编辑:
- ① 组件选择窗口(Qt 中内置的控件)。组件选择窗口分为多个组,如 Layouts、Buttons、Display Widgets 等,界面设计的常见组件都可以在组件选择窗口中找到。拖拽左侧的控件到程序窗口中就可以创建出具体的界面了。
- ② UI 设计窗口。如果要将某个组件放置到该窗口上时,从组件选择窗口上拖放⼀个组件到窗体上即可。
- ③ 动作编辑窗口。动作编辑窗口包括 Action Editor 以及 Signals 和 Slots 编辑器。 Action Editor 主要是用来新建 Action,并且通过拖拽的动作,将新建好的 Action 添加到菜单栏和工具栏上;Signals 和 Slots 编辑器用于可视化地进行信号与槽的关联。
- ④ 对象浏览窗口。用树状视图显示窗体上各组件之间的布局包含关系,视图有两列,显示每个组件的对象名称(ObjectName)和类名称。
- ⑤ 属性设置窗口。显示某个选中的组件或窗体的各种属性及其取值,可以在属性设置窗口里修改这些属性的值。(每个控件都有很多属性,这些属性影响着控件的具体行为)
(4)构建区
第一个按钮是选择构建项目使用的 Qt 套件和构建目标程序的类型(Debug 或 Release)。
- 对于第一个按钮,默认的是 Debug,构建的是 Debug 类型的目标程序。如果需要构建 Release 版目标程序,点开左下角第一个按钮:
这里有三种构建模式:
上图是针对项目只用户到单一 Qt 套件的,如果之前配置了多个 Qt 套件,看到的类似下图:
如果项目配置了多个可用的 Qt 套件,点开左下角第一个按钮后,会看到各个套件以及构建类型,如果要切换 Qt 套件或构建类型,直接选中相应条目,然后点击运行按钮就行了。如果构建和运行时没出错,就会显示出构建好的目标程序界面。
- 第⼆个是运行按钮,快捷键是 Ctrl+R,如果还没构建项目或刚修改了代码,直接点击运行的话,QtCreator 会自动构建生成新的目标程序并运行。
- 第三个是调试按钮,快捷键是 F5。调试程序之前,QtCreator 会自动构建⽣成最新的目标程序,并进入调试模式。
- 第四个是构建按钮,快捷键是 Ctrl+B,只构建最新的目标程序,但不运行。
四、Qt Hello World 程序
1、使用 “按钮” 实现
(1)纯代码方式实现
按钮对象是我们自己 new 的,为了保证其他函数中能够访问到这个变量,就需要把按钮对象设定为 Widget 类的成员变量。
(2)可视化操作实现
A. 双击:"widget.ui" 文件
此时 Qt Creator 会调用 Qt Designer,打开 ui 文件。
B. 拖拽控件至 ui 界面窗口并修改内容
图形化的界面编辑器:
通过图形化界面实现:
这里的按钮对象不需要我们自己 new,new 对象这个操作已经是被 Qt 自动生成了,而且这个按钮对象已经作为 ui 对象里的一个成员变量,也无需作为 Widget 的成员。
C. 构建并运行
点击之后:
再点击:
2、使用 “标签” 实现
(1)纯代码方式实现
创建标签有两种方式:
- QLabel* label = new QLabel(this); //更推荐在堆上创建的方式
- QLabel label; //在栈上创建
上述代码在 Qt 中不会产生内存泄漏,label 对象会在合适的时候被析构释放(虽然没有手动写 delete),是因为把这个对象挂到了对象树上。
实现效果:
(2)可视化操作实现
A. 双击:"widget.ui" 文件
B. 拖拽 “标签” 至 UI 设计界面中,并双击修改标签内容
刚才往界面上拖拽了一个 QLabel 控件,此时的 ui 文件的 xml 中就会多出这一段代码:
进一步的 qmake 就会在编译项目时,基于这个内容生成一段 C++ 代码,通过这个 C++ 代码构建出界面内容。
C. 实现效果
3、使用 “编辑框” 实现
- 单行编辑框:QLineEdit
- 多行编辑框:QTextEdit
(1)纯代码方式实现
实现效果:
(2)可视化操作实现
A. 双击:"widget.ui" 文件
B. 拖拽 “标签” 至 UI 设计界面中,并双击修改内容
C. 构建并运行
五、项目文件解析
1、.pro 文件解析
工程新建好之后,在工程目录列表中有⼀个后缀为 ".pro" 的文件, ".pro" 文件就是工程文件(project),它是 qmake 自动生成的用于生产 makefile 的配置文件。如图所示:
.pro 类似之前 Linux 中学过的 Makefile 文件,qmake 搭配 .pro 的作用与其类似。
".pro" 文件的写法如下:
- 注释:从 "#" 开始,到这一行结束。
- QT += core gui // Qt 包含的模块 Qt5 包含的模块如下图所示:
- greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 这条语句的含义是:如果 QT_MAJOR_VERSION 大于 4 也就是当前使用的 Qt5 及更高版本) 需要增加 widgets 模块。如果项目仅需支持 Qt5 ,也可以直接添加 "QT += widgets" 一句。不过为了保持代码兼容,最好还是按照 QtCreator 生成的语句编写。
- 指定生成的应用程序名:TARGET = QtDemo
- TEMPLATE = app //模板。告诉 qmake 为这个应用程序生成哪种 makefile。下面是可供选择的模板:
- app:建立⼀个应用程序的 makefile。这是默认值,所以如果模板没有被指定,这个将被使用。
- lib:建立⼀个库的 makefile。
- vcapp:建立⼀个应用程序的 VisualStudio 项目文件。
- vclib:建立⼀个库的 VisualStudio 项目文件。
- subdirs:这是⼀个特殊的模板,它可以创建⼀个能够进⼊特定⽬录的 makefile 并且为它调用 make 的 makefile。
- 工程中包含的源文件:SOURCES += main.cpp/widget.cpp
- 工程中包含的头文件:HEADERS += widget.h
- 工程中包含的资源文件:RESOURCES += painter.qrc
- 工程中包含的 "ui" 设计文件:FORMS += widget.ui
- 配置信息:CONFIG += c++11(使用 c++11 的特性)CONFIG 用来告诉 qmake 关于应⽤程序的配置信息。
2、widget.h 文件解析(Widget 类的声明)
Qt 的设定:使用 Qt 内置的类,包含的头文件的名字和类名是一致的。当然,并不是用到的所有的 Qt 的类都需要显示的包含头文件,在 C++ 中,头文件可能是 “间接包含” 的。比如:引入了 a.h,a.h 里又包含了 b.h,此时就相当于把 a.h 和 b.h 都包含了。
在 Qt 中,如果要使用信号与槽(signal 和 slot)这个核心机制,就必须引入 Q_OBJECT 宏。Q_OBJECT 展开之后就会生成一大堆代码。
QWidget *parent = nullptr:创建的 Qt 的对象,就可以把对象给挂到对象树上,往树上挂的时候需要指定 “父节点”(此处的对象树是一个普通的 N 叉树(不是二叉))。
Ui::Widget *ui;:通过这个指针可以访问 UI 设计界面中的任意控件,它是用前面声明的 namespace Ui 里的 Widget 类定义的。
3、main.cpp 文件解析
使用 Qt Creator 新建任意工程之后,main.cpp 文件中都会自动生成如下代码:
之前在 Linux 学习中,也学过六个函数(本质上是一个),叫作 exec(进程程序替换),把可执行文件中的代码和数据,替换到当前进程中。(Linux 中的 exec 和 当前 Qt 中的 exec 没有任何关系)
解释:
- Qt 系统提供的标准类名声明头文件没有 .h 后缀。
- Qt ⼀个类对应⼀个头文件,类名就是头文件名。
- QApplication 为应用程序类,QApplication a;(a 为应用程序对象,有且仅有⼀个)
- QApplication 管理图形用户界面应用程序的控制流和主要设置。
- QApplication 是 Qt 的整个后台管理的命脉。它包含主事件循环,在其中来自窗口系统和其它资源的所有事件处理和调度。它也处理应用程序的初始化和结束,并且提供对话管理。
- 对于任何⼀个使用 Qt 的图形用户界面应用程序,都正好存在一个 QApplication 对象,而不论这个应用程序在同一时间内是不是有 0、1、2 或更多个窗口。
- Widget w; //实例化窗口对象
- a.exec();:程序进入消息循环,等待对用户输入进行响应。这里 main()把控制权转交给 Qt,Qt 完成事件处理工作,当应用程序退出的时候 exec() 的值就会返回。在 exec() 中,Qt 接受并处理用户和系统的事件并且把它们传递给适当的窗口部件。
4、widget.cpp 文件解析
widget.cpp 文件是类 Widget 的实现代码,所有在窗体上要实现的功能添加在此文件中。
5、widget.ui 文件解析
此时再点击左侧边栏的 “编辑” 按钮,那么此时显示的内容就是 .ui 文件的本体:
widget.ui 是窗体界面定义文件,是一个 XML 文件(和 html 很相似,都是使用成对的标签来表示数据),定义了窗口上的所有组件的属性设置、布局,及其信号与槽函数的关联等。用 UI 设计器可视化设计的界面都由 Qt 自动解析,并以 XML 文件的形式保存下来。在设计界面时,只需在 UI 设计器里进行可视化设计即可,而不用管 widget.ui 文件是怎么生成的。 进一步的 qmake 会调用相关的工具,根据这个 xml 文件生成一些 C++ 代码,从而把完整的界面构造出来。
六、Qt 编程注意事项
1、Qt 中的命名规范
- 类名:首字母大写,单词和单词之间首字母大写。
- 函数名及变量名:首字母小写,单词和单词之间首字母大写。
Qt 偏好驼峰命名法。
2、Qt Creator 中的快捷键
- 注释:Ctrl + /
- 运行:Ctrl + R
- 编译:Ctrl + B
- 字体缩放:Ctrl + 鼠标滑轮
- 查找:Ctrl + F
- 整行移动:Ctrl + Shift + ⬆/⬇
- 帮助文档:F1(+Fn)
- 自动对齐:Ctrl + i
- 同名之间的 .h 和 .cpp 的切换:F4(+Fn)
- 生成函数声明的对应定义:Alt + Enter
3、使用帮助文档
打开帮助文档有三种方式,实际编程中使用哪种都可以。
(1)光标放到要查询的类名 / 方法名上,直接按 F1
(2)Qt Creator 左侧边栏中直接用鼠标单击 “帮助” 按钮。
(3)找到 Qt Creator 的安装路径,在 "bin" 文件夹下找到 assistant.exe,双击打开
新建项目,在新建的项目中使用 Qt 中的 "QpushButton" 控件。打开帮助手册,在 "索引" 里面输入 "QpushButton":
4、认识对象模型(对象树)
在 Qt 中创建很多对象的时候会提供一个 Parent 对象指针,下面来解释这个 parent 到底是干什么的。
(1)QObject 是以对象树的形式组织起来的
- 当创建⼀个 QObject 对象时,会看到 QObject 的构造函数接收一个 QObject 指针作为参数,这个参数就是 parent,也就是父对象指针。
- 这相当于在创建 QObject 对象时,可以提供⼀个其父对象,我们创建的这个 QObject 对象会⾃动添加到其父对象的 children() 列表。
- 当父对象析构的时候,这个列表中的所有对象也会被析构。(注意:这里的父对象并不是继承意义上的父类)
这种机制在 GUI 程序设计中相当有用。例如:一个按钮有一个 QShortcut(快捷键)对象作为其子对象。当删除按钮的时候,这个快捷键理应被删除。这是合理的。
(2)QWidget 是能够在屏幕上显示的一切组件的父类。
- QWidget 继承自 QObject ,因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件。因此,它会显示在父组件的坐标系统中,被父组件的边界剪裁。例如,当用户关闭⼀个对话框的时候,应用程序将其删除,那么,我们希望属于这个对话框的按钮、图标等应该⼀起被删除。事实就是如此,因为这些都是对话框的⼦组件。
- 当然,我们也可以自己删除子对象,它们会自动从其父对象列表中删除。比如,当我们删除了一个工具栏时,其所在的主窗口会自动将该工具栏从其子对象列表中删除,并且自动调整屏幕显示。
(3)解决了内存问题
- 当⼀个 QObject 对象在堆上创建的时候,Qt 会同时为其创建⼀个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。
- 任何对象树中的 QObject 对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的 children() 列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有 QObject 会被 delete 两次,这是由析构顺序决定的。
如果 QObject 在栈上创建,Qt 保持同样的行为。正常情况下,这也不会发生什么问题。来看下面的代码片段:
作为父组件的 window 和作为子组件的 quit 都是 QObject 的子类(事实上,它们都是 QWidget 的子类,而 QWidget 是 QObject 的子类)。这段代码是正确的,quit 的析构函数不会被调用两次,因为标准 C++ 要求,局部对象的析构顺序应该按照其创建顺序的相反过程。因此,这段代码在超出作用域时,会先调用 quit 的析构函数,将其从父对象 window 的子对象列表中删除,然后才会再调用 window 的析构函数。
但是,如果我们使用下面的代码:
情况又有所不同,析构顺序就有了问题。我们看到,在上面的代码中,作为父对象的 window 会首先被析构,因为它是最后一个创建的对象。在析构过程中,它会调用子对象列表中每一个对象的析构函数,也就是说,quit 此时就被析构了。然后,代码继续执行,在 window 析构之后,quit 也会被析构,因为 quit 也是一个局部变量,在超出作用域的时候当然也需要析构。但是,这时候已经是第二次调用 quit 的析构函数了,C++ 不允许调用两次析构函数,因此,程序崩溃了。
由此我们看到,Qt 的对象树机制虽然在一定程度上解决了内存问题,但是也引入了一些值得注意的事情。这些细节在今后的开发过程中很可能时不时跳出来烦扰一下,所以最好从开始就养成良好习惯。
在 Qt 中,尽量在构造的时候就指定 parent 对象,并且大胆在堆上创建。
(4)Qt 对象树图示
这里的树上的这些对象,统一销毁时最好不过的。如果某个对象提前销毁,此时就会导致对应的控件在界面上不存在了。所以,我们选择通过 new 的方式来创建对象就是为了把这个对象的生命周期交给 Qt 的对象树来统一管理。
当把对象改在栈上创建,那么此时就可以看到运行起来的程序无法显示出 hello world。此时 label 对象随着构造函数的结束就销毁了。
(5)代码示例
创建一个新工程并编译运行,生成如下窗口:
选中工程程名,鼠标右键 ——> "add new..."(或 “添加新文件”):
或者选择左上角 “文件” ——> “新建文件或项目”:
弹出如下界面:
参考图:
此时手动创建类的头文件以及源文件会自动添加到目标工程中:
修改头文件:
编写源文件:
编译并运行:
当关闭弹出的对话框时,就会自动调用标签的析构函数:
可以看到,这里的结果出现了乱码(编码方式不匹配)。
在计算机中,一个汉字占几个字节?
针对这个问题,不能回答出一个具体的数字。需要有提前条件:当前中文编码使用的是哪种方式(字符集)。
计算机存的是二进制数字。英文字母是用 ASCII 码表表示的,规定了每个字符都有一个对应的数字来表示。
只是表示英文,一个字节就足够了,毕竟英文字母数目非常有限。
日常的常用汉字大概是 4k 多个,算上各自生僻字,总数差不多是 6w 左右。
因为表示汉字的字符集有很多种,不同的字符集表示同一个汉字,可能使用的数字并不相同。
目前,表示汉字字符集主要是以下两种方式
- GBK(中国大陆),使用 2 个字节表示一个汉字。Windows 简体中文版默认的字符集就是 BGK。
- UTF-8 / utf8,变长编码,表示一个符号,使用的字节数有变化(2-4),但是一般一个汉字是 3 个字节。Linux 中默认的字符集是 utf8。
Qt Creator 内置的终端不是 utf8 的方式来显示字符串,且这个终端好像不能设置字符编码。Qt 中有一个 QString,可以帮助我们自动处理编码方式,且还提供了专门用来打印日志的工具 qDebug(),也能很好的自动处理编码方式。
qDebug 这个宏里封装了 QDebug 对象,可以直接使用qDebug(),可以被当作 cout 来使用。
对象树确保的是先释放子节点的内存,后释放父节点的内存。而析构函数的调用顺序则不一定遵守上述要求,因此看到子节点的析构执行顺序反而在父节点析构顺序之后。
注意:调用析构函数和释放内存并非是同一件事情。
5、Qt 窗口坐标体系
坐标体系:以左上角为原点(0,0),X 向右增加,Y 向下增加。
对于嵌套窗口,其坐标是相对于父窗口来说的。示例:使用 Qt 中的坐标系设置控件的位置:分别对 “按钮” 和 widget 本身移动位置:
运行结果如下图示: