【Qt】图形化和纯代码实现Hello world的比较

news2024/11/25 13:00:02

本篇文章使用俩种方式实现Qt上的Hello world:

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

图形化方式

双击Forms文件中的widget.ui文件,进入Qt Designer。

往界面上拖拽一个QLabel的控件,Qt Designer的右上角通过树形结构,显示出了当前界面上都有哪些控件。

通过双击这个Label控件,可以更改里面文本内容。

此时,在ui文件的xml中就会多出来一段代码,进一步的qmake就会在编译项目的时候,基于这个内容生成一段C++代码,通过这个C++代码构建出界面内容。

纯代码方式

一般通过代码来构建界面的时候,通常会把构造界面的代码放在widget/Mainwindow的构造函数中。

注意,unknow type name 'QLabel'无法识别类型,在Qt中,每一个类都有一个对应同名的头文件。这里需要包含QLabel的头文件。

注意,这里出现俩个可以选择label的头文件

  • qlabel.h 是早期的一中风格
  • QLabel

在1998年之后,C++标准成立了C++98标准之后,规定了包含头文件,统一使用#include< cstdio >代替原有的#include< stdio.h >文件。

label“标签”,意思是在界面上创建一个用来显示内容的字符串控件。

创建对象的时候,可以在堆上创建,也可以在栈上创建,这里更推荐在堆上创建。

QLabel(this); 是为了给当前这个label对象,指定一个父类对象,this指的是this此时调用这个类的对象。

设置控件中,要显示的文件内容。

这里为什么是QString呢?

        这是由于Qt诞生于1991年,那个时候C++还没有形成标准,C++更没有“标准库”这样的改变。而在当时,需要表示一个字符串,可以使用C风格字符串(/0结尾),也可以使用C++的string,但是二者均不太好使用。

        Qt当时为了可以开发更加顺畅,就发明了一个自己的库,搞了一系列的基础类来支持Qt的开发。

包括不限于:

  • 字符串 Qstring
  • 动态数组 Qvector
  • 链表 Qlist
  • 字典 Qmap
  • 等等

虽然很多年之后,C++标准中的容器已经被打磨的很不错了,但是很显然已经引入Qt的自己包装好的容器类,也不可能删除,就只能和现有的标准库中的容器类共存了。

        因此,在开发Qt代码的时候,如果需要用到上述容器类,可以使用标准库的容器,也可以使用Qt自己的容器。

但是在Qt原生的api中,涉及到的接口,用到都是Qt的容器。同时在后续代码中,还会经常见到Qstring这样的一些东西,但是很少见到std::string,但是Qstring和std::string之间也是可以很方便的相互转换。

总的来说,Qstring要比标准库中的std::string好用一点,就比如Qstring内部已经堆字符编码做了处理。

 在Qstring中也提供了C风格字符串作为参数的构造函数,不显示构造Qstring,在上述代码中,C风格字符串也会隐式构造成Qstring对象。

【注意】Qstring对应的头文件,已经被很多Q内置的其他类给间接包含了,因此一般不需要显式包含Qstring头文件。

此时,就显示出了Hello world,通过代码创建QLabel默认是在左上角。

关于内存泄漏问题

        在前文new一个对象时,没有出现delete,这里会不会出现内存泄漏呢?(内存泄漏是一个非常严重的问题,不仅仅是内存泄漏,包括文件扫描符泄漏等同类问题都是非常严重的,这种问题是容易第一时间发现的。)

        需要注意的是,上述代码,在Qt中并不会产生内存泄漏,label对象会在合适的时候被析构释放,这里虽然没有手写delete,但是确实能被释放,之所以能够把对象释放,主要是因为这个对象挂到了对象树上。

下面我们就结合对象树看看Qt中是否存在内存泄漏。

对象树

        在前端开发(网页开发)中,也涉及到类似的对象树(DOM),本质上是一个树形结构(N叉树),通过树性结构把界面上的各种元素组织起来。

        在Qt中也是类似,Qt的对象树也是一个N叉树,并把界面上的各种元素组织起来。

 通过这个树性结构,就把界面上要显示的这些控件对象都组织起来了。

        使用对象树,把这些内存组织起来,最重要的目的,就是为了能够在合适的时机,把这些对象统一进行释放。

