Qt 概述

发布时间:2024年01月24日


前言


一、Qt概述

1、Qt项目概述

当我们安装了Qt Creater后,我们创建一个新项目。
Build System为选择构建工具。Qt框架会在编译时自动先调用一系列的生成工具,基于我们写的代码生成一系列其它的C++代码,然后最后将这些代码进行编译。qmake是老牌的Qt构建工具了,CMake并非是Qt专属的构建工具,很多其它项目也会使用CMake构建。Qbs为Qt新一代的构建工具。我们选择qmake即可。
在这里插入图片描述
在这里插入图片描述
Translation File为Qt国际化相关的内容,在这里可以选择翻译文件,我们现在暂时不关注。
在这里插入图片描述
Kits为选择编译器,即选择一下基于哪个编译器的Qt SDK来构建后续代码。MinGw 就是Qt SDK中内置的编译器,就类似于windows版本的gcc/g++编译器。
在这里插入图片描述
Summary为选择版本控制工具。
在这里插入图片描述
然后我们点击运行按钮,就可以将一个初始化的Qt项目运行起来。因为我们此时还没有向窗口中插入任何内容,所以此时只显示了一个空窗口。需要注意的是我们创建的Qt项目的路径中不能包含中文。
在这里插入图片描述
下面我们来看这个最简单的Qt项目中的一些文件。
main.cpp文件。
在这里插入图片描述
mainwindow.h文件。
在这里插入图片描述
mainwindow.cpp文件。
在这里插入图片描述
mainwindow.ui文件。
在这里插入图片描述
.pro文件的作用就类似于我们在Linux中学过的Makefile文件,只不过.pro文件和Makefile文件的语法不一样。qmake搭配.pro起到的作用就和Makefile的作用类似。
在这里插入图片描述
Qt项目在运行时生成的中间文件。我们上面看到的.h .cpp .pro 和 .ui文件都是项目的源代码,如果我们编译运行Qt项目的话,构建过程中还会生成一些中间文件。我们可以查看中间文件都有哪些。
在这里插入图片描述
在运行一次Qt项目后,就会在项目目录并列的地方多出来一个 “build-xxxx” 的目录,这个目录里面就是该项目运行过程中,生成的一些临时文件。
在这里插入图片描述
通过Qt Designer设计的界面的具体细节的实现都在setupUi方法中。
在这里插入图片描述
debug和release目录下的.exe文件就是项目最终生成的可执行程序,如果直接运行,效果就和之前在Qt Creator中运行时的效果相同。
在这里插入图片描述
在这里插入图片描述

2、Qt Hello World 程序

可以通过两种方式实现hello world。

  1. 通过图形化的方式,在界面上创建出一个控件,显示hello world。
  2. 通过纯代码的方式,通过编写代码,在界面上创建控件,显示hello world。

下面为使用图形化的方式。我们看到当使用Qt Designer设计界面时,对应的ui文件的xml中的代码也会跟着改变,这些都是Qt Creator自动完成的。
在这里插入图片描述
在这里插入图片描述

下面我们通过纯代码的方式。一般通过代码来构造界面的时候,通常会把构造界面的代码放到Widget/MainWindow的构造函数中。
在这里插入图片描述
因为我们使用了QLabel,所以我们要包含对应的头文件。
我们看到当包含头文件时,有两种形式的头文件。Qt为1991年推出的,当时C++标准还没有成立,所以Qt使用了自己的这种qlabel.h风格的头文件。当1998年之后,C++标准成立了,C++98标准规定了新的头文件风格,统一使用#include< cstdio >代替c语言中的#include< stdio.h >,Qt为了响应C++98的标准,所以就推出了一套QLabel的头文件包含风格。
在这里插入图片描述
创建QLabel对象时,可以在堆上创建,也可以在栈上创建,但是我们更推荐在堆上创建,因为Qt中有一个对象树的概念,在堆上创建的对象可以通过对象树来进行销毁。
在这里插入图片描述
当我们通过setText函数来设置label对象要显示的文本时,看到setText函数的参数为一个QString引用。这个QString类型和C++中的String类型有什么区别呢?
我们知道Qt诞生于1991年,当时C++98标准还没有形成,当时在Qt中表示字符串可以使用c语言风格的字符串(\0结尾),也可以使用C++的string类型,但是当时C++的string类型并不好用,所以Qt为了让自己的开发能变得高效,就自己开发了一套轮子,即Qt中的字符串QString,动态数据QVector,链表QList,字典QMap等。虽然现在C++的标准已经形成了,但是Qt不可能舍弃掉自己包装好的容器类,所以Qt中的接口都支持自己包装好的容器,不过也支持C++中的容器。在Qt中QString和std::string的转换也很方便,其实在Qt中使用QString比使用std::string好一点,因为QString内部已经对字符编码做了处理了,而不像std::string没有做处理。
在这里插入图片描述
QString中也提供了c语言风格字符串作为参数的构造函数。
在这里插入图片描述
在这里插入图片描述

3、对象树

在 Qt 中创建很多对象的时候会提供?个 Parent 对象指针,下?来解释这个 parent 到底是?什么的。

  • QObject 是以对象树的形式组织起来的。
    当创建?个 QObject 对象时,会看到 QObject 的构造函数接收?个 QObject 指针作为参数,这个参数就是 parent,也就是?对象指针。
  • 这相当于,在创建 QObject 对象时,可以提供?个其?对象,我们创建的这个 QObject 对象会?动添加到其?对象的 children() 列表。
  • 当?对象析构的时候,这个列表中的所有对象也会被析构。(注意,这?的?对象并不是继承意义上的?类!)

