Qt之hello world

news2024/12/25 23:43:57

目录

图形化的方式

使用QLabel

使用编辑框

使用按钮

纯代码的方式

使用QLabel

使用编辑框

使用按钮

关于对象树

观察现象

Qt的常用知识

快捷键

使用帮助文档

Qt 窗口体系


我们最开始学习语言时,第一个接触的知识就是输出字符串 "hello world" 吧,所以在学习Qt时,也学习一下,如何实现 hello world

两种方式实现 hello world:
①通过图形化的方式,在界面上创建出一个控件,显示 hello world
②通过纯代码的方式,通过编写代码,在界面上创建控件,显示 hello world

如果你当前程序界面内容是比较固定的,此时就会以图形化的方式来构造界面
但是如果你的程序界面经常要动态变化,此时就会以代码的方式来构造界面

这两种方式,哪种方便就用哪种,而且这两种方式也可以配合使用


图形化的方式

使用QLabel

在按照上篇博客所讲的,使用 Qt Creator 创建一个Qt项目后,双击右边的 widget.ui

就出现了图形化的界面设计器,可以进行窗口界面内容的编辑了

我们可以使用左侧栏中的一个简单的部件 Label 来完成

这时拖动这个Label到中间的界面,输入 hello world 即可显示出来:

此时在右上角处,通过树形结构,显示出了当前界面上都有哪些控件

刚才往界面上拖拽了一个 QLabel 控件此时, ui 文件的 xml 中就会多出来这一段代码:

进一步的 qmake 就会在编译项目的时候,基于这个内容生成一段 C++ 代码,通过这个 C++ 代码构建出界面内容了,是自动完成的

点击三角运行后,就能显示出 hello world 了:

此时打开与该项目的同级目录的文件,里面的 ui_widget.h 就是 qmake 根据 xml 的内容,生成的代码:

打开 ui_widget.h 后,能看到自动生成的代码:


使用编辑框

QLabel只能显示一个文本,无法做更多的交互性的工作

编辑框有两种:
①单行编辑框:QLineEdit
②多行编辑框:QTextEdit

下面使用单行编辑框,同样打开 widget.ui,点击左侧栏中的 Line Edit:

也将 Line Edit 拖到窗口上,并输入 hello world 文本:

这里的 hello world 也可以通过右侧的属性编辑区进行修改,下面是属于 Line Edit 的属性

想改变也可以点击 text 后面的框,输入进行改变:

并且在运行出来的窗口中,也可以进行输入文本:


使用按钮

继续打开 widget.ui 文件,点击左侧栏中的 Push Button:

继续将 Push Button 拖动到界面上去,输入 hello world:

点击运行,出现一个可以点击的按钮:

此处是可以点击的,但是没有反应,这个按钮有一个属性 objectName,叫做 pushButton,所以下面可以通过 ui->pushButton 获取到这个对象


这里就可以简单引入 Qt 中的信号槽的概念,后面会具体讲解
本质就是给按钮的点击操作,关联上一个处理函数当用户点击的时候,就会执行这个处理函数

下面就在 widget.cpp 中的构造函数中,使用connect函数
Qt 中的 connect 是 QObject 这个类提供的静态函数,这个函数的作用就是连接 信号和槽
这里的 connect函数 和 TCP 的建立连接操作没有任何关系

ui->pushButton 就表示从 ui 文件中访问到了 pushButton
QPushButton::clicked 就表示我们点击按钮时就会自动触发这个信号
this表示指定关联到 this 的槽函数上
&Widget::handleClick表示处理点击操作的函数

由于最后一个传入的 handleClick 函数还没有实现,所以现在实现一下,先在 widget.h 中声明:

再在 widget.cpp 中定义,实现了点击按钮后,可以 hello world 和 hello qt 来回切换:
下面的 text()函数 是获取文本的函数

此时运行程序:

点击一下按钮,变为:

所以在 qmake 自动生成后,ui widget.h 中自动生成的代码里就会包含一个 pushButton 的成员变量,这个变量的名字,就是根据 objectName 的值来确定的

 在 objectName 中设置成什么值,生成的变量名就叫啥名字,就可以根据这个名字来获取到对应的控件的变量了


纯代码的方式

使用QLabel

一般通过代码来构造界面的时候,通常会把构造界面的代码放到 Widget/MainWindow 的构造函数中,构造函数在 widget.cpp 中定义 

此时就可以 new 一个 Qlabel 对象:

Qt 中,每个类都有一个对应同名的头文件,如果用不了就显示包含一下头文件即可:

出现上述报错,就包含对应的头文件,与类同名:

在创建 label 对象时,可以选择像上面的在堆上创建,也可以选择在栈上创建,但是更推荐在堆上创建,具体原因在后面的对象树章节说明

new 对象时,最好传递一个参数 this
也就是给当前这个 label 对象,指定一个 父对象 this,这里的 this 就指向的当前的构造函数所对应的对象,也就是main函数中创建的 Widget 对象

接着就需要使用 setText 方法:

可以看到 setText 方法的参数是 QString,而不是 C++ 中的 std::string,是因为 Qt 是 1991年 诞生的,而 C++ 最早的标准也是 C++98了,即1998年产生的,在1991年,C风格字符串和C++的string都不太好用,所以Qt 为了让自己的开发能变的顺畅,就自己发明了一套轮子,搞了一系列的基础类,来支持 Qt 的开发

例如:
QString、QVector、QList、QMap等等

其中 QString 内部已经对于字符编码做了处理,不会出现乱码的问题
而 std:string,就啥都没干

所以直接传入 hello world即可:

在 QString 中也提供了 C风格字符串 作为参数的构造函数
不显式构造 QString,上述代码中的 C风格字符串 也会隐式构造成 QString 对象
并且 QString 对应的头文件,已经被很多 Qt 内置的其他类给间接包含了,因此一般不需要显式包含 QString 头文件

此时运行程序,如下所示:

通过代码创建 QLabel 默认是在左上角,如果想放到其他位置也是可以的(后续会讲)


使用编辑框

同样在 widget.cpp 的构造函数中添加对象:

此时运行程序:

效果和刚刚的图形化的方式是一样的,区别就是文本的位置在左上角


使用按钮

在 widget.cpp 中编写:

初步思路是上述代码,但是由于接下来实现 handleClick 函数时,无法获取到这里的局部变量 myButton,所以将 myButton 设置为成员变量:

widget.cpp 变为:

同样能够完成和图形化的方式一样的效果

点击变为:


关于对象树

这个代码,new 了对象之后,为什么最后没有 delete 呢,不 delete 不就出现内存泄漏了吗??

结论是:上述代码,在 Qt 中不会产生内存泄露,label 对象会合适的时候被析构释放
之所以能够把对象释放掉,主要是因为把这个对象是挂到了对象树上,也就是上述代码中创建对象时传入了this指针,指明了 父对象

Qt 中也是类似网页开发的对象数(DOM),也是搞了一个对象树,也是 N 叉树,把界面上的各种元素组织起来了,使用对象树把这些内容组织起来,最主要的目的,就是为了能够在合适的时机(也就是窗口关闭的时候),把这些对象统一进行释放

所以上述代码通过 new 的方式创建对象,也就是为了把这个对象的生命周期,交给 Qt 的对象树来统一管理

如果是在栈上创建的,运行时就不会看到 hello world,因为创建对象的代码是构造函数中实现的,当执行完构造函数后,该对象就会销毁,所以不会看到这个字符串


观察现象

下面创建一个 MyLabel 类,观察不手动释放 new 的对象,是否会自动释放

主要思路就是:
创建自定义的类,自定义析构函数,在析构函数中加上日志信息,观察关闭窗口后,在结果中会不会出现打印的日志

首先创建一个 MyLabel 的头文件和源文件:

选择C++,C++ Class:

接着指定我们要创建的类名为 MyLabel,下面的 Base Class 表示父类,手动输入父类为:QLabel

此时点击完成,就成功添加到项目中了:


此时点开 mylabel.h ,可以看到 Qt Creator 不认识 QLabel

所以需要手动包含,这也算是 Qt Creator 的其中一个体验不好的地方吧:
自动生成代码,但是却不自动生成所继承的父类的头文件,需要我们手动包含

下面我们改动一下MyLabel的构造函数,变为有参的构造函数,指定父元素,从而能够使得创建的 MyLabel 对象能够加入到对象树中

在 mylabel.cpp 中也做以修改:

接着需要手动创建析构函数

在 mylabel.cpp 中实现打印时,不能使用 C++ 中的 std::cout,因为可能编码方式不匹配,所以这里使用 qDebug 来打印日志,需要包含头文件 QDebug
下面所使用的 qDebug 是一个宏,后面直接跟上需要输出的字符串即可,会自动处理编码问题

此时 widget.cpp 中,创建一个 MyLabel 对象,注意需要包含 mylabel.h 头文件:

此时运行程序,出现 hello world:

再点开输出界面,关闭这个窗口后,输出如下:

可以看到我们的代码中是没有 delete 的,而程序自动调用了析构函数,从而验证了我们上面所说的结论


小结:

①认识 QLabel 类,能够在界面上显示字符串,通过 setText 来设置的(参数是 QString)

对象树,Qt 中通过对象树,来统一的释放界面的控件对象
Qt 还是推荐使用 new 的方式在堆上创建对象, 通过对象树,统一释放对象创建对象的时候,在构造函数中,指定父对象(此时才会挂到对象树上)
如果你的对象没有挂到对象树上,就必须要记得手动释放

③通过继承自 Qt 内置的类,就可以达到对现有控件进行功能扩展效果,Qt 内置的 QLabel,没法看到销毁过程的
为了看清楚,就创建类 MyLabel,继承自 QLabel,并重写了析构函数
在析构函数中,加上日志,可以直观的观察到对象释放的过程
也可以重写控件中的任何功能,不仅仅是析构函数,从而达到功能扩展目的

乱码问题和字符集
如果使用 cout 就可能出现乱码问题,而乱码问题就是编码方式不匹配导致的
汉字不同于英文字母,汉字总计 6万 多个,并且表示同一个汉字有不同的方式,也就是字符集是不同的,不同的字符集,表示同一个汉字,所使用的数字是不相同的

目前表示汉字的字符集主要有两种方式:GBK、UTF-8(utf8)
GBK:主要在中国使用,使用 2 个字节表示一个汉字,我们使用的Windows 简体中文版,它默认的字符集就是 GBK
UTF-8:变长编码,表示一个符号,使用的字节数有变化,一般是2 - 4字节,但是在 utf8 中,一个汉字,一般是 3 个字节

⑤在 Qt 中打印日志
作为调试信息,使用 cout 固然可以,但是并不是上策 (因为cout的字符编码处理的不好,也不方便统一进行关闭)
Qt 中推荐使用 qDebug() 完成日志的打印,它可以自动进行编码处理的操作
并且使用 qDebug() 时,是可以通过编译开关统一关闭,cout则做不到这一点


Qt的常用知识

快捷键

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

使用帮助文档

方式一:光标放到要查询的类名/方法名上,直接按F1

方式二:Qt Creator 左侧边栏中直接用鼠标单击 "帮助" 按钮

方式三:Qt assistant 也是帮助文档


Qt 窗口体系

Qt 的坐标系是平面直角坐标系,也叫做笛卡尔坐标系

但是也与我们之前数学中的坐标系不同,如下所示:

①坐标系的原点 (0, 0) 就是 屏幕的左上角/窗口的左上角
②给 Qt 的某个控件,设置位置, 就需要指定坐标,对于这个控件来说,坐标系原点就是相对于父窗口/控件的

而 Widget 没有父元素,所以就是以桌面的左上角为原点设置的

