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

本篇文章使用俩种方式实现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.rhkb.cn/news/394697.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

修改SpringBoot启动图标banner

方式一: 将图标文件命名为banner放在resources目录下 文本文件banner 图片banner 方式二&#xff1a;通过配置文件指定图标路径 指定文本图标&#xff1a;spring.banner.locationclasspath:相对于resources下的位置 ("classpath:"可以省略) 指定图片作为图标: sprin…

同态加密和SEAL库的介绍(一)简介

写在前面&#xff1a; 最近在做同态相关的内容&#xff0c;这里记录下相关的知识点和所踩过的坑&#xff0c;希望对大家有帮助。预计分几篇来详细介绍&#xff0c;从概念简介到不同模式介绍&#xff0c;具体包括了每种模式的编解码和加解密以及他们性能的比对。 虽然同…

win11启动IIS服务配置成web服务器·

为什么要将本地配置为 Web 服务器&#xff1f; 在 Web 开发过程中&#xff0c;将本地配置为 Web 服务器有诸多好处&#xff1a; 实时预览: 修改代码后&#xff0c;无需每次都上传到远程服务器&#xff0c;即可在本地浏览器中实时查看效果。 离线开发: 无需依赖网络连接&#x…

R9000P 双系统安装 win11 和 ubuntu

网上了解到一堆关于 r9000p 安装较老的ubuntu系统&#xff0c;会有一堆问题 可能是电脑硬件比较新&#xff0c;较老的系统相关方面不兼容 那么干脆直接装新一点的系统 我安装了 Ubuntu 22.04 1 根据相关教程利用u盘制作系统盘 ultraISO 推荐使用清华源 速度快一点 https://…

AI资本泡沫要来了么?——Coatue EMW 2024会议摘要

引言 随着生成式人工智能的快速发展&#xff0c;科技领域正经历着一场前所未有的变革。然而&#xff0c;伴随这一热潮而来的&#xff0c;是关于AI资本泡沫的激烈讨论。历史上&#xff0c;每一次技术革命都带来了巨大机遇&#xff0c;同时也伴随着泡沫和风险。本文将通过Coatue…

企业级敏捷框架:业务驱动型敏捷与产品需求团队

本文介绍了一种新的企业级敏捷框架——业务驱动型敏捷&#xff08;Business-driven Agile&#xff09;与 PRT&#xff08;Product Requirement Team&#xff09;&#xff0c;旨在解决传统敏捷方法中需求定义的瓶颈&#xff0c;从而提升产品价值并提高开发效率。原文: A new ent…

2024年史上最好用的10款项目管理软件有哪些?

项目管理行业发展趋势 随着信息技术的不断进步&#xff0c;项目管理也呈现出愈加智能化、自动化的发展趋势。无论是大型企业还是中小型公司&#xff0c;都亟需借助先进的项目管理工具&#xff0c;来实现对项目进度、资源、风险等各个环节的精细化管控。 然而在实际应用中&…

Git合并多笔提交为一笔

Git合并多笔提交为一笔 1. 背景 在实际项目开发中&#xff0c;我们会基于生产分支拉出很多需求分支&#xff0c;在需求分支开发完成后再将代码合到生产分支&#xff0c;但随着提交次数越来越多&#xff0c;我们在合到生产分支的时候就得一笔一笔的入库&#xff0c;特别麻烦&a…

Nacos-配置中心

1.为什么要使用配置中心&#xff1f; 2.常用的配置中心组件&#xff1f; 3.如何使用&#xff1f; 在配置中心创建配置文件 启动一个单列的nacos服务 点击发布 在微服务中使用 添加依赖 <!--nacso配置中心的依赖--><dependency><groupId>com.alibaba.cloud&l…

安卓Termux系统设备安装内网穿透工具实现远程使用SFTP传输文件

文章目录 前言1. 安装openSSH2. 安装cpolar3. 远程SFTP连接配置4. 远程SFTP访问4. 配置固定远程连接地址 前言 本教程主要介绍如何在安卓 Termux 系统中使用 SFTP 文件传输&#xff0c;并结合cpolar内网穿透工具生成公网地址&#xff0c;轻松实现无公网IP环境远程传输&#xf…

