【Qt学习笔记】(一)初识Qt
Qt学习笔记
- 1 使用Qt Creator 新建项目
- 2 项目代码解释
- 3 创建第一个 Hello World 程序
- 4 关于内存泄漏问题
- 5 Qt 中的对象树
- 6 关于 qDebug()的使用
- 7 使用其他方式创建一个 Hello World 程序(编辑框和按钮方式)
- 8 关于 Qt 中的命名规范 / 快捷键 / 查询文档
- 9 Qt 窗口坐标系
本文使用的是Qt6.2
1 使用Qt Creator 新建项目
新建项目
打开Qt Creator 界面后点击左上角的 文件 选择 new project
选择项目模板
项目模板 | 说明 |
---|---|
Application | Qt应用程序,包括普通窗体程序和QtQuick程序 |
Libary | 可以创建动态库、静态库以及Qt Quick 扩展插件、QtCreator 自身插件 |
其他项目 | 可以创建单元测试项目、Qt4设计师自定义控件、子目录项目等 |
Non-Qt-Project | 非Qt项目。可以创建纯C或C++项目 |
import Project | 导入项目。从版本控制系统管理的软件项目导入旧的项目 |
常用的是第一类,选中后,在右侧会显示出Qt应用程序的五个子模版:
- Qt Widgets Application :普通窗体模板,传统基于部件的窗体界面程序
- Qt console Application :Qt 控制台应用程序。因为Qt主要用于图形界面设计,这个控制台项目基本不用。
- Qt for Python:在Python 下用LGPL的许可来开发闭源Qt软件。
- Qt Quick Application: Qt 提供的一种高级用户界面技术,使用它可以方便快速的为移动以及嵌入式设备开发流畅美观的用户界面。QtQuick模块是开发QML应用的标准库,提供了使用QML创建用户界面所需的一切,包括可视化、交互、动画、模型、视图、粒子效果以及着色效果等。
选择了不同的项目模板,Qt Creator 就会在项目创建完毕以后生成不同的基础代码
选择项目路径
注意创建路径名称不能有中文!!!
选择构建系统
使用默认的qmake即可
Qt中的构建工具有三种可供选择,分别是: qmake、CMake、 Qbs,下面依次介绍。
- qmake: qmake是一个构建工具(build tool) ,用于自动生成makefile文件。qmake支持跨平台构建。qmake编辑的是一个后缀名为.pro的文件。
- CMake: CMake是一个跨平台的构建工具。CMake本身不是一个编译器,其实就是生成一个让编译器能读懂编译流程的文件工具。让CMake自动生成构建系统,例如Makefile和Visual Studio项目文件。CMake 是一个第三方工具,有自己的文档。
- Qbs: Qbs (Qt Build Suite: Qt构建套件)同qmake、 CMake一样都是构建工具。Qbs号称是新一代的构建工具,比qmake编译速度更快。Qbs 没有绑定Qt版本,它从项目文件的高级项目描述中生成一个正确的依赖表。而传统的MakeFile生成工具如qmake和CMake,其在生成MakeFile文件后将实际的命令交给Make工具去执行。
Qt官方声明,因市场原因,弃用Qbs。对于Qt用户来说,qmake是当前使用最广泛的构建工具,CMake其次。
填写类信息设置界面
对于基类的选择,目前有三种基类
基类 | 说明 |
---|---|
QMainWindow | 主窗口类,一般用于较为复杂的应用程序,除了中央客户区界面,还包括菜单栏、工具栏、状态栏以及多个可停靠的工具对话框等 |
QWidget | 最简单、最基本的窗体程序,里面可以放置多个控件实现程序功能. |
QDialog | 基于对话框的程序,对话框一般用于弹窗, 也可以用于主界面显示。对话框是从QWidget继承而来的,并丰富了一些能,如模态显示和返回值等 |
三者关系如下图
选择语言和翻译文件
这里的语言不是编程语言,而是例如“中文” “英文” 这种语言
由于暂时不需要考虑国际化问题,直接点击下一步即可
选择 Qt 套件
Qt套件是指Qt程序从编译链接到运行环境的全部工具和Qt类库的集合,对于MinGW版本Qt程序生成和调试,至少需要MinGW中的编译器g++ (自 动调用链接器)、g++ 配套的基础库、调试器gdb还有使用MinGW环境编译而成的Qt类库自身。默认情况下,在上面Kit Selection里选中全部套件。
选择版本控制系统
如果想把代码提交到github可以在这里选择
项目构建完成
点击左下角运行按钮,或者按CTRL+R,查看效果
2 项目代码解释
main.cpp 文件解析
QApplication 为应用程序类;代码中 QApplication a ,a 为应用程序对象,有且仅有一个;
- QApplication 管理图形用户界面应用程序的控制流和主要设置;
- QApplication是Qt的整个后台管理的命脉。它包含主事件循环,在其中来自窗口系统和其它资源的所有事件处理和调度。它也处理应用程序的初始化和结束,并且提供对话管理。
- 对于任何一个使用Qt的图形用户界面应用程序,都正好存在一个QApplication对象,而不论
这个应用程序在同一时间内是不是有0、1、 2或更多个窗口。
Widget 为刚才创建项目的时候,所选的类名
- w.show() 调用show函数显示窗口
- Widget 的父类是QWidget,函数由该父类提供
a.exec() :程序进入消息循环,等待对用户输入进行响应。这里main()把控制权转交给Qt, Qt 完
成事件处理工作,当应用程序退出的时候exec()的值就会返回。在exec() 中,Qt接受并处理用户
和系统的事件并且把它们传递给适当的窗口部件。
widget.h 文件解析
- 在 Qt 中,头文件的命名是有规律的,一般类名和头文件的命名相同。
- Q_OBJECT 本质上是一个宏,展开后是一长段代码。如果某个类想使用信号和槽机制,就需要引入这个宏。
- 图中第17行代码为构造函数,这里在后面的“对象树”中会再次提到。
- Ui::Widget *ui 和form file文件密切相关,通过该指针,可以访问UI界面中的任意控件。
widget.cpp 文件解析
widget.ui 文件解析
点击form file 中的 ui 文件,打开图形编辑界面
点击左侧的“编辑”,查看该ui界面的本体
该格式为XML格式,和HTML格式类似
Qt 中使用XML文件去描述程序的界面,进一步会结合qmake 调用相关的工具,依据XML文件生成C++代码,从而把完整的界面构造出来
.pro 文件解析
- .pro 是Qt项目的工程文件,也是qmake工具构建时的重要依据。
- .pro 类似与Makefile 文件,qmake搭配.pro文件起到的作用和Makefile是类似的
- 图中第一行代码是要引入的QT模块,后面学习一些内容的时候会修改这里
中间文件
如果编译运行Qt项目,构建过程中还会生成一些中间文件,如下图,打开资源管理器查看
打开后,返回上一级会看到多出来一个build-xxx文件夹,这个文件夹里面就是项目在运行过程中生成的一些临时文件
- 可以看到编译Qt程序,还是会用到makefile文件,只不过不需要我们手动去写,而是qmake自动生成的。
- widget.ui 由xml 生成的ui_widget.h 文件也在图中,双击打开查看
之前提到的 widget.h 里的ui指针就是该类的指针
- 点击debug 文件,可以看到最终生成的可执行程序
直接运行,效果和在Qt Creator 中运行是相同的效果。(运行失败的话,看看有没有配置环境变量)
3 创建第一个 Hello World 程序
利用 Qt 创建一个Hello World 程序有两种方式。分别是图形化的方式和纯代码的方式。
图形化方式
图形化方式比较简单,打开 ui 界面,然后找到 Label标签 拖动到编辑界面,然后输入文字即可。
运行程序,查看效果。
在 Qt Designer 的右边可以查看有哪些控件,label 实际上就是一个界面上用来显示字符串的控件
在编辑界面可以看到XML文件中多了一段代码,qmake就会在编译项目的时候,基于这个内容生成一段C++代码,构建出界面内容。
纯代码方式创建Hello World 程序
一般通过代码来构造界面的时候,通常会把构造界面的代码放到 Widget 的构造函数中
代码如下,记得包含头文件
运行查看效果
Hello World 程序创建完成。但是文字默认在左上角,通过纯代码的方式也可以修改,后面会讲。
4 关于内存泄漏问题
在这段代码中,在 new 了一个对象之后,却没有 delete ,会不会造成内存泄漏?
答案是在 Qt 中不会造成内存泄漏。此处通过 new 的方式创建对象,就是为了把该对象的生命周期交给 Qt 的对象树统一管理。代码中的 label 对象会在合适的时机被析构释放,这个合适的时机是指在窗口关闭的时候。
5 Qt 中的对象树
Qt 中的对象树,是一颗 N叉树 ,通过该树把界面上的各种元素组织起来。
比如有如下几种元素。
经过对象树组织后,就变成下图所示
使用对象树组织起来,最主要的目的,就是为了在合适的时机,也就是窗口关闭的时候,把这些对象统一释放。
QLabel *label = new QLabel(this);
代码中传入this 参数是为了将该对象挂在对象树上。通过 new 的方式在堆上建立对象,交给对象树管理。
而之前说的下面这种方式,是不推荐的
QLabel label(this);
这种在栈上创建的方式,可能存在“提前释放”的问题。运行查看效果。
窗口中没有设定好的 label 控件,因为被提前释放掉了。
6 关于 qDebug()的使用
qDebug() 的使用效果和 std::cout << std::endl 的效果一样,但是比后者好。
原因是 qDebug() 会自动处理编码方式,在 Qt 中如果用 cout 打印文字日志,可能会出现乱码,因为编码不同。
比如在析构函数中加入打印语句。
运行后,然后关闭窗口,自动调用析构函数,查看应用程序输出,会看到乱码
所以通常采用 qDebug() 的方式去打印日志。
qDebug() 还有一个优点就是可以统一打开和关闭,就能方便程序员调试。
在 .pro 文件加入这条代码即可
DEFINES += QT_NO_DEBUG_OUTPUT
需要 清除 然后重新构建才有效
7 使用其他方式创建一个 Hello World 程序(编辑框和按钮方式)
除了上面使用 label 标签的形式,还可以采用编辑框和按钮的方式。同样分为图形化界面方式和纯代码方式完成。
编辑框图形化方式
如下图所示,编辑框分为单行编辑框和多行编辑框,这里选择单行编辑框即可。拖动到编辑界面,然后输入文字。
运行查看效果。编辑框的内容运行后可以自己修改。
编辑框纯代码方式
纯代码方式和之前介绍过的大同小异。首先需要创建一个 QLineEdit 对象,然后设置文字。
运行查看效果。
按钮图形化方式
在 ui 界面找到 Push Button 然后拖动到图形化编辑界面输入文字
运行查看效果
这个按钮是可以点击的,但是点击了没有反应。如果想要点击了有反应,需要用到信号和槽机制,后面会讲。这里先简单说一下,本质就是给按钮的点击操作,关联一个处理函数,当用户点击的时候,就会执行这个处理函数。
这里需要用到 connect 函数
代码如图所示:
- 第一个参数需要访问到 ui 文件中创建的控件,表示哪个控件发出的信号,在 Qt Designer 中创建一个控件的时候,此时就会给这个控件分配一个 objectName 属性,这个属性的值,要求在界面中是唯一的。qmake 在预处理.ui文件的时候,就会根据这里的 objectname 生成对应的C++代码。这个值可以在ui界面手动修改
- 第二个参数表示发出了个什么信号,这里 clicked 表示点击,当用户点击按钮时就会发出该信号
- 第三个参数表示谁来处理该信号,将第二个参数的信号能够关联到对应的槽函数上,在此之前需要确认关联到哪个对象的槽函数,填写 this ,关联到 widget 对象的槽函数。
- 第四个参数传一个具体的处理函数,这个函数需要我们自己去写处理方式。我们的处理方式是:点击一次按钮,文本在 Hello World!和Hello Qt! 之间来回切换。代码如下:
void Widget::handClick()
{if(ui->pushButton->text() == QString("Hello World!")){ui->pushButton->setText("Hello Qt!");}else{ui->pushButton->setText("Hello World!");}
}
记得先在头文件声明该函数。声明以后,快速生成函数定义快捷键:alt + 回车
会自动在 .cpp 文件帮我们处理好一些代码
运行查看效果
点击一次按钮
文本内容改变了,再点击一次
点击一次按钮就会在两个文本内容之间来回切换,成功实现我们想要的功能。
纯代码方式实现按钮版 Hello World 程序
纯代码方式实现,首先需要我们自己 new 一个 button 对象,为了能让其他成员函数能够访问该变量,需要将该对象定义为成员变量。
具体代码如下,功能如上面所述
运行查看效果
点击后
再次点击
成功实现。
实际开发以纯代码为主还是图形化界面为主?
这两者都很重要,难分主次。如果当前程序界面,界面内容是比较固定的,此时就会以图形化界面的方式来构造界面。如果当前界面,经常要动态变化,此时就会以代码的方式来构造界面。这两种方式,哪种方便就用哪种,而且这两种方式可以配合使用。
8 关于 Qt 中的命名规范 / 快捷键 / 查询文档
命名规范
- 类名:首字母大写,单词和单词之间首字母大写,也就是大驼峰命名法。如:QPushButton
- 函数名:首字母小写,单词和单词之间首字母大写,也就是小驼峰命名法。如:setText
快捷键
- 注释: ctrl+ /
- 运行: ctrl+ R
- 编译: cttrl+ B
- 字体缩放: ctrl +鼠标滑轮
- 查找: ctrl + F
- 整行移动: ctrl+shift+ ↑/↓
- 帮助文档: F1
- 自动对齐: ctrl+ i;
- 同名之间的.h和.cpp的切换: F4
- 生成函数声明的对应定义: alt + enter
使用帮助文档
打开文档一共有三种方法
- 光标放到要查询的类名/方法名上,直接按F1
- Qt Creator左侧边栏中直接用鼠标单击"帮助"按钮
- 找到Qt Creator的安装路径,在"bin"文件夹下找到assistant.exe,双击打开;
9 Qt 窗口坐标系
坐标体系:以左上角为原点(0,0),X向右增加,Y向下增加
对于嵌套窗口,其坐标是相对于父窗口来说的。
比如图中 QPushButton 的父窗口就是 QWidget,原点就是QWidget 左上角。QWidget没有父元素,相当于父元素就是整个显示器,原点就是显示器左上角。
上面我们提到过,以纯代码的方式创建一个这样一个程序,按钮会默认在左上角,也就是原点(0,0)处,这里的位置是可以改变的。
需要用到 move 函数
把这个按钮相对于原点水平移动200像素,垂直移动300像素,效果如下
还可以设置窗口弹出时的位置。设置为弹出为显示器的原点处
查看效果,在窗口弹出后位置在显示器左上角。
以上是关于 Qt 的一些基础操作,下篇文章是关于 Qt 的信号和槽机制。
相关文章:

【Qt学习笔记】(一)初识Qt
Qt学习笔记 1 使用Qt Creator 新建项目2 项目代码解释3 创建第一个 Hello World 程序4 关于内存泄漏问题5 Qt 中的对象树6 关于 qDebug()的使用7 使用其他方式创建一个 Hello World 程序(编辑框和按钮方式)8 关于 Qt 中的命名规范…...

YIA主题如何关闭新版本升级提示?WordPress主题怎么取消升级提醒?
前两天YIA主题发布了升级到2.8版本,新增了一些功能,优化调整修复了一些功能,但是这些功能调整幅度不大,加上boke112百科使用的YIA主题已经进行了很多方面的个性化修改,所以就懒得升级了,但是每次进入WordPr…...

消息队列的应用场景
消息队列的应用场景 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题实现高性能,高可用,可伸缩和最终一致性架构使用较多的消息队列有ActiveMQ,RabbitMQ,Ze…...

Arcgis10.3安装
所需软件地址 链接:https://pan.baidu.com/s/1aAykUDjkaXjdwFjDvAR83Q?pwdbs2i 提取码:bs2i 1、安装License Manager 点击License Manager.exe,默认下一步。 安装完,点击License Server Administrator,停止服务。…...

用Python和 Cryptography库给你的文件加密解密
用Python和 Cryptography库给你的文件加密解密 用Python和 Cryptography库给你的文件加把安全锁。 先介绍与加密解密有关的几个基本概念。 加密(Encryption):加密是将明文转换为密文的过程,使得未经授权的人无法读懂。 解密&a…...

