QT跨平台应用程序开发框架(2)—— 初识QT

目录

一,创建helloworld

1.1 通过图形化

1.2 通过代码

1.3 通过编辑框

1.4 使用按钮

二,对象树

2.1 关于对象树

2.2 演示释放流程

三,乱码问题

3.1 为什么会有乱码问题

3.2 解决乱码问题

四,认识Qt坐标系

五,周边

5.1 命名规范

5.2 快捷键

5.3 如何使用帮助文档


一,创建helloworld

在窗口上打印helloworld我们有两种方式:

  • 一种是通过图形化的方式,在界面上创建出一个控件,显示helloworld
  • 另一种是通过纯代码的方式,通过编写代码在界面上创建控件,显示helloworld

1.1 通过图形化

先双击 .ui 文件来到图形化编辑页面:

然后就会在页面的右上方显示我们安装的控件:

最后我们点击左下角运行按钮,我们创建的窗口上就会显示一个hello world字符串

1.2 通过代码

  • 在我们项目的 widget.cpp 文件中,有一个构造函数:
  • 如果我们要通过代码去构造界面,一般都会把构造界面的代码放在 Widget/MainWindow类的构造函数里面,注意只是创建并不是使用
  • 我们要使用一个类,一般都要加上对应的头文件,并且一般每个类都有一个对应同名的头文件,之后就可以接在构造函数中new一个QLabel,在堆上创建;或者直接在栈上创建,Qt更推荐在堆上创建,原因我们后面的对象树再详细讲讲:
  • 另外,我们在new对象时,建议把this也放进去,就是new QLabel(this); 这个表示给这个label对象指定一个父对象,这点我们对象树再详细讲讲

在包含头文件时,可能会出现两个头文件:

  • 像第二个qlabel.h 这种是上古时期的头文件命名风格,比较Qt是1991年出来的, 那时候的C++编程还是比较荒蛮的状态
  • 直到1998年C++ 推出了 C++98 标准,规定包含头文件,统一使用 #include<cstdio> 代替C语言的 #include<stdio.h>

之后我们就可以往label对象里面设置一个文本:

关于QString类型:

  • Qt诞生于1991年,C++还未形成标准,C++也就没有“标准库”这样的概念
  • 所以在那个年代如何表示一个字符串,有很多方式,比如C风格的字符串(\0结尾),或者是C++的string
  • 但是在当时,STL也还没有搞起来,什么都不太好用,于是Qt自己搞了一套轮子,也就搞了一系列基础类来支持Qt的开发,比如字符串QString,动态数组 QVector,还有链表QList字典 QMap等
  • 虽然后面有了 C++标准和STL,但是想要Qt直接舍弃原有的内容,也不太现实,所以只能和现有的标准库中的容器类共存了
  • 所以我们自己在开发过程中要使用容器类,两者都可以是使用,但是在Qt原生的 api 中,涉及到的接口,用的都是Qt自己那一套容器,比如上面的设置文本,很多方法的参数都是Qt的容器类而不是STL的
  • 但是QString用起来要比 std::string香很多,因为QString内部已经对字符编码做了处理,和java一样,而不像std::string那样啥也没干,所以不经常出现乱码问题

之后直接运行,窗口也就会显示出hello world了 ,只是默认在左上角,如果要想放到其它位置,也可以做到,后面会详细讲解

问题:我们以new创建的对象,但是最后没有delete,会出现内存泄漏吗

解答

  • 上述代码不会有内存泄漏,label对象会在合适的时候自动释放
  • 主要的原因,就是我们前面构造的时候,把this给传进去了,也就是把这个对象挂在了对象树上,下面我们就来详细了解下对象树

1.3 通过编辑框

Qt中有两种编辑框:①单行编辑框(QLineEdit)    ②多行编辑框(QTextEdit)

我们要用到的控件是Input Qidgets下的Line Edit,也是最简单的单行编辑框