【合适的时机】窗口关闭或者销毁的时间。

        这里的树上的这些对象,统一销毁是最好不过的,如果某个对象提前销毁,此时就会导致对应的控件就在界面上不存在了。

        通过new的方式创建对象,也就是为了把对象的生命周期交给Qt的对象树来统一管理。

        假设这个对象是按照栈上的变量创建的,就可能会存在一些提前释放的问题:

当把对象设成在栈上创建,此时就可以看到运行起来的程序无法显示出Hello world,此时label对象随着构造函数的结束就销毁了。

【继承的本质】对现有代码进行扩展。

 构造一个类来观察内存泄漏问题

 

 

Qt Creator虽然可以生成部分代码,但是没有完全生成,部分内容还是需要自己手动包含。

构造函数使用带QWidget* 版本的,这样才能确保自己的对象能够加到对象树上。

 然后点击.h文件对应的.cpp文件。

【小技巧】在Qt中,可以通过点击F4切换头文件和对应的.cpp文件。

调用父类的构造函数,才能让自己的类对象加入到Qt对象中,创建自定义的类,最主要的目的是自定义一个析构函数,在析构函数中,完成打印,方便看到最终的自动销毁对象的效果。

写下一个函数声明之后,按下alt+enter,就可以自动地在对应地.cpp文件中添加函数的定义,然后再将内容输出。 

使用自己定义的MyLabel代替原来的QLabel,所谓的“函数”本质上是扩展,保持原有功能不变的基础上,给对象扩展出一个析构函数,通过这个析构函数打印一个自定义的日志,方便观察程序运行的结果。

关闭窗口,看到有日志输出。

有日志,说明析构函数已经执行,虽然没有手动delete,但是由于把myLabel挂到了对象树上,此时窗口被销毁的时候,就会自动销毁对象树中的所有对象。

但是预期中打印“被销毁”,但是实际中打印出现乱码。乱码这种事情是经常会出现的,乱码出现的原因有且只有一个(不局限于C++),就是编码方式不匹配。

乱码问题的解释

问题:在计算机中,一个汉字占用几个字节?

  • 针对这个问题,只要回答出一个具体的数字,就一定是错误的。需要包含一定的前提条件:当前中文编码使用的是哪种方式(字符集)。

计算机中的数据是以二进制的方式存储的,对于英文字母,使用ASCII码值表示,规定了每一个字符,都有一个对应的数字来表示,只表示英文,一个字节足够了。

        对于中文来讲,中文的日常用字有四千多个,如果加上生僻字总数可以达到六万个左右,如果仍然使用一个类似于ASCII码表格存储,给每一个汉字分配一个整数即可,这对于计算机而言,似乎也是可以实现的。

        表示汉字的字符集,其实是有很多种的,但是不同的字符集,对于同一个汉字会使用不同的数字。

目前表示汉字字符集,主要是分为俩种方式:

  1. GBK(中国大陆)使用俩个字节表示一个汉字,Windows简体中文版默认的字符集就是GBK。
  2. UTF-8 / utf8,变长编码,表示一个符号,使用的字节数有变化,2-4个,但是在utf8中,一个汉字一般是3个字节,在Linux中默认就是utf8.

一个汉字具体的utf8/GBK编码数值可以通过在线工具来查看。

http://www.mytju.com/classCode/tools/encode_utf8.aspicon-default.png?t=N7T8http://www.mytju.com/classCode/tools/encode_utf8.asp

        所以,我们在Qt中看到的编码方式是不匹配的,原因是:如果字符串中本身是utf8编码的,但是终端(控制台)是按照GBK的方式来解析显示的,此时就会出现乱码,就比如拿着utf8的数值去查看GBK的码表,就会出现乱码的情况。

在Qt中,字符串的编码方式和当前文件的编码方式一致。

注意:

  • 如果显示的是UTF-8,说明这个文件就是UTF-8编码的;
  • 如果显示的是ANSI,说明这个文件是GBK编码的。

而Qt creator中出现了乱码,所以就不是utf8编码的,同时需要注意的是,这个终端好像不能设置字符编码的。