所以我们就明白了,为什么上面使用纯代码的方式,创建出的按钮是在左上角的,默认情况下就是在 (0, 0)位置,也就是左上角的

运行可以看到是在左上角的:

可以使用 move函数 来设置位置,move中单位是像素:

运行程序可以看到:

也就是:

这里的像素其实我们的笔记本电脑中,显示设置-显示器分辨率中的 1920 × 1080,这两个数字的单位就是像素


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

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

相关文章

10分钟使用Strapi(无头CMS)生成基于Node.js的API接口,告别繁琐开发,保姆级教程,持续更新中。

一、什么是Strapi? Strapi 是一个开源的无头(headless) CMS,开发者可以自由选择他们喜欢的开发工具和框架,内容编辑人员使用自有的应用程序来管理和分发他们的内容。得益于插件系统,Strapi 是一个灵活的 C…

【微服务】Java 对接飞书多维表格使用详解

目录 一、前言 二、前置操作 2.1 开通企业飞书账户 2.2 确保账户具备多维表操作权限 2.3 创建一张测试用的多维表 2.4 获取飞书开放平台文档 2.5 获取Java SDK 三、应用App相关操作 3.1 创建应用过程 3.2 应用发布过程 3.3 应用添加操作权限 四、多维表应用授权操作…

国家能源集团携手海康威视研发攻克融合光谱煤质快检技术

10月24日,在国家能源集团准能集团黑岱沟露天煤矿,安装于准能选煤厂785商品煤胶带机中部的煤质快检核心设备,正在对当天装车外运的商品煤煤质进行实时检测。仅两分钟后,涵盖发热量、水分、灰分、硫分等多项指标的数据信息已传输到到…

jupyter界面修改成中文教程

在系统变量里面增加一个变量名:LANG 变量值:zh_ CN.UTF8 成功修改成为中文

修改huggingface的缓存目录以及镜像源

执行以下语句查看当前配置 huggingface-cli env默认输出应该如下 (py39-transformers) PS D:\py_project\transformers_demo> huggingface-cli envCopy-and-paste the text below in your GitHub issue.- huggingface_hub version: 0.26.1 - Platform: Windows-10-10.0.22…

Docker 镜像下载问题及解决办法

Docker 镜像下载问题及解决办法 我在杂乱的、破旧的村庄寂寞地走过漫长的雨季,将我年少的眼光从晦暗的日子里打捞出来的是一棵棵开花的树,它们以一串串卓然不俗的花擦明了我的眼睛,也洗净了我的灵魂。 引言 在使用 Docker 时,用户…

Catalan数 C++解决

输入描述 输入一个正整数n。 输出描述 输出Catalan数的前n项。 用例输入 1 0 用例输出 1 1 用例输入 2 5 用例输出 2 1 1 2 5 14 42 #include<bits/stdc.h> using namespace std; int main() {int n;cin>>n;int dp[n1]{0};dp[0]dp[1]1;for(int m2;…

使用TeamViewer远程局域网内的两台电脑

有个场景&#xff0c;有人还不知道TV可以局域网操作&#xff0c;记录一下。 主要就是修改设置&#xff0c;将取消激活改为接受 然后输入受控端的ip即可

CryoEM - 冷冻电镜 基于深度学习的 从头重构(Ab-initio Reconstruction) 开源项目 教程

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/143162494 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 来源于 CryoDragon 算法 冷冻电镜(CryoEM) 是一种成像方式,为蛋白质和…

【人工智能】——matplotlib教程

文章目录 1.matplotlib简介2.基本绘图功能2.1给图形添加辅助功能2.2在一个坐标系中绘制多个图像2.3多个坐标系显示图像 3.常见图像绘制 1.matplotlib简介 matplotlib 是一个用于创建二维图表和数据可视化的 Python 库&#xff0c;它提供了一种类似于 MATLAB 的绘图接口。matplo…

React基础使用教程