当然,也可以用代码来创建编辑框,并且方式和上面是非常相似的:

1.4 使用按钮

按钮控件位于Buttons目录下的Push Button:

但是目前这个按钮能点击,但是没有反馈,也正常,因为我们还没有设置,我们要想让这个按钮点击后有反馈,需要用到Qt中一个非常重要的机制叫做“信号槽机制”,这个我们后期再详细介绍,这里我们先简单演示下:

别忘记在widget.h里声明函数哦:

效果如下:

问题:connect的第一个参数是如何访问到具体某个控件的?

解答:这时候Qt Designer右下角那一坨东西就有用了:

  • 我们在Qt Designer中通过拖拽方式创建一个控件的时候,会给这个控件分配一个objectName属性
  • 这个属性的值是在这个页面中唯一的,比如上面我们搞了两个按钮,对应的objectName就不一样
  • qmake会根据objectName生成对应的C++代码,其中QPushButton对象的变量名字就是这里的objectName,这个变量就是ui属性中的成员变量
  • 这个objectName也可以自己修改

上面是通过拖拽方式创建按钮,下面我们通过代码来创建按钮:

二,对象树

2.1 关于对象树

前端开发(网页开发)也涉及到类似对象树(DOM),本质上也是一个树形结构(N叉树),用于组织页面上的各种结构

Qt中也是类似,也是搞了一个对象N叉树,把界面上的各种元素组织起来,比如我们的页面大概长这样:

那么对象树就大概长这样:

  •  用对象树把这些内容组织起来,最主要的目的,就是能够对这些对象统一管理,比如统一释放,这点和我们Linux里的“先描述,再组织”的目的非常相似

问题:上面这些对象统一销毁是最好的,那么如果是一个对象先销毁了,会发生什么?

解答:会导致对应的控件在页面上无法显示,导致对应的控件在页面上不存在了

所以我们以new的方式创建对象,就是为了把这个对象的生命周期,和 Qt 对象树的生命周期进行同步,所以对象会随着对象树的销毁统一全部销毁,并且也方便管理

问题:如果改为在栈上创建对象会发生什么?

解答:如下图:

2.2 演示释放流程

上面说一大堆对象树方便释放,但是实际效果并不明显,下面我们自己搞一个QLabel类,然后打印一些东西来演示释放效果:

①创建对应的C++文件:

 

然后就多出了两个文件:

②实现mylabel.h

由于我是习惯与函数声明和定义放一起写的,所以mylabel.cpp没有用到,大家也可以按照自己的方式写,下面是MyLabel类也就是mylabel.h的实现:

#ifndef MYLABEL_H
#define MYLABEL_H

#include<QLabel>
#include<iostream>
class MyLabel : public QLabel
{
public:
    MyLabel(QWidget* parent) //用带参数的构造函数,这样才能确保自己的对象能够加到对象树上
        :QLabel(parent)
    {}

    ~MyLabel()
    {
        std::cout << "MyLabel 已销毁!" << std::endl;
    }
};

#endif // MYLABEL_H

③在widget.cpp中创建并调用MyLabel类 

 

④查看效果

注意,析构函数是对象销毁时才会调用,所以当窗口生成出来要再关闭后,才会调用析构函数,如下动图:

可以看到析构函数能够进行打印,但是这里出现了乱码,下面我们来解释并解决一下

三,乱码问题

3.1 为什么会有乱码问题

乱码问题我们后面会经常涉及到,但是乱码出现的原因大部分情况下只有一个,就是“编码方式不匹配

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

解答

  • 绝大多数的人回答时都会即答“2个字节”,但是实际上,针对这个问题,只要回答一个具体的数字,100%是错的,因为我们需要搞清楚一个前提条件,就是我们当前的中文编码是哪种方式(字符集)
  • 计算机存的是二进制,英文字母和很多符号我们是用ASCII码表搞得,规定了每个字符都有由一个数字来表示就够了,因为英文就那么多
  • 我们常用的汉字大概是4千左右,算上各种生僻字的话,大概有6w多个,所有就搞了一个更大的表格用更大的数字来表示汉字了,对于计算机来说6w多个符号的表格没有什么压力的,但是这个表格是什么样子,具体每个汉字用哪个数字表示,就有很多种了

