【Qt】Qt界面构建与对象管理:从 “Hello World“ 到内存释放

文章目录

  • 1. 通过图形化界面创建控件
  • 2. 通过纯代码方式创建控件
  • 3. 对象树管理与内存管理
  • 小结:

在软件开发中,构建用户界面是至关重要的一步。Qt作为一个跨平台的C++框架,提供了强大的界面构建工具和对象树管理机制,使得界面开发变得简单高效。本文将介绍两种实现 “Hello World” 界面的方法:一种是通过图形化界面创建控件,另一种是通过纯代码方式创建控件,并探讨了Qt框架中的对象树管理机制与前端开发中的DOM对象树的类比。

1. 通过图形化界面创建控件

Qt提供了可视化设计工具,通过拖拽控件、设置属性和信号槽等方式,可以快速构建用户界面。下面是通过图形化界面创建一个显示 “Hello World” 的控件的步骤:

  1. 打开Qt Creator,创建一个新的Qt Widgets Application项目。
  2. 在设计模式下,从左侧的控件库中拖拽一个Label控件到界面上。
  3. 在属性编辑器中设置Label的文本为 “Hello World”。
  4. 编译运行程序,即可看到界面上显示了 “Hello World”
    在这里插入图片描述

2. 通过纯代码方式创建控件

虽然图形化界面设计工具方便直观,但有时候我们也需要通过纯代码的方式来创建控件。下面是通过纯代码方式在Qt中创建一个显示 “Hello World” 的控件的示例代码:

// widget.cpp
// 一般通过代码来构造界面的时候
// 通常会把构造界面放到 Widget/MainWindow 的构造函数中
#include "widget.h"
#include "ui_widget.h"#include<QLabel>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 创建对象的时候可以在栈上创建栈上,也可以在堆上创建// QLabel label(this) // 在栈上创建会,一下马上消失// 更推荐这种直接在堆上面创建的方式QLabel* label = new QLabel(this); //给当前的 label对象,指定一个父对象label->setText("hello world"); // 在QString 中也提供了C风格字符串作为参数的构造函数.// 不显式构造QString,上述代码中,C风格字符串也会隐式构造成QString对象.
}Widget::~Widget()
{delete ui;
}

Qt在早期确实为了解决C++标准库的不足而引入了自己的一套基础类和容器类,以便支持Qt框架的开发。下面是一些常用的Qt自带容器类及其功能:

  1. QString:用于处理字符串,支持 Unicode 字符串,提供了丰富的字符串操作方法。
  2. QVector:动态数组,类似于std::vector,但提供了更多的功能和操作。
  3. QList:链表,类似于std::list,但也提供了额外的操作和功能。
  4. QMap:字典,类似于std::map,用于键值对的映射。
  5. QSet:集合,类似于std::set,用于存储不重复的元素。

这些Qt自带的容器类在Qt的API中被广泛使用,因此在Qt开发中,通常会见到这些类的使用。虽然这些类与标准库中的类功能类似,但它们通常提供了更多的特性和对Qt框架的更好的支持。

在使用这些Qt容器类时,可以方便地进行与标准库容器类的互操作,例如QString和std::string之间的转换。同时,Qt的容器类内部已经处理了一些字符编码的细节,使得处理
Unicode 字符串更为方便。相比之下,标准库中的std::string可能需要额外的处理来支持特定的字符编码。

总的来说,Qt提供的这些容器类为开发者提供了更多选择,同时也更好地与Qt框架集成,使得开发过程更加高效和便捷。

// 更推荐这种直接在堆上面创建的方式
QLabel* label = new QLabel(this); //给当前的 label对象,指定一个父对象 
// 此处通过new的方式创建对象,也就是为了把这个对象的声明周期,交给Qt的对象树统一管理。

3. 对象树管理与内存管理

Qt框架中的对象树管理机制类似于前端开发中的DOM对象树,Qt中也是类似,也是搞了一个对象树,也是N叉树,把界面上的各种元素组织起来了 。通过将控件添加到父控件中,Qt能够自动管理控件的生命周期,从而避免内存泄漏。在上述示例中,我们给QLabel控件指定了父对象为当前的Widget,这样当Widget被销毁时,其子控件也会被自动销毁,从而确保内存的正常释放。
在这里插入图片描述