SQLiteStudio 连接sqlite3数据库(真机数据库可视化调试)

SQLiteStudio安装 官网链接&#xff1a;https://sqlitestudio.pl/ 下载后&#xff0c;直接按部就班&#xff0c;打开即可使用 用户手册&#xff08;工具如何使用直接看这份就可以了&#xff09;&#xff1a;https://github.com/pawelsalawa/sqlitestudio/wiki/User_Manual 其…

网安新声 | 微软蓝屏事件安全启示录

网安加社区【网安新声】栏目&#xff0c;汇聚网络安全领域的权威专家与资深学者&#xff0c;紧跟当下热点安全事件、剖析前沿技术动态及政策导向&#xff0c;以专业视野和前瞻洞察&#xff0c;引领行业共同探讨并应对新挑战的策略与可行路径。 2024年7月19日&#xff0c;微软发…

node中path模块处理路径以及path模块的方法的使用

1.案例代码 // 1.导入fs模块&#xff0c;来操作文件 const fs require(fs) const path require(path)// 2.path.join():拼接文件路径 console.log(path.join(F:,/kanno,临时文件/7.31,/image,../,成绩.txt)); const filePath path.join(/files,成绩.txt) console.log("…

Unity Addressables bundle依赖查看和资源重复查看工具

在开发的过程有时候想要知道addressables 打包出来bundles的依赖关系&#xff0c;以及资源的重复情况。直接通过自带的addressables工具查看有点困难。这里分享一个github上的开源工具。名称为UnityAddressablesBuildLayoutExplorer。该工具可以帮助查看所有文件的依赖情况&…

AI在医学领域:使用眼底图像和基线屈光数据来定量预测近视

关键词&#xff1a;深度学习、近视预测、早期干预、屈光数据 儿童近视已经成为一个全球性的重大健康议题。其发病率持续攀升&#xff0c;且有可能演变成严重且不可逆转的状况&#xff0c;这不仅对家庭幸福构成威胁&#xff0c;还带来巨大的经济负担。当前的研究着重指出&#x…

LeetCode Hard|【460. LFU 缓存】

力扣题目链接 LFU全称是最不经常使用算法&#xff08;Least Frequently Used&#xff09;&#xff0c;LFU算法的基本思想和所有的缓存算法一样&#xff0c;一定时期内被访问次数最少的页&#xff0c;在将来被访问到的几率也是最小的。 相较于 LRU 算法&#xff0c;LFU 更加注重…

什么是云原生?(一)

1. 前言 停下手头的工作&#xff0c;让你的同事定义“云原生”一词。你很可能会得到几个不同的答案。 1.1 让我们从一个简单的定义开始&#xff1a; 云原生架构和技术是一种设计、构建和操作在云中构建并充分利用云计算模型的工作负载的方法。 1.2 云原生计算基金会给出了官方…

简单的 CompletableFuture学习笔记

简单的 CompletableFuture学习笔记 这里记录一下自己学习的内容&#xff0c;简单记录一下方便后续学习&#xff0c;内容部分参考 CompletableFuture学习博客 1. CompletableFuture简介 在api接口调用时间过长&#xff0c;调用过多外围接口时&#xff0c;为了提升性能&#x…

Android 12系统源码_多屏幕(一)多屏幕设备显示Activity

前言 分屏&#xff1a;是指一个屏幕分出多个窗口&#xff0c;分别显示不同应用的界面&#xff0c;这在当前的手机设备中很常见。多屏&#xff1a;是指一个设备存在多个屏幕&#xff0c;这些可能是虚拟屏幕或者实体硬件屏幕&#xff0c;不同的应用同时显示在不同的屏幕中&#…

SpringBoot多数据源事务处理

多数据源时,一般会配置多个事务管理器 Spring编程式 第二种方式 不可能去同一个方法上写两个事务注解 不允许 SpringBoot 2.6.0之后禁止自己注入自己 本来可以自己注入自己去调用 (为什么要自己注入自己调用,AOP代理,类不是自己写的类) 最简单方式 引入 <dependency&…