目前表示汉字字符集我们主要是两种方式:

  • ①GBK,使用2个字节的大数字表示一个汉字,我们Windows简体中文版就是默认用的GBK
  • ②UTF-8 / utf8,属于变长编码,表示一个符号,使用的字节数有变化;在utf8中,一个汉字一般是3个字节

我们可以在Windows本地和Linux中验证一下:

下面是Linux中的执行结果:

#include<iostream>
#include<string.h>

int main()
{
    const char* s = "好";
    std::cout << strlen(s) << std::endl;
}

下面是在Windows上的测试结果: 

3.2 解决乱码问题

我们在析构函数中打印中文,那么这个代码的编码方式就是和主体文件直接相关的

  • Qt Creator 内置的终端不一定是 utf8 的方式来显示字符串,并且好像也不能设置字符编码,但是既然出现了乱码,那么肯定不是 UTF-8
  • 当前表示中文的主流方式还得是 UTF-8,因为不仅支持中文,很多其它国家文字都可以支持

但是不用担心,我们之前也说过,QString 是可以帮我们自动处理编码问题的;而且不止QString,Qt 也提供了专门用来打印日志的工具,也能自动处理编码问题

 并且 qDebug 还可以通过编译开关,实现一键式关闭

四,认识Qt坐标系

以左上角为原点(0,0),X往右增加,Y向下增加:

给Qt某个控件设置位置,就要指定坐标,坐标系原点就是相对于父窗口/控件的

  • move表示把控件移动到具体位置,单位是像素点
  • x和y函数就是获得该控件相对与原点(0, 0),的横坐标和纵坐标

#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
#include<QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QPushButton* b1 = new QPushButton("按钮1", this);
    QPushButton* b2 = new QPushButton("按钮2", this);

    b1->move(300, 200); //设置按钮1的坐标
    this->move(0, 100); //这个就是设置窗口的坐标,原点为我们屏幕的左上角

    qDebug() << "按钮1的坐标为:[" << b1->x() << ", " << b1->y() << "]";
    qDebug() << "按钮2的坐标为:[" << b2->x() << ", " << b2->y() << "]";
}

Widget::~Widget()
{
    delete ui;
}

 

五,周边

5.1 命名规范

  • 类名:首字母大写,单词和单词之间的首字母大写,比如QApplication
  • 函数和变量名:首字母小写,单词和单词之间首字母大写,比如studentCount
  • Qt偏好驼峰命名法,这一点和之前的C++代码有区别,我们之前是喜欢这样的:unordered_map,priority_queue,这叫做蛇形命名法

5.2 快捷键

  • 注释:ctrl + /
  • 运行:ctrl + R
  • 编译:ctrl + B
  • 字体缩放:ctrl + 鼠标滚轮
  • 查找:ctrl + F
  • 整行移动:ctrl + shift + 上下箭头
  • 帮助文档:F1
  • 自动对齐:ctrl + i
  • 同名之间.h 和 .cpp 切换:F4
  • 生成函数声明的对应定义:alt + Enter

5.3 如何使用帮助文档

  • 可以将鼠标光标放到要查询的类名/方法名上,直接按F1
  • Qt Creator 左边侧栏中直接点击“帮助”按钮可以直接跳转
  • 第三种方式就是在开始菜单找到帮助文档,之前已经介绍过

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【搭建JavaEE】(3)前后端交互,请求响应机制,JDBC数据库连接

前后端交互 Apache Tomat B/S目前主流。 tomat包含2部分&#xff1a; apache容器 再认识servlet 抽象出的开发模式 项目创建配置 maven javaeetomcat 忽略一些不用的文件 webapp文件夹 HiServlet 这里面出现了webinfo&#xff0c;这个别删因为这个呢&#xff0c;是这这个这…