证明对象是被自动销毁了的:
新建一个C++类:
在这里插入图片描述
在这里插入图片描述
Qt Creator 是帮我们生成了一些代码,但是没有完全生成,头文件没给咱们自动包含,只能自己手动包含了。

在这里插入图片描述

// widget.cpp
#include "widget.h"
#include "ui_widget.h"#include "mylabel.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 使用自己的定义的 Mylabel 代替原来的 QLabel, 所谓的“继承” 本质上是扩展,保持原来的功能不变的基础上,// 给对象扩展出一个析构函数,通过这个析构函数,答应一个自定义日志,方便咱们观察运行效果。MyLabel* label = new MyLabel(this);label->setText("hello world");
}Widget::~Widget()
{delete ui;
}
// widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;
};
#endif // WIDGET_H
// mylabel.cpp
#include "mylabel.h"
#include <iostream>// QLabel(parent) 就是这个调用父类构造函数,调用这个,才能让咱们自己类的对象加入到Qt对象树中
MyLabel::MyLabel(QWidget* parent) : QLabel(parent)
{}MyLabel::~MyLabel()
{std::cout << "MyLable 被销毁!" << std::endl;
}
// mylabel.h
#ifndef MYLABEL_H
#define MYLABEL_H#include <QLabel>class MyLabel : public QLabel
{
public:// 构造函数使用带 QWidget* 版本的// 这样才能保证咱们自己的对此昂能够加到对象树上MyLabel(QWidget* parent);~MyLabel();
};#endif // MYLABEL_H

当关闭窗口的时候
在这里插入图片描述
在关闭窗口时,预期输出 “MyLabel 被销毁!”,但实际上输出了乱码。这是因为输出的中文字符在计算机中存储时所占字节数取决于字符集的不同。

在计算机中,一个汉字,占几个字节?
针对这个问题,只要你回答出一个具体的数字,就一定是错的 !!
前提条件:当前中文编码使用的是哪种方式(字符集) 计算机存的其实是二进制数字 英文字母,怎么表示的 ?
ASCII码表,规定了每个字符,都有一个对应的数字来表示 。
目前,表示汉字字符集,主要是两种方式.

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

出现乱码的原因就是:
如果你字符串本身是utf8 编码的,但是终端(控制台)是按照gbk的方式来解析显示的,此时就会出现乱码。
(拿着utf8这里的数值,去查询gbk的码表),此时就会出现乱码了 !!

std::cout << "MyLable 被销毁!" << std::endl;

在这里插入图片描述

Qt中有一个好东西,QString:是可以帮助我们自动的处理编码方式的。
不止是QString,Qt也提供了专门用来打印日志的工具,也能自动处理编码方式,Qt中提供了一个qDebug()工具,借助这个,就可以完成打印日志的过程.很好的处理字符编码。(不需要程序员关注了,内部帮咱们搞好了)

在这里插入图片描述
这样就正常了
在这里插入图片描述

后续再Qt中,如果想通过打印日志的方式,输出一些调试信息,都优先使用 qDebug。虽然使用 cout 也行,但是 cout 对于编码的处理不太好,在 windows 上容易出现乱码(如果是Linux 使用 Qt Creator,一般就没事了,Linux默认的编码一般都是 utf8) 使用qDebug,还有一个好处 ,打印的调试日志,是可以统一进行关闭的 !
输出的日志,是开发阶段,调试程序的时候,使用的。 如果你的程序发布给用户,不希望用户看到这些日志的 ! qDebug 还可以通过编译开关,来实现一键式关闭 。