当前表示中文主流的方式是utf8(支持各国语言文字)。

在Qt中,Qstring是可以帮助我们自动的处理编码方式的;不仅Qstring,Qt也提供了专门用来打印日志的工具,也能自动处理编码方式。

Qt中提供了qDebug()工具,就可以完成日志的过程,这样可以很好地处理字符编码,不需要程序员过多干预,内部就会很好地处理问题。

 

【注意】QDebug是Qt中地一个类,一般不会直接使用这个类,而qDebug是一个宏,封装了QDebug对象。

可以直接使用qDebug(),可以当作cout直接使用。

        后续在Qt的过程中,如果想通过打印日志的方式输出一些调试信息,都优先使用qDebug(),虽然使用cout也可以,但是cout对于编码的处理不太好,在Windows上容易出现乱码,而如果是在Linux中使用Qt creator。一般就可以,这是因为Linux默认的编码一般都是utf8的。

为什么会选择输出日志来观察程序呢?

调试器很多时候都是有局限性的,是无法使用的,但是使用日志可以很好地解决问题,无论哪一种方式,本质上都是观察程序执行地中间过程和中间结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1992590.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CTFHUB-web-RCE-读取源代码

开启题目 网页发现了源代码&#xff0c;还是和前几题一样是 php:// &#xff0c;提示说 flag 在代码中&#xff0c;并且在 /flag 文件夹中&#xff0c;题目名字也叫读取源代码。 php://filter 是一种元封装器&#xff0c;专门用于数据流的过滤和筛选。与传统的文件操作函数相比…

selenium的UI自动化框架入门

环境准备 python、pycharme、chromedriver google下载的官网地址 https://google.cn/chrome/ chromedriver chromedriver的下载 https://chromedriver.storage.googleapis.com/index.html chromedriver配置环境变量 C:\Users\Administrator\.cache\selenium\chromedrive…

Python的安装环境以及应用

1.环境python2&#xff0c;Python 最新安装3.12可以使用源码安装 查看安装包 [rootpython001 ~]# yum list installed | grep epel 3[rootpython001 ~]# yum list installed | grep python [rootpython001 ~]# yum -y install python3 安装python3 查看版本 [root…

【LLM大模型】中国人工智能系列白皮书--大模型技术

近期&#xff0c;中国人工智能学会发布了 《2023 中国人工智能系列白皮书–大模型技术&#xff08;2023版&#xff09;》&#xff0c;涵盖了大模型发展历程、技术概述、风险与挑战以及未来发展展望等。 &#x1f449;CSDN大礼包&#x1f381;&#xff1a;全网最全《LLM大模型入…

控制某些请求不记录日志

说明&#xff1a;由于统一拦截日志请求&#xff0c;导致所有匹配的请求都会打印日志&#xff0c;这里需要控制有些请求执行不打印日志&#xff0c;比如定时每隔几秒执行某些请求。 具体实现如下&#xff1a; 一、自定义注解&#xff0c;如下&#xff1a; /** * Description: …

代码随想录算法(哈希表一)

目录 242有效的字母异位词 349两个数组的交集​编辑 set解决 数组解决 1两数之和 242有效的字母异位词 如果使用暴力解法的话直接可以使用两层for循环 我们平时用到的哈希表的数据结构就是数组 set和map 用到哈希表的话 就可以想这三个数据结构 这个题的话只有小写的英文…

Advanced IP Scanner - 网络管理工具介绍

Advanced IP Scanner 是一款免费、快速且用户友好的网络扫描工具。它能够帮助用户扫描局域网&#xff08;LAN&#xff09;中的所有设备&#xff0c;提供详细的设备信息&#xff0c;包括IP地址、MAC地址、设备名称和厂商信息。该工具对IT管理员和普通用户都非常有用&#xff0c;…

Java0 Java基础知识

预备知识 我们各种各样的信息是怎么存储到计算中的&#xff1f; 二进制 二进制是什么 由德国的莱布尼茨于 1679 年发明。 二进制数据是用0 和 1 两个数码来表示的数。它的基数为 2 &#xff0c;进位规则是"逢二进一" &#xff0c;数字计算机只能识别和处理由0和1符…