美摄科技PC端视频编辑解决方案,为企业打造专属的高效创作平台

在当今这个信息爆炸的时代&#xff0c;视频已成为不可或缺的重要内容形式&#xff0c;美摄科技推出了PC端视频编辑解决方案的私有化部署服务&#xff0c;旨在为企业提供一款量身定制的高效创作平台。 一、全面功能&#xff0c;满足企业多样化需求 美摄科技的PC端视频编辑解决…

探索图像编辑的无限可能——Adobe Photoshop全解析

文章目录 前言一、PS的历史二、PS的应用场景三、PS的功能及工具用法四、图层的概念五、调整与滤镜六、创建蒙版七、绘制形状与路径八、实战练习结语 前言 在当今数字化的世界里&#xff0c;视觉内容无处不在&#xff0c;而创建和编辑这些内容的能力已经成为许多行业的核心技能…

STM32-笔记41-RTC(实时时钟)

一、什么是RTC&#xff1f; 实时时钟的缩写是RTC(Real_Time Clock)。RTC 是集成电路&#xff0c;通常称为时钟芯片。 实时时钟是一个独立的定时器。 RTC模块拥有一组连续计数的计数器&#xff0c;在相应软件配置下&#xff0c;可提供时钟日历的功能。修改计数器的值可以重新设…

51c自动驾驶~合集46

我自己的原文哦~ https://blog.51cto.com/whaosoft/13050104 #世界模型会是L3自动驾驶的唯一解吗 三维空间占有率&#xff08;3D Occupancy&#xff09;预测的目的是预测三维空间中的每个体素是否被占有&#xff0c;如果被占有&#xff0c;则对应的体素将被标记。3D Semant…

mybatis-spring @MapperScan走读分析

接上一篇文章&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145100531&#xff0c; 本文注解分析mybatis-spring中的MapperScan注解&#xff0c;则将容易许多。 目录 MapperScan注解定义ConfigurationClassPostProcessor扫描注册beanDefinitionorg.mybatis.s…

Apache PAIMON 学习

参考&#xff1a;Apache PAIMON&#xff1a;实时数据湖技术框架及其实践 数据湖不仅仅是一个存储不同类数据的技术手段&#xff0c;更是提高数据分析效率、支持数据驱动决策、加速AI发展的基础设施。 新一代实时数据湖技术&#xff0c;Apache PAIMON兼容Apache Flink、Spark等…

SQL面试题1:连续登陆问题

引言 场景介绍&#xff1a; 许多互联网平台为了提高用户的参与度和忠诚度&#xff0c;会推出各种连续登录奖励机制。例如&#xff0c;游戏平台会给连续登录的玩家发放游戏道具、金币等奖励&#xff1b;学习类 APP 会为连续登录学习的用户提供积分&#xff0c;积分可兑换课程或…

电商系统,核心通用架构案例设计方案浅析

文章目录 一、用户系统案例设计1、用户信息的存储方案2、用户注册确保唯一3、用户数据合并方案4、用户敏感信息加密存储5、数据传输安全性6、多用户数据隔离性7、防止恶意注册8、用户好友关系存储方案9、用户登录token方案10、会员优先处理设计 二、网关系统设计1、网关的功能2…

【EI 会议征稿】第四届材料工程与应用力学国际学术会议(ICMEAAE 2025)

2025 4th International Conference on Materials Engineering and Applied Mechanics 重要信息 大会官网&#xff1a;www.icmeaae.com 大会时间&#xff1a;2025年3月7-9日 大会地点&#xff1a;中国西安 截稿时间&#xff1a;2025年1月24日23:59 接受/拒稿通知&#xf…

SQL面试题2:留存率问题

