QT学习----知识整理(入门篇)

一、初识QT

1、序章

1.1 下载地址

官网:Try Qt | Develop Applications and Embedded Systems | Qt

或者:Index of /archive/qt(下载慢)

或者:FFmpeg中文网站 中文教程 Android 安卓 @-QT 下载

1.2 组件介绍

MSVC:VS的IDE套件

MinGW:IDE的套件(Qcreator用的这个)

UWP:Windows的通用平台

Android:安卓开发

Sources:库的源码

Qt Charts:图形处理(折线图、曲线图等)

QT Quick 3D:3D开发

Qt Virtual Keyboard:虚拟键盘

Qt WebEngine:Web开发

..............

and so on

1.3环境变量

设置这个的目的是为了生成的程序能够全局访问。

2、编程环境介绍

2.1QT的类

在使用Qcreator编程时,有帮助文档可以查找自己不太清楚的内容,下面是一些qt支持的类:

2.2程序构造

Qcreator与VS的区别部分有很多,最直观的就是VS中是解决方案,而Qcreator中有引导用的工程文件

2.2.1Qcreator

分析:

"QT +=" :模块添加

core、gui:核心模块与窗口界面模块

CONFIG += C++11:配置项目添加,支持C++11新特性

DEFINES += QT_DEPRECATED_WARNINGS:定义一个调用过的时侯函数警告的宏

SOURCES +=:自己后续新建的cpp文件会自动添加进这里

HEADERS +=:自己后续新建的头文件会自动添加进这里

FORMS +=:自己后续新建的UI文件会自动添加进这里

2.2.2VS环境

2.2.3主函数

其中QApplication是应用程序类,一个qt应用程序只能有一个

2.2.4QtWidgetsApplication

用域解析运算符访问类QtWidgetsApplication中的QtWidgetsApplication函数,并初始化列表

2.2.5QtWidgetsApplication头文件

其中nullptr是设置成顶层的意思

2.2.6资源文件

添加资源的文件,添加完的资源可在程序内调用,常见的资源为图片

二、走进QT

1、窗口类型

1.1QWidget

  • 所有窗口的基本类(父类)
  • 可以内嵌到其他窗口的内部 —— 无边框(需要给该窗口指定父窗口)
  • 可以作为独立的窗口显示 —— 有边框(不能给该窗口指定父窗口)
  • Qt中所有控件的基类

新建:

MainWindown添加widget头文件:

显示界面(有边框):

显示界面(无边框):

1.2QDialog

对话框是个很有帮助的窗口,一般用于消息提示、密码输入等

  • QWidget的子类(派生类)
  • 对话框窗口类
  • 模态和非模态两种显示方式
  • 不能内嵌

模态为使用exec(),使对话框一直执行;非模态为正常的show()显示对话框

 

模态:

叉掉该页面后:

非模态:

1.3QMainWindow

  • 主窗口类
  • 可以包含菜单栏、工具栏、状态栏
  • 不能内嵌
  • QWidget的子类(派生类)

1.4窗口的一些小技巧

隐藏:

删除:

删除这里有个问题,main函数里面的主界面不能够删除,删除后运行会失败,可以隐藏。

取消关闭功能:

首先找到父类窗口widget,Ctrl+鼠标左键点击即可跳转,然后查找保护类,里面有个关闭事件,关于事件,后面再讲,这里讲怎么使用。

在想要取消该功能的界面重写事件

事件忽略

关闭键无法使用

2、坐标体系

2.1原点

Qt的坐标原点在窗口的左上角

  • x轴向右递增
  • y轴向下递增

2.2内嵌窗口

内嵌窗口A原点坐标(20,20)是在主界面窗口中位置,内嵌窗口B原点坐标(20,20)是在内嵌窗口A窗口中位置

3、Qt中的内存回收机制

在Qt中创建对象的时候会提供一个parent对象指针(可以查看类的构造函数),下面来解释这个parent到底是干什么的。

指针类型必须为QObject指针类型,QObject是从对象树的形式组织起来的。

QWidget是能够在屏幕上显示一切组件的父类,QWidget继承自QObject。

Qt中实现内存的自动回收,需要满足以下两个条件:

①创建的对象必须是QObject类的子类(间接子类也可以)

  • QObject类是没有父类的,Qt中有很大一部分类都是从这个类派生出去的
  • Qt中使用频率很高的窗口类和控件都是QObject的直接或间接的子类
  • 其他的类可以自己查阅Qt帮助文档

②创建出的类对象,必须要指定其父对象是谁,一般情况下有两种操作方式:

  • 构造函数
  • 通过setParent()方法

4、Qt中的数据类型

4.1基础数据类型

Qt是C++框架,因此C++中所有的语法和数据类型Qt中都被支持,Qt定义的自己的数据类型定义在#include <QtGlobal>中。

4.2log输出

qDebug是qt自己专门的日志输出,使用时需要添加<QDebug>的类

4.3字符串类型

小纸条:

C ----- char *

C++ -------std::string

Qt --------QByteArray,QString

4.3.1QByteArry

可以看做是C语言中的char *的升级版本,下述具体内容可自行查找手册

  • 构造函数
  • 数据操作
  • 子字符串查找和判断
  • 遍历
  • 查看字节数
  • 类型转换
4.3.2QString
  • 构造函数
  • 数据操作
4.3.3QString与QByteArray的区别

QString是按字符计数

QByteArray是按字节计数,一个汉字3个字符

4.4QVariant

     QVariant是Qt框架中的一个非常重要的类,它提供了一种存储各种基本数据类型(如int、double、QString等)以及Qt自定义类型(如QImage、QUrl等)的通用容器。这个类的设计目的是为了方便地在需要处理不同类型数据的场合下使用,尤其是在信号-槽机制、模型-视图编程等场景中。

4.4.1标准类型

详见手册,自行查阅。

初始化三种方式:

  • 构造一个空对象,把空对象初始化

        QVariant()

        void setValue(const T & value)

  • 镜像函数

        QVariant fromValue(const T & value)

  • 带参构造

        QVariant(const QString & value)

4.4.2自定义类型

4.4.3举例

4.5位置和尺寸

4.5.1 QPoint

QPoint::QPoint(int xpos, int ypos);

4.5.2 QLine

两个QPoint确定一条QLine

QLine::QLine(const QPoint &p1, const QPoint  &p2)

4.5.3 QSize

4.5.4 QRect

QRect是QT中的矩形,可自行查阅帮助手册,后续讲QPainter的时候再讲矩形、三角、圆形等图形。图形可以理解为几个坐标构造的图形,坐标点处理更上述点、线、尺寸相同,height和width得到高度和宽度,setheight和setwidth设置高度和宽度。

4.6 日期时间

4.6.1 日期与时间的格式化
4.6.1.1 日期

d              --------------      1~31

dd            --------------       01~31

ddd          --------------       'Mon'  to  'Sun'

dddd        --------------       'Monday'  to  'Sunday'

M             --------------       1~12

MM          --------------        01~12

MMM       --------------        'Jan' to 'Dec'

MMMM    --------------        'January'  to  'December'

yy            ---------------       00~99

yyyy        ---------------       0000 ~ 9999

举例说明:

格式:2024-05-13

代码编写:QString date = d.toString("yyyy-MM-dd");或者QString date = d.toString("yyyy-MM-d");

注意大小写,大小写要区分!!!

4.6.1.2 时间

时:

h              ---------------        0~23或1~12 AM/PM

hh            ---------------        00~23或01~12 AM/PM

H              ---------------       0~23

HH           ---------------       00~23

分:

m             ---------------       0~59

mm          ---------------       00~59

秒:

s               --------------        0~59

ss            ---------------        00~59

毫秒:

zzz          ---------------        000~999

上午或下午:

AP or A   ---------------         AM/PM   汉显

ap  or  a  ---------------         am/pm   汉显

举例:

4.6.2 QDate

这里面用的最多的是获取当前日期,其余的可以自行根据需求查阅帮助手册。

4.6.3 QTime

常用的QTime为当前时间currenttime和运行时间统计elapsed

4.6.4 QDateTime

常用函数:

例子:

5、信号与槽

信号与槽机制为QT特色,需要完全理解,而且不拘于形式,需要理解原理,这对以后学习很有帮助。可以理解为,信号发出者,发出什么信号,该信号接收者,接收信号后有什么动作,QT中信号与槽用connect函数连接。下面详细讲讲信号与槽:

5.1 信号的本质

信号的本质就是事件,如按钮、键盘等输入。

QT中信号传递给使用者的形式:

① 对哪个窗口进行操作,哪个窗口就能捕捉到这些被触发的事件

② 触发一个事件,就可以得到QT框架给发出的某个特定信号

③ 信号的呈现形式就是函数

在Qt中信号的发出者是某个实例化的类对象,对象内部可以进行相关事件的检测。

5.2 槽的本质

收到信号后的处理动作,本质是一类特殊功能的函数。

举例:

跟好兄弟出去旅游,好兄弟说:“我走累了”,于是我带他去打游戏。

分析:

好兄弟----发送信号的对象,信号内容:我走累了

我-----接收信号的对象,并且处理掉这个信号,处理动作:带他去打游戏 

5.3 信号与槽的关系

使用Object类中的connect函数进行连接

connect(信号产生对象,信号,信号接收者,动作或者信号)

举例:

这里要注意继承关系,如果槽函数不写在slot里面,需要写到public中,mainwindow才能够访问到。

5.4 标准的信号槽使用

5.4.1 标准信号/槽

查询帮助文档,一般类中对应的有信号与槽的函数,如QWidget中有Public Slots与Signal。

有的类没有直接写信号与槽,但是它的父类有,如QPushButton中没有signals,但是它的父类QAbstractButton中有,它继承使用。

5.4.2 使用

5.4.3 Lambda表达式

这里使用了Lambda表达式,简单讲解下这个表达式。

这两个表达是相同的,但是用Lambda表达式更方便点,用直接槽函数的方式更利于理解一点。

推荐使用Lamda表达式,性能优化,如果是大项目,代码量大的,性能足够的情况下,推荐使用自定义槽函数。

Lamda表达式就是一个匿名函数,语法格式如下:

[capture](params) opt -> ret{body;};

        ---capture : 捕获列表

        ---params : 参数列表

        ---opt       :函数选项

        ---ret        : 返回值类型

        ---body    : 函数体

//代码示例->匿名函数的调用

int ret = [](int a) -> int

{

        return a+1;

} (100);

其中,(int a)是形参,-> int可省略,(100)为命名、实参。

关于Lambda表达式的细节介绍:

1、捕获列表:捕获一定范围内的变量

  • []                   -----     不捕捉任何变量
  • [&]                -----      捕获外部作用域中的所有变量,并作为引用在函数体内使用(按引用捕获)
  • [=]                -----      捕获外部作用域中的所有变量,并作为副本在函数体内使用(按值捕获),拷贝副本在匿名函数体内部是只读的。
  • [=, &foo]       -----      按值捕获外部作用域中所有变量,并按照引用捕获外部变量foo。
  • [bar]             -----      按值捕获bar变量,同时不捕获其他变量,多个变量用“,”隔开即可
  • [&bar]           -----      按值捕获bar变量,同时不捕获其他变量,多个变量用“,”隔开即可
  • [this]             -----      捕获当前类中的this指针
    • 让Lambda表达式拥有和当前类成员函数同样的访问权限
    • 如果已经使用了&或者=,默认添加此选项

2、参数列表:和普通函数的参数列表一样

3、opt选项 --> 可以省略

  • mutable:     可以修改按值传递进来的拷贝(能修改拷贝,不是值本身)
  • exception:  指定函数抛出异常,如抛出整数类型可以使用throw()

4、返回值类型:

  • 标识函数返回值的类型,当返回值为void,或者函数体中有一处return的地方(此时编译器可以自动推判出返回值类型)时,这部分可以省略

5、函数体:

  • 函数的实现,这部分不能省略,但函数体可以为空
5.4.4 自定义信号槽使用

如果想要使用自定义的信号槽,首先要编写新的类并且让其继承Qt的某些标准类,我们自己编写的类想要在Qt中使用信号槽机制,那么必须要满足如下条件:

  • 这个类必须从QObject类或者是其子类进行派生
  • 在定义类的头文件中加入Q_OBJECT宏

5.4.4.1 自定义信号

要求:

1、信号是类的成员函数

2、返回值是void类型

3、信号的名字可以根据实际情况进行指定

4、参数可以随意指定,信号也支持重载

