Qt的概述

📅 2026/7/21 22:45:31
Qt的概述
1.前言互联网公司有这样一些核心岗位1.开发(程序员)。2.测试。3.运维(管理机器)。4.产品经理(非技术岗主要的职责是提出需求)。开发岗一般有后端开发前端开发算法工程师游戏开发等等。我们当前所讨论的Qt是用于”客户端开发“的若把前端开发也单独拎出来又可以分为1.网页前端开发(做网页的)。2.桌面应用开发(做电脑上的应用程序的)。3.移动应用开发(做手机上的应用程序的)。Qt这个技术主要用于桌面应用开发桌面应用开发也可以叫客户端开发(一般听到前端可能指具体的某个前端也可能是包罗万象的前端)。客户端开发属于历史悠久的一个事情最开始苹果电脑推出第一代图形化操作界面系统的时候客户端开发这样的技术就诞生了像网页移动都是后来出现的。前面反复讨论到了客户端这样一个术语再来说一下客户端可认为是直接和用户打交道的这一端的程序我们平时所接触到的大部分程序其实都属于客户端比如我们用的chrome、qq音乐、stream等都可以称为客户端。和客户端有个相对应的概念叫服务器服务器就属于站在客户端背后的那个男人了。我们用户使用程序是为了解决一些实际的问题但是有些问题得让服务器通过网络在背后给我们做出一些支撑才能去解决比如用滴滴打车下单后订单通过网络到滴滴服务器再由服务器通过网络派发给司机的客户端这样就完成了一个打车的过程。很明显是服务器站在客户端背后提供了默默的支撑才能完成整个业务逻辑解决实际问题。虽然大部分的客户端程序是需要有背后的服务器做支撑的但是确实也有些程序是不需要服务器的。这样的程序比如画图板、计算机等同样也是直接和客户打交道的虽然不联网也可以称为客户端程序。总的来说客户端这样的概念是非常广泛的其实前面说的网页、桌面、移动开发也可以统称为客户端开发但qt技术专指的是桌面应用开发qt无法开发网页前端也不能开发移动应用。但是目前qt官方也支持了移动应用的开发了但是目前还没有听说有啥知名的商用移动应用是qt开发的。客户端开发的重要任务是编写和用户交互的界面。和用户交互的界面有两种典型风格1.命令行界面/终端界面(黑框框)也称为TUI。2.图形化界面称为GUI。TUI适用于专业软件给程序员用的GUI适合普通用户qt就是用来编写桌面的GUI程序的一套框架。在Windows中编写GUI程序也是有很多解决方案的qt只是其中的一种。qt有一个优势可以跨平台运行效率也不差。2.qt背景介绍qt是一个跨平台的c图形用户界面应用程序框架这句话也不难理解因为我们前面说了qt是开发图形化界面的。这里有个词叫应用程序框架什么是框架呢框架本质上是一群大佬发明出来的方便让咱们普通的程序员写出来的代码比较靠谱什么意思呢在软件开发中谈到自由、灵活是个贬义词因为代码越自由、灵活就意味着越容易出错保证代码不出错是一个很重要的事情于是就有大佬发明了框架框架可以约束程序员不要把代码写的天马行空其实框架就是在限制程序员的自由这样可以保证写的代码的下限不要让代码太糟糕。因此图形化界面应该怎么写qt这个框架已经把大思路梳理好了按照大框架走小的细节自己再添加这样保证代码不会写的太差这就是框架的含义。我们平时还听过库库和框架其实有一定的相似性都是属于大佬把一些代码写好了让我们直接去使用。但是库是被程序员调用的也就是程序员是主体程序员决定什么时候用库及在哪里用等框架则是框架占主体也就是框架把大流程梳理好然后程序员配合框架完善填充框架中留出的一些细节。3.搭建 Qt 开发环境qt开发环境需要安装三个部分1.c编译器(指的是gcccl.exe这样的东西不是visual studio这样的东西。编译器!ide编译器只是ide调用的一个程序)。2.qt的SDKSDK叫做软件开发工具包它里面会包含开发qt程序所用的方方面面的各种工具。比较幸运的是一般qt的SDK里面已经内置了一个c编译器这样不用额外安装了。内置的编译器是mingw是windows版本的gcc/g(要是想用vs内置的cl.exe作为编译器也不是不行但需要配置很多额外的东西容易出错)。既然有内置因此具体安装的过程中需要把对应的c编译器一起勾选上。3.需要有一个qt的集成开发环境(IDE)业界主要是这样几个1.qt官方提供的QT Creator。2.Visual Studio。3.Eclipse。第一种方式是最容易入门最容易上手的方式可认为是开箱即用不需要任何额外的配置。虽然QT Creator使用过程中存在不少bug有些bug非常影响使用体验但是整体来说用起来挺方便的比较适合初学者。第二种方式功能更强但是需要额外的配置更多更容易出错。第三种方式并非只是java IDE它本身是一个ide平台可以搭配不同的插件构成不同的ide。目前Eclipse市场份额受到的冲击很大重量级工具有JetBrains轻量级工具有VsCode。这里推荐用第一个而且Qt Creator也是集成在qt sdk里面的。因此说是安装三个东西其实只要安装一个qt sdk另外两个也就都有了。4.Qt SDK 的下载和安装但凡需要下载安装一个程序首选官方网站。Qt 下载官网http://download.qt.io/archive/qt/。进去后看到这样一个界面看到提供了很多版本最新的是6.11我们选择5.14因为最新的东西可能会不太稳定。现在点进去小版本无所谓随便点一个进去后下载这个exe程序这个东西就是我们要下载的qt sdk(但是有些时候访问国外网站可能会不能访问或下载程序速度很慢)下载sdk后剩下的安装过程就比较容易了一路next选mingw7.3.0 64-bit这是qt sdk中内置的c编译器装好后要给装好的qt去配置一下环境变量(不是必须的但建议配置)。下面说说怎么配置在搜索菜单搜索环境变量下面点开看到上面是配置用户变量下面是配置系统变量。windows也是一个支持多用户的操作系统但我们平时都是自己用自己的电脑所以不太关注是用户变量还是系统变量。用户变量就是当前用户会生效系统变量是所有用户都会生效。所以这里配置用户和系统都可以反正都是自己在使用。无论用户还是系统变量都有一个特殊的变量叫Pathlinux下也有个环境变量叫PATH输入的命令就会去PATH下对应的目录中查找对应的程序windows下也是一样的(比如winr后输入calc打开计算机就是在PATH路径下进行查找的。若也想运行qq也要把路径添加到Path环境变量里)。现在要做的事情是需要把刚才安装好的qt sdk中的某个目录加到Path环境变量中这样环境变量就配置完毕了。那为啥要配置这个环境变量1.让OS/Qt Creater工具能够找到qt sdk中提供的exe。2.运行qt程序的时候能够找到对应.dll动态库(环境变量也可以理解成一种简单的进程间通信机制)。现在qt sdk安装完毕了环境变量配置好了下面看看安装好的东西里有哪些重点关注的内容这几个就是qt sdk中自带的一些工具程序也都是我们在开发中需要关注的。先简单看一下第一个是qt助手这是qt的一份离线的官方文档方便查询某个类或api等怎么去使用。再看第二个这是图形化的通过拖拽来控件来设计界面的工具。再看第三个作用是支持国际化比如有的时候写的程序是要和国际接轨的。这样允许你单独创建一个语言配置文件把界面上需要的各种文字都配置到文件中并且在文件提前把各种语言的翻译都配置进去这样就可以一键式切换语言。再下来是一个终端里面是可以使用qt sdk的命令。最后一个是qt的集成开发工具也是学习qt过程中主要使用的工具。5.使用Qt Creator新建项目点开qt creator点文件处的新建文件或项目弹出的对话框让我们选一个具体的项目模板我们当前阶段选Application(应用程序)也就是如果使用Qt写一个GUI程序就应该选择这个。右侧也有很多选项我们要选的是Qt Widgets Application这就是图形化界面程序的项目模板。接下来选好后点击选择可以选择项目名称和项目所在的路径选好后点击下一步Build system是构建系统意思是通过qt写的程序涉及到一系列的元编程技术。元编程就是通过代码生成代码就是qt框架会在编译的时候自动先调用一系列的生成工具基于你自己写的代码生成一系列的其它的c代码最终编译的代码也是最后生成的这些代码其中qt提供的构建工具主要是上面的三种(这里主要使用qmake)选好后点击下一步我们使用qt creator创建项目会自动的生成一些代码出来生成的代码就包含一个类Base class那是选择这个自动生成的类的父类是谁。这主要有三个选项第一个是完整的应用程序窗口(可以包含菜单栏工具栏状态栏等)第二个表示一个控件(chain窗口上的一个具体的元素比如输入框按钮下拉框等)第三个表示一个对话框。我们此处选第二个当父类选QWidget后对应的类名也就变了。注意Widget这个类是项目里自动生成的代码它的类名QWidget是自动生成的代码所继承的父类(qt中内置的类都是以Q前缀开头)。选完类名后还有Header file和Source file其实就是我们让它自动生成一个类这个类代码要包含在一些文件里这里就涉及到widget.h和.cpp(此处生成的文件名是和类名关联的这样的关联并非是强制的但推荐一样)。还有个form fileqt中创建图形化界面的程序有两种方式1.直接通过c代码的方式创建界面。2.通过form file以图形化的方式来生成界面。此处若勾选了Generate form它会生成一个widget.ui的formfile此时就可以使用qt designer或直接使用qt creator来编辑这个ui文件从而以图形化的方式快速方便的生成图形化界面。这里勾选上继续点下一步这里是选择翻译文件(对应的语言)此处暂时不关注和国际化相关的。继续点下一步这里是选择一下基于哪个编译器的qt sdk来构建后续代码。继续点下一步若要提交到git可以选择选none也可以。最终点完成此时一个项目就创建好了。创建好后看到qt creator生成了一些目录和文件我们先运行一下程序感受一下刚刚新建好的空白项目是什么样的效果点左下角绿色的三角这就是运行按钮点击一下(项目新建路径用中文可能会有问题遇到问题重新创建)虽然什么都没有但确实构建出了图形化界面后续想办法如何修改代码让窗口变的丰富多彩。6.代码解释接下来看一下创建好的空白项目里都生成了哪些东西首先映入眼帘的是main.cpp这样一个文件里面有个main函数。main函数有2个参数第一个参数是命令行参数的个数第二个参数是命令行参数都是什么内容。接下来创建了一个叫QApplication这样一个对象并且把刚才的参数作为构造函数的参数传到这样的对象里面了。我们编写一个qt的图形化界面程序一定需要有QApplication对象。再下来创建了一个Widget对象并且调用了w.show。刚才在创建项目的时候填写了生成的类名当时我们填写的是Widget于是qt creator就给我们生成了一个Widget这样的类这个类有了后就生成了一个对象并且调用show方法。这两行代码意思是创建一个控件对象并显示出来(.show()方法让控件显示出来.hide()方法让控件隐藏。Widget的父类是QWidget这些方法都是Qwidget提供的)。再然后还有个return a.exec()exec表示让程序执行起来。之前linux中也学过6个函数exec系列表示程序替换把可执行文件中的代码和数据替换到当前进程中。当前qt的exec和linux中的exec没有任何关系只是名字恰好是一样的。现在把main函数看完了继续看一下Widget类是什么样子的可以看到有个widget.h和widget.cpp这两个文件包含了Widget类的声明和定义。先看一下头文件这个.h里面就是widget类的声明。1和2行是保证头文件只被包含一次第10行看到Widget类继承自QWidget这个QWidget就是我们创建项目时选择的父类。这个类是Qt SDK内置的要想使用这个类就需要包含对应的头文件也就是第4行(Qt的设定使用Qt中内置的类包含的头文件的名字就是和类名一致的。当然也不是用到的所有的Qt的类都需要显示包含头文件c中头文件可能是间接包含的比如引入了a.ha.h里又包含了b.h此时就相当于把a.h和b.h都包含了。后续写带代码的原则一个Qt类先拿过来用如果直接能用说明对应的头文件已经被间接包含过了无需显示包含如果这个类提示找不到定义啥的手动的显示把对应头文件包一下就行了)。再下来在这个类里面有个Q_OBJECT这是Qt内置的一个宏(宏本质上是文本替换)Q_OBJECT展开之后就会生成一大堆的代码。Qt中有一个非常核心的机制信号和槽如果某个类想使用信号和槽就需要引入Q_OBJECT这个宏。在下面15和16是构造函数和析构函数这有个parent参数qt中引入了对象树机制(后面再详细介绍)相当于创建的Qt的对象就可把这个对象给挂到对象树上往树上挂的时候就需要指定当前对象的父节点。在下面有个Widget*ui这个和formfile密切相关。再看看生成的.cpp文件中还有哪些东西首先看到两个头文件第一个是创建项目生成的头文件第二个是formfile被qmake生成的头文件。再下面是刚才的类构造函数具体的定义了核心是给ui属性进行了创建实例并且有个setupui其实6和8行是把formfile生成的文件(界面)和当前widget关联起来。再下面是个析构函数就是把前面new的对象delete了。这里的关键要点就是form file这是什么东西及会产生什么效果展开Forms里面有widget.ui这就是所谓的form file是个.ui后缀的文件。双击这个文件此时在qtcreator中它就切换到了设计这样的标签页并且进入到qtdesigner这样的界面。也就是当直接双击ui文件此时Qt Creator就会调用Qt Designer来打开ui文件此时看到的就是一个图形化的界面编辑器。来简单认识一下接下来点一下左侧边栏的编辑看到了ui文件本来的面貌。也就是ui文件内容本身是上面样子格式的内容(这个格式称为xml它和html非常类似使用成对的标签来表示数据)只不过这些内容会被Qt Designer当作图形化界面来去进行处理(扩展了解xml这里的标签有哪些标签都表示什么含义这是程序员自定义的也就是此处看到的这些标签是qt开发者约定的。htm的标签是固定的每个标签什么含义有专门标志委员会约定)。Qt中使用xml文件就是去描述程序的界面是啥样的进一步的qmake会调相关的工具依据这个xml文件生成一些C代码从而把完整的界面构造出来这就是当前看到的ui文件。 接下来还有个很重要的东西需要我们重点关注一下在我们生成的项目中还有个Empty.pro文件.pro文件是Qt项目的工程文件也是qmake工具构建时的重要依据。第一行表示当前要引入的Qt的模块后面学习到一些内容的时候可能会修改这里。第5行是个编译选项期望当前编译器按照c哪个版本来编译可以通过这里来去指定。最关键的是18~27这里描述了当前项目中参与构建的文件都有什么(也就是编译器要编译哪些文件)。这个地方不需要手动修改Qt Creator帮我们自动维护好。.pro类似于之前linux中学过的Makefile指定好编译哪些等qmake搭配.pro的作用和Makefile是类似的(Qt Creator把这个过程中编译的细节都封装好了只需要点击运行按钮就直接编译)。上面看到的.h .cpp .pro .ui都是源代码如果编译运行Qt项目构建过程中还会生成一些中间文件我们来大概看一下这些是刚才的源代码文件。点上级目录看到和刚才项目目录并列的还有一个目录。在运行一次程序之后就会在项目目录并列的地方多出来一个“build-xxxx”目录这个目录里面就是该项目运行过程中生成的一些临时文件。点进看看看到了Makefile说明编译Qt程序还是会用到makefile只不过这个makefile不需要手动写而是qmake自动生成的。还看到有个ui_widget.h这就是刚才widget.ui xml文件生成的.h文件。前面在widget.cpp中包含了这样一个文件这个就是在这里被自动生成的。这个.h文件有什么呢这个文件里生成了一个Ui_Widget类里面提供了setupUi方法(这个类其实就是widget.h中的Ui::Widget)。上面是Qt自动生成的代码这个代码就会在setupUi这个方法中生成界面的具体细节也看到widget.cpp中有使用这个方法。debug里面可以看到exe这就是最终生成的可执行程序如果直接运行效果和之前在Qt Creator中运行的效果一样。7.Qt Hello World 程序刚才创建项目并没有写任何代码目前程序也可以跑起来看到空白的窗口现在我们期望空白窗口上显示一个helloworld字符串。接下来我们就具体操作一下首先还是打开Qt Creator(若创建新项目还是上述过程)创建好项目后来进行helloworld的操作我们期望在界面上显示helloworld的字符串怎么显示呢我们有两种方式进行完成1.通过图形化的方式在界面上创建一个控件显示hello world。2.通过纯代码的方式通过编写代码在界面上创建控件显示hello world。我们先通过图形化的方式来演示一下打开widget.ui这个form file现在我们就调用了Qt designer这样的图形化的界面设计器去完成窗口界面内容的编辑。左侧是qt给我们提供的各种内置控件我们想显示hellow world可以使用很多控件去完成此处为我们使用一个最简单的下面有个Label控件它所处的分类叫Display Widgets顾名思义这个分类里的所有控件都是用来显示的。我们把这个控件拖到界面上一放此时界面上就出现了一个label控件。我们可以拖拽把label放大一些方便后续编辑然后双击可以进入编辑状态然后写入hello world此时修改就生效了相当于界面存在了一个label控件。继续看右上边看到Qt Designer右上角通过树形的结构显示出了当前界面上有哪些控件。这里看到有创建项目默认生成的QWidget控件然后下面有个QLabel也就是label这样的控件。我们刚才的过程在main.cpp widget.cpp里面是没有变化的变化的是widget.ui点编辑可以看到刚才往界面拖拽了一个QLabel控件此时ui文件的xml中就会多出这一段代码这一段代表描述了当前界面上的label具体是什么样子。进一步的qmake就会在编译项目的时候基于这个内容生成一段c代码通过这个c代码构建出界面内容了(自动完成的)。下面运行一下看到窗口界面上出现了hello world。然后在右键目录在Exporer中显示找到上级build目录这个ui_widget.h就是qmake根据widget.ui配置文件里的内容生成的头文件在这个头文件里完成一些界面内容的初始化完成创建label的过程。打开看一下看到setupui方法里有创建一个QLabel对象然后进行一些设置这样标签就被创建出来了。接下来用纯代码方式实现一下helloworld我们再创建一个新的项目把刚才的项目关了直接创建右边栏会多出来个项目后续操作容易分不清当前文件打开的是哪个项目(关闭后回到qtcreator的欢迎界面了然后重新创建新的项目)这里也生成了ui文件我们不打算编辑它而是通过代码的方式来完成。这里打开Widget.cpp这里包含了一个构造函数。一般我们通过代码来构造界面的时候通常会把构造界面的代码放到Widget的构造函数中(选择的是继承QWidget父类就放widget里面选QMainWindow类放到MainWindow构造函数里面)。构造函数是在main.cpp执行的一进入main函数先创建QApplication然后创建Widget这个创建的过程就执行了构造函数也就执行了接下来要写的控件创建的过程。下面来编写我们还是创建一个label对象qt中叫QLable(通过new创建堆的方式创建)此时编写代码时提示我们说QLabel找不到定义因为Qt中每个类都有一个对应的同名的头文件需要显示包含一下包含时发现有两个这里解释一下上古时期Qt用的是qlabel.h这种风格的头文件1998年之后C标准成立了C98规定包含头文件统一使用#includecstiod代替原有的#includestdio.h因此Qt也做出了变化。这样就包好了再解释一下什么叫Label呢label翻译过来是标签准确来说是界面上一个用来显示内容的字符串控件在界面上起到说明的效果此处用QLabel来完成文字的显示。12行创建对象的时候还要注意一些细节1.创建对象的时候可以在堆上创建也可以直接在栈上创建qt中一般更推荐在堆上创建的方式。2.在我们new出对象的时候构造函数这最好添一个参数this这个参数含义是给当前创建的label对象指定一个父对象(前面提到过qt中有一个很重要的概念叫对象树本质是一个分叉树通过树形结构把当前界面上的控件对象组织到一起。树的特点是每个结点可以有n个子节点只有一个父节点指定这个对象的父节点也就知道它在树的哪个位置。这里是让创建的label对象的父节点是this这个this是构造函数所对应的对象这个对象是main函数里的Widget wthis指向的是main函数中创建的Widget对象意思是我们创建的label对象它的父元素就是main中的Widget w对象)。下面把label创建出来后再给label创建一个文本里面可以指定一个字符串。setText这是设置控件中要显示的文本是啥。这里的形参类似是QString这还有一个要交代的东西qt诞生于1991年那时c还没有形成标准因此那时c更没有标准库这样的概念了。当时那个年代如何去表示一个字符串可以使用c风格的字符串(\0结尾)、也可以使用c的string。当年这些用起来都非常不好用qt为了让自己的开发能变的顺畅就自己发明了一套轮子搞了一系列的基础类来支持qt的开发包括不限于字符串 QString、动态数组QVector、链表 QList等。很多年之后上述这些容器等内容已经打磨的很好了形成了c标准。很显然这些已经引入的qt自己包装好的这些容器类也不可能删了就只能和现有的标准库中的容器类共存了。因此我们开发qt代码的时候如果需要用到上述容器类可以使用标准库的容器也可以使用qt自己搞的这一套。但是qt原生的api中涉及到的接口用的都是qt自己的这一套容器。后续代码中还会经常见到QString这样的一些东西而很少见到std::stringQString和std::string之间也能很方便的相互转换。继续回到代码中在QString中也提供了c风格字符串作为参数的构造函数不显示构造QString上述代码中c风格字符串也会隐式构造QString对象。QString对应的头文件已经被很多qt内置的其它类给间接包含了因此一般不需要显示包含QString头文件。下面运行一下此时看到界面中显示了helloworld字符串只不过默认显示在左上角。8.初识对象树现在代码就编写完成了但是有个细节问题这里是new的方式创建了一个对象那么new完之后为什么没有delete呢不delete不就出现内存泄漏了吗但是上述12行的代码1在qt中不会产生内存泄漏label对象会在合适的时候被析构释放(虽然没有手动写delete确实能释放)。关于怎么释放的奥秘在于this这里之所以能够把对象释放调主要是因为把这个对象挂到了对象树上。下面说说qt中搞了一个对象树是个N叉树把界面上的各种元素组织起来了。举个例子比如有个这样的界面这个界面最顶层窗口叫QWidget这样的对象这个界面里还会包含其它一些元素这样的一个界面结构就会在qt内部通过一颗对象树来去进行表示。这个对象树大概样子是最上面根结点是QWidget对象根下面包含了几个子结点这就是一个非常典型的树形结构通过这个树形结构就把界面上要显示的控件对象都组织起来了。为什么要用树形结构进行组织呢使用对象树把这些内容组织起来最主要的目的就是为了能够在合适的时机(窗口关闭/销毁)把这些对象统一进行释放。这里树上的这些对象统一销毁是最好不过的如果某个对象提前销毁此时就会导致对应的控件就在界面上不存在了。因此前面第12行通过new的方式创建对象也就是为了把这个对象的生命周期交给Qt的对象树来统一管理。试想一下如果这个对象是按照栈上的变量创建的就可能会存在一些提前释放的问题。可以试一试在栈上创建变量然后也指定父元素是this再次运行一下当把对象改成在栈上创建此时就可以看到运行起来的程序无法显示出hello world此时label对象随着构造函数的结束就销毁了。所以用new的方式把对象生命周期交给qt的对象树更加合理但是还是有人会担心不delete真的可以释放吗下面改变一下代码看看自动释放的过程。为了演示对象树帮我们自动释放对象的过程我们需要再去把代码调整一下。我们之前是直接创建了一个QLable对象这是qt里面内置的一个对象这个对象析构的时候并没有一些打印提示之类的因此我们看的并不是很清楚。为了更直观的看到这个对象被释放的过程我们创建一个新的项目然后自己定义一个QLable类然后通过自定义的类看到自动释放对象的效果(先关闭之前的项目再创建新的项目)再然后新创建文件那新建一个类出来然后就可以看到在qtcreater里面多出了mylable文件然后.h里面提示不认识QLable这个名字Qtcreator是帮我们生成了一些代码但是没完全生成头文件没给咱们自动包含只能靠我们自己手动包含然后把构造函数也修改一下加一个parent能够指定父元素然后切换到对应的.cpp修改一下(在qtcreator中可以通过F4切换头文件和对应的.cpp文件)这样就把构造函数修改完毕了。这里调用了父类构造函数才能让我们自己类的对象加入到qt对象树中。创建自定义的类最主要的目的是自定义一个析构函数在析构函数中完成打印方便我们看到最终的自动销毁对象的效果。继续完成析构函数声明还要有定义可以光标放析构函数上然后按atl回车然后点过去就跳转过去了并生成代码然后来编写按照以往方式来写然后创建对象运行一下看到helloworld正常显示说明我们创建的Mylabel可以很好的继承QLabel的功能的QLable可以干嘛Mylabel也就可以干嘛。目前程序没有什么输出下面关闭窗口触发析构来让对象释放发现有日志说明析构函数是执行了。虽然没有手动delet但是由于把MyLabel挂到了对象树上此时窗口被销毁的时候就会自动销毁对像树中的所有对象MyLabel的析构是执行到了。但是预期的显示效果是被销毁三个中文但是实际的显示效果出现了乱码。乱码问题出现的原因只有一个那就是编码方式不匹配。下面来说说乱码问题在计算机中一个汉字占几个字节针对这个问题只要回答出一个具体的数字就一定是错的。因为要回答问题得先弄清楚前提条件就是当前中文编码使用的是哪种方式(字符集)。计算机存的是二进制数字怎么用二进制表示各种汉字或者符号呢英文字母用ASCII表示在ASCII中规定了每个字符都有一个对应的数字来表示。英文字母又没有多少只是表示英文一个字节足够了。中文中一共6w左右汉字那怎么表示汉字呢思路和前面一致仍然使用一个大表格给每个汉字分配一个整数即可。对于计算机来说6w多个符号的表格是小case那具体这个表格什么样子具体每个汉字都使用哪个数字表示这个事情就不一定了(可能不同的组织有不同的表示方式)所以表示汉字的字符集其实是有很多种的不同的字符集表示同一个汉字使用的数字不相同。目前表示汉字字符集主要是2种方式1.GBK(中国大陆使用多)使用2个字节表示一个汉字像我们使用的Windows简体中文版默认的字符集就是GBK。2.UTF-8/utf8这是个变长编码表示一个符号使用的字节数有变换一般2~4但是在utf8中一个汉字一般是3个字节像Linux中默认就是utf8。现在说说为什么前面出现了乱码就是编码方式不匹配。比如你字符串本身是utf8编码的但是终端(控制台)是按照gbk的方式来解析显示的此时就会出现乱码(拿着utf8这里的数值去查询gbk的码表)。前面我们析构函数那里写了打印字符串这个字符串是包含在mylabel.cpp中的这个字符串使用哪种方式编码的和当前mylabel.cpp文件的编码方式是一致的怎么看这个文件的编码方式呢说明这个字符串是utf8方式的。QtCreator内置的终端是utf8的方式显示字符串吗不好说这个终端好像不能设置字符编码但是出现了乱码肯定不是utf8。那怎么解决呢无非是让编写和解析方式一样但改终端的找不到改文件也不好因为主流方式还得是utf8。在Qt中有一个东西叫QString是可以帮助我们自动处理编码方式的。不只是QString也提供了专门用来打印日志的工具也能自动处理编码方式Qt中提供了一个qDebug工具借助这个就可以完成打印日志的过程它能很好的处理字符编码就不需要我们关注了。下面用一下QDebug是Qt中的类但不会直接使用这个类qDebug()是个宏封装了QDebug对象直接使用qDebug()这个东西就可以当作cout来使用。下面运行关闭一下因此后续在qt中如果想通过打印日志的方式输出一些调试信息都优先使用qDebug。使用qDebug还有一个好处打印的调式日志是可以统一进行关闭的。输出的日志是开发阶段调式程序的时候使用的如果你的程序发布给用户不希望用户看到这些日志可以快速通过qDebug的编译开关来实现一键式的关闭。9.补充经过前面学习以及能用两种方式来显示helloworld一个是纯代码的方式一个是通过图形化界面的方式。其实qt中想完成helloworld可以基于很多控件来实现前面是使用label完成的label只是单纯的显示一个文本没办法做更多的交互性质的工作接下来换种方式再来实现一下helloworld。这里使用编辑框来完成helloworld编辑框在qt中有两种一种是单行编辑框我们叫做QLineEdit还有一个叫多行编辑框叫做QTextEdit(我们当前用单行)。我们打开Forms文件找到LineEdit然后把LineEdit拖到窗口上现在我们就有了一个LineEdit接下来可以给LineEdit里面设置一个文本此时文本就有了。这里的helloworld文本可以通过右侧的属性编辑区来进行修改往下翻可以看到这些就是QLineEdit这个控件所对应的属性(含义后面说)。可以看到有一个属性是text这个text就是编辑框里面包含的文本可以在text里面修改文本的内容。下面运行一下而且文本框里面的内容也是可以编辑的这就是通过编辑框的方式来完成helloworld的编写。接下来再使用纯代码的方式来实现上述功能(再次新建项目虽然有widget.ui但不去使用)切回到widget.cpp这里在构造函数里面编写一下代码。我们创建一个QLineEdit*对象并指定好父对象也就是当前在main函数里面创建的widget对象以它为父对象构建出了QLineEdit。然后仍然用setTex再次运行还可以通过按钮的方式来创建出helloworld打开widget.ui找到按钮这里面有个很重要的按钮叫PushButton这是一个普通的按钮一般都是使用这个按钮。下面把按钮拖到界面上然后写入文本再次运行程序此时程序界面里面就有了一个按钮按钮上显示的文本就是helloworld。按钮的使命就是点击以后会有效果那怎么让按钮点击以后有效果呢这里就涉及到了qt中的信号槽机制(后面说这里演示使用方式)信号槽的本质就是给按钮的点击操作关联上一个处理函数当用户点击的时候就会执行这个处理函数。我们打开widget.cpp来给按钮添加点击处理操作。还是在构造函数这里我们需要用到一个connect函数qt中的connect是QObject这个类提供的静态函数这个函数作用是连接信号和槽(就是给点击关联一个处理函数)。这里的参数有四个第一个参数是信号是谁发的这里处理的是点击按钮的信号所以是按钮发的信号用ui-pushButton选中界面上的按钮通过ui-这样的写法可以访问到ui文件中创建的控件。我们前面创建了控件pushButton创建这个控件时会带有一个属性叫objectName在QtDesigner中创建一个控件的时候此时就会给这个控件分配一个objectName属性这个属性的值要求是唯一的不能和别人重复。这里会自动生成内容也可以自己手动修改成别的不管怎么样qmake在预处理.ui文件的时候就会根据这里的objectName生成对应的c代码c代码中该QPushButton对象的变量名就是这里的objectName这个变量就是ui属性中的成员变量。我们要处理按钮被点击的信号第二个参数传的是一个函数指针这个东西是当我们点击按钮的时候就会触发一个clicked这样的信号。我们期望这个对象能够关联到一个具体的槽函数上先指定关联到哪个对象的槽函数这样就关联到Widget对象的一个槽函数。再后面指定一个具体的函数也是传函数指针目前函数还没有定义。通过上述的代码我们就完成了信号和槽之间的一个连接操作。这里点击ui-pushButton按钮(发出信号的主体)的时候就会自动触发clicked(发了个什么信号)这个信号this是谁来处理这个信号最后是具体怎么处理。接下来具体实现一下这个函数先打开widget.h声明这里在这里指定函数声明然后alt回车添加定义再次运行一下再次点就不会变了。我们还可以调整一下实现一个切换的效果(直接-text是获取文本)这个代码中通过ui-pushButton获取到ui文件界面上的按钮之所以可以选中这个按钮是这个按钮有个属性叫objectName由于这个属性叫pushButton所以最终通过ui-pushButton来获取到这个对象。这个ui是widget.h里面有个Widget*ui指针是创建好项目后自动生成的然后Widget里面的内容是qmake自动生成的。再次运行就会发现每一次的点击文本内容都会发生变换。看完程序执行效果以后来关注一下objectName是终止怎么变成ui里的属性的还是右键.pro文件在explorer中显示然后进入上级目录然后找到对应的build目录里面有一个.h这就是根据widget.ui生成的文件。在当前生成的代码里就会包含一个叫pushButton的成员ui_widget.h中自动生成的代码里就会包含一个pushButton的成员变量这个变量的名字就是更具objectName的值来确定的。在objectName中设置成什么值生成的变量名就叫什么名字然后就可根据这个名字获取到对应的控件变量了。头文件中还可以看到又会生成一个类继承Ui_Widget这个类是在Ui这样的命名空间里面因此widget.h中引用就是这个类Ui_Widget里面的东西就可以通过ui来获取访问。继续用纯代码的方式实现一下前面的效果在widget.cpp中包含头文件QPushButton然后创建一个按钮记得指定父元素然后设置一个文本写到这里界面上就以及有了一个按钮按钮里有helloworld下面运行一下接下来完成信号槽的连接点一下按钮可以触发反应。继续用connectconnect里面指定谁发送的信号是myButton。发送了一个clicked信号this去处理这个信号用handlerClick去处理这个信号接下来完成函数的声明和实现接下来和前面一样判断一下按钮里面的文本但发现写myButton访问不到因为myButton在构造函数中的一个局部域里所以局部变量不能跨越函数去访问。因此把myButton变成Widget的成员变量就可以了此时就继续完善此时同样可以完成切换效果了接下来对比一下两个版本代码的差别对比发现若是纯代码版本意味着当前myButton按钮对象是自己new的为了保证其它函数能访问到这个变量就需要把按钮对象设定为Widget类的成员变量。若是图形化方式此时的按钮对象不需要咱们自己newnew对象的操作已经是被Qt自动生成了而且这个按钮对象已经作为ui对象里的一个成员变量了也无需作为Widget的成员。10.Qt Creator的快捷键11.使用帮助文档打开帮助文档有三种方式实际编程中使用哪种都可以。1.光标放到要查询的类名/方法名上 直接按 F1。比如QPushButton这个类是干嘛的不知道想去文档中查一下光标选中按F1此时相当于把文档打开了就可以看到QPushButton类的相关介绍了。2.Qt Creator左侧边栏中直接用鼠标单击 帮助 按钮看到把文档各个方面的内容分门别类以目录形式放好了。3.找到 Qt Creator 的安装路径在 bin 文件夹下找到 assistant.exe双击打开12.认识qt坐标系在qt中使用的坐标系就是数学里常见的平面直角坐标系但和数学中的有些区别一般数学上的称为右手坐标系计算机中的称为左手坐标系。计算机中的坐标系原点(00)就是屏幕左上角或者窗口左上角。给qt的某个控件设置位置就需要指定坐标对于这个控件来说坐标系原点就是相对于父窗口或控件的。比如这是显示器的屏幕屏幕里有qt的窗口QWidgetQWidget里面有个按钮QPushButtonQPushButton的父元素/父控件/父窗口就是QWidgetQWidget没有父元素(NULL)就相当于父元素就是整个显示器的桌面了。下面用代码来演示一下创建好项目然后在widget.cpp里面通过代码创建一个QPushButton当前的button不去设置默认就出现在左上角此时默认情况下按钮就是在(00)位置就是左上角。可以使用move函数来设置按钮的位置参数一个是横坐标一个是纵坐标。谈到坐标坐标背后的单位是像素。显示器本质上就是一大堆可以发光的小亮点/小灯泡来构成的比如见过显示器分辨率是1920*1080这样的文字这说的是水平方向有1920个像素(亮点)垂直方向有1080个像素。显示器亮点数量越多画面就越好。下面运行程序看一下也可以给Widget本身移到位置