初识JSX React主要使用的就是jsx语法来编写dom&#xff0c;所以我们要先认识jsx&#xff0c;然后再开始学习两者相结合jsx其实就是在JS中编写HTML的一种写法编写jsx要注意以下几个规则&#xff1a; 定义虚拟DOM时&#xff0c;不要写引号标签中混入JS表达式时要用{}样式的类名指…

蓝桥杯模块(四)数码管动态显示

一、数码管电路图 二、电路分析 1.数码管电路分析 端口分公共端和段码&#xff0c;先用公共端控制一个数码管&#xff0c;再用段码实现显示数字。共阳数码管公共端输入高电平&#xff0c;段码输入低电平实现点亮 2.锁存器 Y7控制段码&#xff0c;Y6控制公共端 3.数码管编码基…

2024.7最新子比主题zibll7.9.2开心版源码+授权教程

授权教程&#xff1a; 1.进入宝塔搭建一个站点 绑定 api.zibll.com 域名 并上传 index.php 文件 2.设置伪静态 3.开启SSL证书&#xff0c;找一个能用的域名证书&#xff0c;将密钥(KEY)和证书(PEM格式)复制进去即可 4.在宝塔文件地址栏中输入 /etc 找到 hosts文件并打开&a…

初探Vue前端框架

文章目录 简介什么是Vue概述优势MVVM框架 Vue的特性数据驱动视图双向数据绑定指令插件 Vue的版本版本概述新版本Vue 3Vue 3新特性UI组件库UI组件库概述常用UI组件库 安装Vue安装Vue查看Vue版本 实例利用Vue命令创建Vue项目切换工作目录安装vue-cli脚手架创建Vue项目启动Vue项目…

从零开始:Python与Jupyter Notebook中的数据可视化之旅

目录 **理解数据与数据可视化的基本流程****了解Python与其他可视化工具****掌握Anaconda、Jupyter Notebook的常用操作方法****原理** 环境配置1. **安装Anaconda软件&#xff0c;创建实验环境**2. **安装Jupyter Notebook**3. **创建第一个Jupyter Notebook文本**&#xff08…

双指针法应用超级大总结

前言 前面很多题目都有采用双指针的思想解题&#xff0c;有的是最基本的双指针、有的用快慢指针、有的是滑动窗口&#xff0c;有的是降低时间复杂度&#xff0c;有的是必须采用这种思想&#xff0c;整的人头都大了&#x1f62d;&#x1f62d;&#x1f62d;。现在系统整理总结一…

Spring Boot技术中小企业设备管理系统设计与实践

6系统测试 6.1概念和意义 测试的定义&#xff1a;程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为&#xff1a; 目的&#xff1a;发现程序的错误&#xff1b; 任务&#xff1a;通过在计算机上执行程序&#xff0c;暴露程序中潜在的错误。 另一个…

Could not retrieve mirrorlist http://mirrorlist.centos.org错误解决方法

文章目录 背景解决方法 背景 今天在一台新服务器上安装nginx&#xff0c;在这个过程中需要安装相关依赖&#xff0c;在使用yum install命令时&#xff0c;发生了以下报错内容&#xff1a; Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7&archx8…

SpringMVC实战:构建高效表述层框架

文章目录 1. SpringMVC简介和体验1.1 介绍1.2 主要作用1.3 核心组件和调用流程1.4 快速体验 2. SpringMVC接收数据2.1 访问路径设置2.2 接收参数2.2.1 param和json参数比较2.2.2 param参数接收2.2.3 路径参数接收2.2.4 json参数接收 2.3 接收cookie数据2.4 接收请求头数据2.5 原…

10340 文本编辑器(vim)

经验值&#xff1a;1600 时间限制&#xff1a;1000毫秒 内存限制&#xff1a;512MB 经开区2023年信息学竞赛试题 不许抄袭&#xff0c;一旦发现&#xff0c;直接清空经验&#xff01; 题目描述 Description 李明正在学习使用文本编辑器软件 Vim。与 Word、VSCode 等常用的…