element-ui button 仿写 demo
基于上篇 button 源码分享写了一个简单 demo,在写 demo 的过程中,又发现了一个小细节,分享一下: 1、组件部分: <template><buttonclass"yss-button"click"handleClick":class"[ty…...

Maya------创建多边形工具
配合导入图像使用 Tab键可以删除一个点! 模型不能超过4边面!多切割工具进行连接! 15.maya常用命令5.创建多边形工具 反转 双显 挤出_哔哩哔哩_bilibili...

SQL分组统计条数时,不存在组类型,如何显示条数为0
首先有张表 CREATE TABLE person (id int NOT NULL AUTO_INCREMENT,name varchar(255) DEFAULT NULL,type int DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci;表里很简单三条数据: INSERT INT…...

通过日期计算星期函数(C语言版)
测试源代码: #include <stdio.h>int getDayOfWeek(int year, int month, int day) {if (month < 3) {month 12;year--;}int q day;int m month;int K year % 100;int J year / 100;int dayOfWeek (q 13 * (m 1) / 5 K K / 4 J / 4 - 2 * J) % …...

配置支持 OpenAPI 的 ASP.NET Core 应用
写在前面 Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。 本文记录如何配置基于Swagger 的 ASP.NET Core 应用程序的 OpenAPI 规范。 需要从NuGet 安装 Swashbuckle.AspNetCore 包 代码实现 var builder WebApplicati…...

前端自己整理的学习面试笔记
简介 以下是本人一年多整理的前端学习笔记,现汇总分享给大家,很多问题都是面试必问的 更多学习资源,可以点击我获取更多 1 js数据类型 原始类型: null undefined number string boolean Symbol BigInt 引用类型: 对…...

jQuery html的使用
jquery中的html方法可以获取和设置标签的html内容 var $div $("div")// 获取标签div的html内容alert($div.html())console.log($div.html()) .html: 设置标签的html内容,之前的内容会清除(只会显示 CSDN) // 设置标签的html内容&…...

锦上添花!特征选择+深度学习:mRMR-CNN-BiGRU-Attention故障识别模型!特征按重要性排序!最大相关最小冗余!
适用平台:Matlab2023版及以上 特征选择方法:"最大相关最小冗余"(Maximal Relevance and Minimal Redundancy,简称MRMR)是一种用于特征选择的方法。该方法旨在找到最相关的特征集,同时最小化特征…...

C++ QT入门2——记事本功能实现与优化(事件处理+基本控件)
C QT入门2——记事本功能优化(事件处理基本控件) 一、记事本功能优化编码乱码问题QComboBox下拉控件QString、string、char * 间的数据转化编码问题解决整合 光标行列值显示记事本打开窗口标题关闭按钮优化—弹窗提示快捷键设计 二、☆ QT事件处理事件处…...

《Lua程序设计》-- 学习10
环境(Environment) 具有动态名称的全局变量 全局变量的声明 由于Lua语言将全局变量存放在一个普通的表中,所以可以通过元表来发现访问不存在全局变量的情况。 正如前面所提到的,我们不允许值为nil的全局变量,因为值为…...

Linux内核编译-ARM
步骤一、下载源码及交叉编译器后解压 linux kernel官网 ARM GCC交叉编译器 步骤二、安装软件 sudo apt-get install ncurses-dev sudo apt-get install flex sudo apt-get install bison sudo apt install libgtk2.0-dev libglib2.0-dev libglade2-dev sudo apt install libs…...

开源编辑器:ONLYOFFICE文档又更新了!
办公软件 ONLYOFFICE文档最新版本 8.0 现已发布:PDF 表单、RTL、单变量求解、图表向导、插件界面设计等更新。 什么是 ONLYOFFICE 文档 ONLYOFFICE 文档是一套功能强大的文档编辑器,支持编辑处理文本文档、电子表格、演示文稿、可填写的表单、PDF&#…...

第3章 文件类型和目录结构
第3章 文件类型和目录结构 在这这章之前我们先学习一个前面使用过的命令 ls 查看文件ls 命令格式: [rootbogon redhat]# ls --helpUsage: ls [OPTION]... [FILE]...List information about the FILEs (the current directory by default).Sort entries alphabeti…...

前端构建变更:从 webpack 换 vite
现状 这里以一个 op (内部运营管理用)项目为例,从 webpack 构建改为 vite 构建,提高本地开发效率,顺便也加深对 webpack 、 vite 的了解。 vite 是前端构建工具,使用 一系列预配置进行rollup 打包&#x…...

记录基于Vue.js的移动端Tree树形组件
目录 一、Liquor Tree 入门 : Development Component Options 组件选项 Structure 结构 二、vue-treeselect Introduction 介绍 Getting Started 入门 Vue 树形选择器( Vue tree select )组件在搭建 Vue 的 app 中特别常用,Vue tree select 除了简单的树形结构…...

Vue中嵌入原生HTML页面的方法
在Vue中嵌入原生HTML页面通常可以通过组件或页面的方式来完成。下面将详细说明如何通过组件方式实现这个功能,并提供一个简单的代码示例。 方法说明 创建原生HTML页面:首先,你需要创建一个原生HTML页面,这个页面可以是一个独立的…...

17 # 类型检查机制:类型保护
例子: enum Type {Strong,Week }class Java {helloJava(){console.log(hello Java);} }class JavaScript {helloJavaScript(){console.log(hello JavaScript);} }function getLanguage(type: Type){let lang type Type.Strong ? new Java() : new JavaScript();…...

Vulnhub-RIPPER: 1渗透
文章目录 一、前言1、靶机ip配置2、渗透目标3、渗透概括 开始实战一、信息获取二、rips的使用三、获取密码文件四、日志审查五、提权 一、前言 由于在做靶机的时候,涉及到的渗透思路是非常的广泛,所以在写文章的时候都是挑重点来写,尽量的不饶…...

幻兽帕鲁自建服务器:可以使用香港服务器吗?
随着网络技术的发展,越来越多的游戏爱好者选择通过自建服务器来享受游戏的乐趣。幻兽帕鲁作为一款备受喜爱的游戏,也有不少玩家想要自建服务器进行游戏。而在选择服务器地点时,很多玩家会想到使用香港服务器。那么,是否可以使用香…...

Revisiting image pyramid structure for high resolution salient object detection
accv2022的技术,在我测评的数据集上确实要明显好于basnet,rembg等一众方法。 1.Introduction 使用LR数据集训练的方法通过调整输入尺寸可以在HR图像上产生不错的结果。本文主要关注仅使用LR数据集进行训练以产生高质量的HR预测。HR的有效感受野ERFs和LR…...

中移(苏州)软件技术有限公司面试问题与解答(7)—— kmalloc与vmalloc的区别与联系及使用场景
接前一篇文章:中移(苏州)软件技术有限公司面试问题与解答(0)—— 面试感悟与问题记录 本文参考以下文章: kmalloc与vmalloc如何选择 Vmalloc与kmalloc的区别 特此致谢! 本文对于中移…...

微服务-微服务Alibaba-Nacos 源码分析 (源码流程图)
客户端流程 客户端心跳与实例往服务端注册...

后端性能优化的一些总结
目录 1、背景 2、优化实现 2.1查询数据表速度慢 2.2调别人接口速度慢 2.3导入速度慢、 2.4导出速度慢的做出介绍 2.5统计功能速度慢 3、总结 1、背景 系统上线后,被用户反应系统很多功能响应时长很慢。用户页面影响速度有要求,下面针对查询数据表…...

【升级openssl1.1.1t报错libssl.so.1.1: cannot open shared object file】
升级openssl报错: openssl vesion openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory 编译安装openssl1.1.1t当执行openssl version的时候,报上述错误,将编译到的…...

CVE-2024-0352 likeshop v2.5.7文件上传漏洞分析
本次的漏洞研究基于thinkPHP开发开的一款项目..... 漏洞描述 Likeshop是Likeshop开源的一个社交商务策略的完整解决方案,开源免费版基于thinkPHP开发。Likeshop 2.5.7.20210311及之前版本存在代码问题漏洞,该漏洞源于文件server/application/api/contr…...