5、信号需要使用signals关键字进行声明,使用方法类似于public等关键字

6、信号函数只需要声明,不需要定义(没有函数体实现)

7、在程序中发送自定义信号:发送信号的本质就是调用信号函数

  • 惯性在信号函数前加关键字:emit
  • emit只是显示的声明一下信号要被发送,没有特殊含义
  • 底层emit == #define emit
5.4.4.2 自定义槽

1、返回值是void类型

2、槽也是函数,因此也支持重载

  • 槽函数的参数个数<=信号函数的
  • 槽函数的参数类型必须是信号函数中有的

3、Qt中槽函数的类型:

  • 类的成员函数
  • 全局函数
  • 静态函数
  • lambda表达式(匿名函数)

4、槽函数可以使用关键字进行声明:slots(Qt5中slots可以省略不写)

  • public slots
  • private slots
  • protected slots
5.4.5 信号槽拓展
5.4.5.1 信号槽使用拓展

1、一个信号可以连接多个槽函数,发送一个信号有多个处理动作

  • 需要写多个connect连接
  • 槽函数的执行顺序是随机的,和connect函数的调用顺序没有关系(补充:Qt4随机,Qt5槽调用顺序和信号发射顺序相同)
  • 信号接收者可以是一个对象。也可以是多个对象

2、一个槽函数可以连接多个信号,多个不同信号,处理动作是相同的

  • 写多个connect就可以

3、信号可以连接信号

        信号接收者接收信号后,可以发送一个新的信号作为槽函数

4、信号槽可以断开

        

5.4.5.2 信号槽的连接方式

Qt5连接方式:

connect(const QObject *sender, &QObject::signal, const QObject *receiver, &QObject::method);

Qt4连接方式:

connect(const QObject *sender, SIGNAL(型号函数名(参数1,参数2...)), const QObject *receiver, SLOT(槽函数名(参数1,参数2....)));

5.4.5.3 Lambda表达式

详见5.4.3

5.4.5.4 自定义槽函数与lambda表达式的优缺点

1、自定义槽函数

优点:

  • 可读性强:自定义槽函数具有明确的名称和功能,使得代码更加清晰易懂
  • 灵活性高:可以在槽函数中使用复杂的逻辑和功能,使其更适合处理复杂的情况
  • 易于维护:如果需要更改逻辑功能,只需要修改一处代码即可。

缺点:

  • 编写复杂:相比于lambda表达式,自定义槽函数的编写过程更复杂
  • 降低性能:相比于lambda表达式,自定义槽函数可能会导致一些额外的开销

2、Lambda表达式

优点:

  • 简洁明了:Lambda表达式可以在一行代码中定义一个功能,使得代码更加简洁
  • 即用即写:Lambda表达式可以在信号与事件处理中直接使用,不需要提前定义
  • 性能优化:Lambda表达式通常比自定义槽函数具有更好的性能

缺点:

  • 可读性差:对于不熟悉lambda表达式的人来说,可能会觉得其代码难以理解
  • 功能受限:lambda表达式的功能相对自定义槽函数来说更为有限
  • 难以调适:lambda表达式可能会使调试过程变得更加困难,因为它们通常包含在一个大的表达式或函数中

综上所述:

复杂的逻辑和功能,推荐自定义槽函数;

简洁高效性能高,推荐lambda表达式。

6、定时器QTimer

定时器QTimer在实际中使用很多,需要完全吃透。数据实时传输,一般采用QTimer定时来接收信号。

简单的来讲,用的最多的使用步骤就是:

  • 构造QTimer函数
  • 对象start开始工作,这里确定工作周期,start(1000)为1000ms周期
  • 获取start开始周期结束的timeout信号,写对应的槽函数

精度可以注意一下,其他的自行查阅帮助手册。

Qt::PreciseTimer               -------------        精确的精度,毫秒级

Qt::coarseTimer                -------------         粗糙的精度,和1毫秒的误差在5%的范围内,默认精度  

Qt::VeryCoarseTimer        -------------         非常粗糙的精度,精度在1秒左右

举例说明:

结果三秒刷新一次当前时间,无误。

7、资源文件

添加资源文件

添加资源

为了方便可以修改文件名字

8、QWidget

大致讲讲窗口的一些属性。