小结:

  1. QLabel类:能够在界面上显示字符串,通过setText()方法设置显示内容,参数为QString。
  2. 内存泄漏/资源泄漏:在Qt中需要注意及时释放对象,防止内存泄漏或者文件资源泄漏。
  3. 对象树:Qt通过对象树来管理界面控件对象的释放。推荐使用new方式在堆上创建对象,并指定父对象,在构造函数中将对象挂到对象树上,以便统一释放对象。创建的时候,在构建函数中,指定父对象(此时才会挂到树上),如果你的对象没有挂到对象树上,就必须记得手动释放
  4. 继承扩展:通过继承Qt内置的类,可以对现有控件进行扩展。例如,可以创建自定义类MyLabel,继承自QLabel,并重写析构函数,在其中加入日志记录以观察对象释放过程。继承本质上是对现有代码进行扩展,可以重写控件中的功能以实现个性化需求。
  5. 乱码问题和字符集:在处理中文字符时,需要注意字符集的问题。常见的字符集有GBK和UTF-8,输出乱码可能是因为字符集不匹配导致的。
  6. 日志打印:在Qt中推荐使用qDebug()函数打印日志信息,而不是使用cout。qDebug()能够自动处理字符编码,方便统一进行日志输出管理,同时能够通过编译开关一键式关闭调试信息输出。

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

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

相关文章

单页面首屏优化,打包后大小减少64M,加载速度快了13.6秒

需求背景 从第三方采购的vue2 ElementUI实现的云管平台&#xff0c;乙方说2011年左右就开始有这个项目了&#xff08;那时候有Vue了吗&#xff0c;思考.jpg&#xff09;。十几年的项目&#xff0c;我何德何能可以担此责任。里面的代码经过多人多年迭代可以用惨不忍睹来形容&a…

Qt做关于界面

在上位机系统中&#xff0c;经常需要显示当前软件版本&#xff0c;当前fpga版本&#xff0c;那么咱就做一个help的菜单的关于界面 解决的问题&#xff1a; 解决显示版本信息的UI Axure界面图&#xff1a; 如何实现&#xff1a; 实现文件的存储&#xff1a;QSetting来存储版…

玩转Virtual Box虚拟机

玩转Virtual Box虚拟机 虚拟化技术和虚拟机简介 什么是虚拟化技术&#xff1f; 虚拟化技术是将计算机的各种硬件资源予以抽象、转换、分割、组合的一种计算机技术。虚拟化技术打破了实体结构间不可切割的障碍&#xff0c;从而使用户可以按照需求重新组合硬件资源&#xff0c…

NX二次开发UF_MTX(矩阵运算)常用函数

目录 一、概述 二、函数的介绍 2.1 UF_MTX3_copy&#xff08;复制原来矩阵&#xff09; 2.2 UF_MTX3_determinant&#xff08;计算矩阵的行列式&#xff09; 2.3 UF_MTX3_identity&#xff08;单位矩阵&#xff09; 2.4 UF_MTX3_initialize&#xff08;可以根据X、Y方向向…

R: 阿尔法α多样性计算和箱图制作,以及差异分析

# install.packages("vegan") library(vegan) library(ggplot2) library(ggpubr)setwd("xxx") # 使用read.table()函数读取数据 df <- read.table("xxx", header TRUE, row.names 1)# 转置数据框 df <- t(df)# 计算每个样品的香农多样性…

【Linux】虚拟机与Xshell及VS Code的连接

一、基础环境 虚拟机&#xff1a;VMware Workstation Pro 虚拟机镜像&#xff1a;ubuntu-18.04.5-desktop-amd64.iso 其他&#xff1a;Xshell 6、Xftp 6、Visual Studio Code 上述软件的安装操作不再赘述&#xff0c;CSDN上有大量的优秀博文&#xff0c;可参考&#xff1a;详细…

SpringBoot---------Lombook

Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具&#xff0c;通过使用对应的注解&#xff0c;可以在编译源码的时候生成对应的方法&#xff0c;也就是简化咱们之前pojo&#xff0c;实体类里面臃肿的get/set有参无参。 首先查看一…

学习51单片机 C语言知识

一、数据类型 C 语言包含的数据类型如下图所示 C51 的数据类型分为基本数据类型和组合数据类型&#xff0c;情况与标准 C 中的数据类型基本相同&#xff0c;但其中 char 型与 short 型相同&#xff0c;float 型与 double 型相同&#xff0c;另外&#xff0c;C51 中还有专门针…

免费一年期ssl证书怎么申请?看这里!(教育版、政务版)

自从去年年底开始&#xff0c;各大公有云陆续下架一年期的免费ssl证书&#xff0c;且申请数量都做了限制调整&#xff0c;那么现在去哪里申请免费一年期的ssl证书呢&#xff1f; 一、短期ssl证书 首先了解一下短期免费证书的平台&#xff0c;一般免费证书都为90天有效期&…