联想电脑重装系统时无法发现硬盘

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

C语言—水手分椰子问题

自己敲得&#xff1a; #include<stdio.h> #include<math.h> int main() {int i, j;float n;for (i 0;; i){n 5 * i 1;for (j 0; j < 4; j)//要求这四次每次的n都是整数才行{n n * 5 / 4 1;if (fmod(n, 1) ! 0) break;//或者 if(n!(int)n) break;}if (j …

TypeScript位运算

参考文献&#xff1a; https://blog.csdn.net/xuaner8786/article/details/138858747 https://www.runoob.com/typescript/ts-operators.html 位运算符 TypeScript 中的位运算符用于在二进制位级别上操作数字。这些运算符在处理整数和底层系统编程时特别有用。以下是一些使用…

C:冒泡排序

1、冒泡排序介绍&#xff1a; 冒泡排序的核心思想就是&#xff1a;两两相邻的元素进行比较。 先用一个例子来帮助大家理解一下冒泡排序的算法是怎们进行的 有一排高矮不同的人站成一列&#xff0c;要按照从矮到高的顺序重新排队。 冒泡排序的方法就是&#xff0c;从第一个人…

【栈和队列】常见面试题

文章目录 1.[有效的括号](https://leetcode.cn/problems/valid-parentheses/description/)1.1 题目要求1.2 利用栈解决 2. [用队列实现栈](https://leetcode.cn/problems/implement-stack-using-queues/description/)2.1 题目要求2.2 用队列实现栈 3.[用栈实现队列](https://le…

cesium gltf模型

cesium 支持的三维模型格式包括GLTF和GLB&#xff08;二进制glTF文件&#xff09;。 本文通过使用Entity图元的modelGraphics对象来加载gltf模型&#xff0c;简单对gltf模型的加载进行了封装。通过设置模型的欧拉角&#xff0c;可以计算模型的朝向。 1 3D数学中模型旋转的方式…

数据定义和操作

一、数据定义语言和操作语言 1. 分析需求设计数据库表 根据“优乐网”系统需求&#xff1a; 此系统满足以下需求&#xff1a; 系统支持生成商品的入库和出库。入库之后的商品可以在平台显示 所有用户都可以浏览系统的商品信息&#xff0c;只有注册用户才能订购团购商品和服…

机械学习—零基础学习日志(python编程)

零基础为了学人工智能&#xff0c;正在艰苦的学习 昨天给高等数学的学习按下暂停键&#xff0c;现在开始学习python编程。 我学习的思路是直接去阿里云的AI学习课堂里面学习。 整体感觉&#xff0c;阿里云的AI课堂还是有一些乱&#xff0c;早期课程和新出内容没有更新和归档…

进阶学习------linux运维读写执行权限

进阶学习------linux运维读写执行权限 在UNIX和类UNIX操作系统中&#xff0c;文件权限是通过一组特定的数字来表示的&#xff0c;这些数字分为三组&#xff0c;分别对应于用户&#xff08;文件所有者&#xff09;、组和其他用户的权限。每组权限由三个二进制位表示&#xff0c;…

如何进行硬件调试?

硬件调试是硬件系统设计、开发和制造过程中不可或缺的一环&#xff0c;旨在对可能出现的问题进行分析和解决。以下是进行硬件调试的一般步骤和方法&#xff1a; 一、准备阶段 熟悉设计文档&#xff1a;在开始调试之前&#xff0c;需要详细阅读和理解硬件系统的设计文档、原理图…

【探索数据结构与算法】——深入了解双向链表(图文详解)

目录 一、双向链表的基本概念 ​​​ 二、双向链表的结构 三、双向链表的基本操作实现方法 1.双向链表的初始化 2.双向链表的头插 3.双向链表的尾插 6.查找节点 7.在指定位置之前插入节点 8.删除指定位置节点 9.打印链表数据 10.双向链表销毁 四、完整代码实现 …

html+css+js网页设计 星享咖啡6个页面(带js) ui还原度90%

htmlcssjs网页设计 星享咖啡6个页面&#xff08;带js&#xff09; ui还原度90% 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等…