这种机制在 GUI 程序设计中相当有?。例如,?个按钮有?个 QShortcut(快捷键)对象作为其?对象。当删除按钮的时候,这个快捷键理应被删除。这是合理的。
QWidget 是能够在屏幕上显?的?切组件的?类。

  • QWidget 继承? QObject ,因此也继承了这种对象树关系。?个孩??动地成为?组件的?个?组件。因此,它会显?在?组件的坐标系统中,被?组件的边界剪裁。例如,当??关闭?个对话框的时候,应?程序将其删除,那么,我们希望属于这个对话框的按钮、图标等应该?起被删除。事实就是如此,因为这些都是对话框的?组件。
  • 当然,我们也可以??删除?对象,它们会?动从其?对象列表中删除。?如,当我们删除了?个?具栏时,其所在的主窗?会?动将该?具栏从其?对象列表中删除,并且?动调整屏幕显?。

Qt 引?对象树的概念,在?定程度上解决了内存问题。

  • 当?个 QObject 对象在堆上创建的时候,Qt 会同时为其创建?个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。
  • 任何对象树中的 QObject 对象 delete 的时候,如果这个对象有 parent,则?动将其从 parent 的children() 列表中删除;如果有孩?,则?动 delete 每?个孩?。Qt 保证没有 QObject 会被delete 两次,这是由析构顺序决定的。

Qt对象树如图:
在这里插入图片描述
下面我们自定义一个MyLabel控件来验证对象树对子对象的自动释放。
在这里插入图片描述
在这里插入图片描述
然后我们实现MyLabel的析构函数。
小技巧,我们在写完一个函数的声明之后,按下alt+enter,就可以自动在对应的cpp文件中添加函数的定义了。
在这里插入图片描述
在这里插入图片描述
然后我们在Widget中添加一个MyLabel控件。
在这里插入图片描述
当我们执行项目时,我们看到在Widget窗口中的MyLabel正常显示出来内容了。
在这里插入图片描述
当我们关闭Widget窗口时,此时我们在代码中并没有delete label,但是我们看到还是调用了MyLabel的析构函数,这就是Qt中的对象树自动释放了子对象。但是我们看到打印的消息中,汉字被显示为了乱码,这其实是因为编码方式不匹配造成的。
在这里插入图片描述
我们知道计算机中只能存储二进制的数据,我们平常看到的英文字母在计算机中存储的其实是它的ASCII码值,即ASCII码为每一个字符都规定了一个对应的数字来表示,所以计算机中存储这一个数字就表示ASCII码对应的字母。我们知道英文字母是有限的26个,如果加上我们常用的+、-、*、#等等这些字符,使用一个字节就足够存储了,这就是ASCII码。
但是我们的汉字是很多的,日常使用的汉字大概是4K多个,但是算上各种生僻字,总数差不多有6w左右,那么我们存储汉字也需要采用一个汉字和数字对应的表来存储。即使用一个大表格,这个表格需要可以表示6
w以上的数,然后我们给每个汉字分配一个整数即可。但是具体这个表格是什么样的,具体每个汉字使用哪一个数字来表示,这个就不一定了。因为每一套字符集对于同一个汉字都有不同的数字表示,并且每一套字符集的转码和解码方式也不同。
目前汉字字符集主要有两种表示方式:

  1. GBK。使用2个字节表示一个汉字,Windows简体中文版默认的字符集就是GBK。
  2. UTF-8 / utf8。变长编码,表示一个符号时使用的字节数有变化,在2-4字节之间。但是在utf8字符集中一个汉字一般使用3个字节存储。Linux系统中默认的就是utf8字符集。

乱码问题出现的原因就是因为编码方式不匹配,例如我们的字符串本身是utf8编码的,但是在终端显示时是按照GBK的方式来解析显示的,那么此时就会出现乱码。即拿着utf8的数值去查询gbk的码表,此时就会出现乱码。

在mylabel.cpp中字符串使用的哪种方式编码和当前mylabel.cpp文件的编码方式是一致的。
在这里插入图片描述
我们可以找到mylabel.cpp这个源代码文件,然后通过记事本打开,点击另存为,在下面就可以看到mylabel.cpp文件的编码方式。我们看到mylabel.cpp文件的编码方式为utf8,而在Qt Creator内置的终端中,可能不是使用utf8的方式来显示字符串的,所以就出现了乱码。
在这里插入图片描述
那么我们应该怎么解决这个乱码问题呢?在Qt中自己封装的QString容器是可以帮助我们自动的处理编码方式的,而且不只是QString,Qt也提供了专门用来打印日志的工具,也能自动处理编码方式。Qt中提供了qDebug()工具,借助这个就可以完成打印日志的过程,很好的处理字符编码。
qDebug()其实是个宏,这个宏封装了QDebug对象,直接使用qDebug()就相当于使用cout了。后面我们在Qt中,如果向通过打印日志的方式输出一些调试信息,都可以优先使用qDebug(),因为qDebug()对编码进行了处理,并且qDebug()可以通过编译开关来实现一键式关闭。
在这里插入图片描述
在这里插入图片描述

文章来源:https://blog.csdn.net/dong132697/article/details/135769602
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。