引言 场景介绍&#xff1a; 在互联网产品运营中&#xff0c;用户注册量和留存率是衡量产品吸引力和用户粘性的关键指标&#xff0c;直接影响产品的可持续发展和商业价值。通过分析这些数据&#xff0c;企业可以了解用户行为&#xff0c;优化产品策略&#xff0c;提升用户体验…

【Rust自学】11.7. 按测试的名称运行测试

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 11.7.1. 按名称运行测试的子集 如果想要选择运行的测试&#xff0c;就将测试的名称&#xff08;一个或多个&#xff09;作为cargo test的…

深入浅出 Android AES 加密解密:从理论到实战

深入浅出 Android AES 加密解密&#xff1a;从理论到实战 在现代移动应用中&#xff0c;数据安全是不可忽视的一环。无论是用户隐私保护&#xff0c;还是敏感信息的存储与传输&#xff0c;加密技术都扮演着重要角色。本文将以 AES&#xff08;Advanced Encryption Standard&am…

jupyter notebook练手项目:线性回归——学习时间与成绩的关系

线性回归——学习时间与学习成绩的关系 第1步&#xff1a;导入工具库 pandas——数据分析库&#xff0c;提供了数据结构&#xff08;如DataFrame和Series&#xff09;和数据操作方法&#xff0c;方便对数据集进行读取、清洗、转换等操作。 matplotlib——绘图库&#xff0c;p…

JVM虚拟机的组成 笼统理解 六大部分 类加载子系统 运行时数据区 执行引擎 本地接口 垃圾回收器 线程工具

目录 JVM虚拟机的组成&#xff1a;概述 JVM虚拟机的组成&#xff1a;详细解析 1. 类加载子系统 2. 运行时数据区 3. 执行引擎 4. 本地接口 5. 垃圾回收器 6. 线程管理与调试工具 概述 JVM&#xff08;Java Virtual Machine&#xff09;是一个虚拟计算机&#xff0c;执行…

单细胞组学大模型(8)--- scGenePT,scGPT和GenePT的结合,实验数据和文本数据的交融模型

–https://doi.org/10.1101/2024.10.23.619972 研究团队和单位 Theofanis Karaletsos–Head Of AI - Science at Chan Zuckerberg Initiative &#xff08;Chan Zuckerberg Initiative是扎克伯格和他妻子Chan成立的科研&教育机构&#xff09; 研究简介 研究背景&…

kafka原理和实践

Kafka是当前分布式系统中最流行的消息中间件之一&#xff0c;凭借着其高吞吐量的设计&#xff0c;在日志收集系统和消息系统的应用场景中深得开发者喜爱。本篇就聊聊Kafka相关的一些知识点。主要包括以下内容&#xff1a; Kafka简介 Kafka特点Kafka基本概念Kafka架构Kafka的几…

CSS | 实现三列布局(两边边定宽 中间自适应,自适应成比)

目录 示例1 &#xff08;中间自适应 示例2&#xff08;中间自适应 示例3&#xff08;中间自适应 示例4 &#xff08;自适应成比 示例5&#xff08;左中定宽&#xff0c;右边自适应 示例6&#xff08;中间自适应 示例7&#xff08;中间自适应 示例8&#xff08;中间定宽…

【大数据】机器学习------神经网络模型

一、神经网络模型 1. 基本概念 神经网络是一种模拟人类大脑神经元结构的计算模型&#xff0c;由多个神经元&#xff08;节点&#xff09;组成&#xff0c;这些节点按照不同层次排列&#xff0c;通常包括输入层、一个或多个隐藏层和输出层。每个神经元接收来自上一层神经元的输…

docker一张图理解

1、push 将本地的镜像上传到镜像仓库,要先登陆到镜像仓库。参数说明&#xff1a; –disable-content-trust : 忽略镜像的校验,默认开启 # 上传本地镜像myapache:v1到镜像仓库中。 docker push myapache:v1 1.2、search 从Docker Hub查找镜像。参数说明&#xff1a; –…