创新案例|Amazon.com 2023 年营销策略:电子商务零售巨头商业案例研究

2022 年最后一个季度&#xff0c;亚马逊报告净销售额超过 1,492 亿美元。这种季节性峰值是亚马逊季度报告的典型特征&#xff0c;但增长是不可否认的&#xff0c;因为这是该公司有史以来最高的季度。毫无疑问&#xff0c;这家电商零售巨头继续引领电商增长。本文将介绍我们今天…

木马——文件上传

目录 1、WebShell 2.一句话木马 靶场训练 3.蚁剑 虚拟终端 文件管理 ​编辑 数据操作 4.404.php 5.文件上传漏洞 客户端JS检测 右键查看元素&#xff0c;删除检测代码 BP拦截JPG修改为php 服务端检测 1.MIME类型检测 2.文件幻数检测 3.后缀名检测 1、WebShell W…

充气膜体育馆:为学校带来的健康运动环境

充气膜体育馆作为一种先进的建筑结构&#xff0c;配备先进的空气净化系统&#xff0c;为学校带来了重要的意义和价值。 充气膜体育馆不仅提供了室内运动场地&#xff0c;还通过先进的空气净化系统保障了学生在任何天气条件下都能进行健康的体育活动。尤其是在雾霾天气频繁的地区…

使用docker打包当前服务器的neo4j环境

Docker 是一个开源的应用容器引擎,它允许开发者将应用程序及其依赖打包到一个可移植的容器中,这样应用程序就可以在任何支持Docker的平台上运行,而无需担心环境差异。 当运行一个Docker容器时,它会加载一个镜像并运行它。Docker在容器内部创建一个隔离的环境,这个环境被称…

使用spring boot集成shardingsphere分库分表简易测试

根据如下pom整上一个spring-boot项目&#xff0c;spring-boot版本用2.3.5&#xff0c;shardingsphere用5.1.1。 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://ww…

7-25 念数字

题目链接&#xff1a;7-25 念数字 一. 题目 1. 题目 2. 输入输出格式 3. 输入输出样例 4. 限制 二、代码 1. 代码实现 #include <iostream> #include <string> using namespace std;const string pinyin[] { // 每个数字对应的拼音"ling","yi&…

【Hadoop】- YARN架构[7]

前言 Yarn架构是一个用于管理和调度Hadoop集群资源的系统。它是Hadoop生态系统的一部分&#xff0c;主要用于解决Hadoop中的资源管理问题。 通过使用Yarn架构&#xff0c;Hadoop集群中的不同应用程序可以共享集群资源&#xff0c;并根据需要动态分配和回收资源。这种灵活的资…

验证线缆(汽车线束、网线、多芯线)破损或断开与正常线缆的区别在哪里?依AEM CV-100 k50测试仪

工厂产线生产的线缆&#xff08;汽车线束、网线、多芯线&#xff09;做成成品&#xff0c;即2端都安装好了模块。在这种情况下如何快速的判定此条线缆是合格的呢&#xff0c;此处的合格为物理层面上的合格&#xff08;不会出现开路、短路&#xff09;&#xff0c;也就是最基本保…

client-go源码结构及客户端对象

一、基础知识介绍 1、GVR 和 GVK G Goup资源组&#xff0c;包含一组资源操作的集合VVersion资源版本&#xff0c;用于区分不同API的稳定程度及兼容性RResource资源信息&#xff0c;用于区分不同的资源APIKKind资源对象类型&#xff0c;每个资源对象都需要Kind来区分它自身代表…

冒泡排序c++

题目描述 编程输入n(1≤n≤20)个小于1000非负整数&#xff0c;然后自动按从大到小的顺序输出。&#xff08;冒泡排序&#xff09; 输入 第一行&#xff0c;数的个数n; 第二行&#xff0c;n个非负整数。 输出 由大到小的n个非负整数&#xff0c;每个数占一行。 样例输入 …

restful请求风格的增删改查-----修改and删除

一、修改&#xff08;和添加类似&#xff09; 前端&#xff1a; <script type"text/javascript">function update(){//创建user对象var user {id:$("#id").val(),username:$("#username").val(),password:$("#password").val…