一些常用的界面修改:

8.1 图标与标题

8.2 窗口尺寸

8.3 鼠标右键事件

剩下的自己对着帮助手册摸索!

9、QMainWindow

补充下比QWidget多的工具栏,其实QMainWindow作为QWidget的派生类,在QWidget上也可以添加工具栏之类的。

在QDesigner里面,新建动作,拖拽到状态栏

主程序添加动作触发的连接。

其他的搜索框之类的,可以自己参考帮助手册摸索下。

10、QDialog

对应关系:

11、QDialog派生类

QDialog的派生类可以自己定义,也可以用已定义的,常见的有:QColorDialog、QErrorMessage、QFileDialog、QFontDialog、QInputDialog、QMessageBox、QProgressDialog、QWizard等。

11.1 QMessageBox

11.1.1 about

简单提示框,图片和主界面图标一致

11.1.2 critical

错误提示框

11.1.3 question

询问提示框,有返回,返回有Yes、No、Save、Cancel、OK、Open等

11.1.4 information

消息框

11.1.5 warning

警告框

11.2 QFileDialog

  • getExistingDirectory:得到一个存在的本地目录,返回值是目录绝对路径
  • getOpenFileName:得到一个文件,返回文件路径
  • getOpenFileNames:得到多个文件,返回这些文件的文件路径
  • getSaveFileName:得到一个路径,写文件的时候用

parent:当前对话框窗口的父对象也就是父窗口

caption:当前对话框窗口的标题

dir:当前对话框窗口打开的默认目录

options:当前对话框窗口的一些可选项,枚举类型,一般不需要进行设置,使用默认值即可

filter:过滤器,在对话框中只显示满足条件的文件,可以指定多个过滤器,使用“;;”分隔

        样式举例:

                Images(*.png*.jpg)

                Images(*.png*.jpg);;Text files(*.txt)

selectedFilter:如果指定了多个过滤器,通过该参数指定默认使用哪一个,不指定默认使用第一个过滤器

11.3 QFontDialog

字体对话框

11.3.1 QFont ---- 字体类

QFont::QFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false)

const QString &family:“微软”“雅黑”等字体名称

int pointSize:初始值,默认值“-1”对应为字号大小“12”

int weight:加粗初始值,默认值“-1”,不加粗,取值0~99

Qt自己的粗细枚举值:

其中常用的为Thin特细,Normal正常,Bold正常加粗

11.3.2 QFontDialog类的静态API

11.3.3 窗口字体的设置

//QWidget类

//得到当前窗口使用的字体

const QWidget :: QFont & font() const;

//给当前窗口设置字体,只对当前窗口类生效

void QWidget :: setFont(const QFont &);

//QApplication类

//得到当前应用程序对象使用的字体

[static]QFont QApplication :: font();

//给当前应用程序对象设置字体,作用于当前应用程序的所有窗口

[static]void QApplication :: setFont(const QFont &font, const char *className = nullptr);

11.3.4 举例

11.4 QColorDialog

11.4.1 颜色类QColor

主要是三基色加上透明度,经常看见的(r, g, b, a)指的就是红色red(0~255)、绿色green(0~255)、蓝色blue(0~255)、透明度alpha(0~255)

11.4.2 QColorDialog类的静态API

11.4.3 举例

11.5 QProgressDialog

进度对话框,带进度条

labeText:对话框中显示的提示信息

cancelButtonText:取消按钮上显示的文本信息

minimum:进度条最小值

maximum:进度条最大值

parent:当前窗口的父对象

f:当前进度窗口的flag属性,使用默认属性即可,无需设置

注意:需创建界面对象,需创建QTimer刷新进度条

                Qt::NonModal             ------------      非模态

                Qt::WindowModal       ------------      模态,阻塞父窗口

                Qt::ApplicationModal   -----------       模态,阻塞应用程序中的所有窗口

举例:

11.6 InputDialog

这个用来写密码简单点,不用多加判断

三、总结

本篇结束,还有很多细节没有讲到,这个需要大家在日常编程中自己去发掘,记得查看帮助手册即可,qt的帮助手册是真的有帮助,哈哈。后面再出进阶篇,主要是线程、通信、绘画、OpenGL、OpenCV、FFMpeg等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值