【Qt快速扫盲】QT概述_GUI程序创建_基础知识点等

目录

笔记整理于 https://www.bilibili.com/video/BV1Jp4y167R9/?p=1 等系列视频,侵权自删!

一、Qt概述

  1. 定义:Qt是一个跨平台的C++应用程序开发框架。
  2. 用途:被广泛用于开发GUI(图形化用户界面)程序,也可以用于开发非GUI程序。
  3. 注1:Qt提供了大量可调用的类库,帮助我们实现各种功能。当我们想要使用某些类库时,需要将其对应的模块加载到项目之中(个人理解:类似于C++中的include头文件操作)。
  4. 注2:Qt Creator是Qt程序的一款IDE(用VS也可以编写Qt程序)。

二、基于Qt创建GUI程序(对应P1-P12)

  1. 步骤:参考 https://www.bilibili.com/video/BV1Jp4y167R9?p=8&vd_source=777a132b6bd4e162e4a6d378080957fc 的P7
  2. 说明:(1)生成的文件中,XXX.pro基本不需要我们进行修改(如果我们要使用Qt的其他模块时,需要在该文件的第一行进行添加);(2)YY.h、YY.cpp和YY.ui三者可以视为绑定在一起的三个文件。
  3. MSVC、MinGW这些是Qt的编译套件,在创建GUI程序时可以进行选择。
  4. Qt代码使用#进行注释。
  5. Qt有三个窗口类:QWidget、QDialog和QMainWindow。
  6. 对于Qwidget而言,它是是所有窗口类的基类。它既可以内嵌到主窗口中,也可以不内嵌(通过是否给定参数this来实现)。
  7. 对于对话窗口类QDialog而言,其具有模态(使用exec函数)和非模态(使用show函数)两种显示方式。在模态显示方式下,Dialog将会阻塞程序的执行。这表现为:如果此时有多个子窗口,那么将不能进行随机切换(不能实现焦点切换),此时我们只能先关闭Dialog窗口。而在我们关闭了Dialog子窗口之后,主窗口MainWindow才能够显示出来。
  8. 对于窗口类QMainWindow而言,其不可以作为内嵌窗口,并且其还拥有额外的菜单栏、状态栏和工具栏。其中工具栏可以有多个。
  9. 【如何添加子窗口】右键点击项目名,点击其中的Add new选项,进行选择即可。
  10. 关于Qt的坐标原点:原点在窗口左上角,x轴正向右,y轴正向下。
  11. 【一个感受】 我们常做的一个操作是:在最上面include某个库,然后基于某个对象调用这个库中的某些函数!
  12. 关于Qt的内存回收机制:只有满足一定条件的被new出的对象才能被回收——①创建的对象必须是QObject类的子类(间接子类也可以);②创建出的类对象,必须要指定其父对象是谁(常用this)。
  13. Qt中的qDebug()作用相当于C++中的cout

三、基础知识点(对应P13-P28)

3.1 Qt专门数据类型

Qt是C++框架,因此支持C++所有数据类型(int、long等)。除此以外,Qt还自定义了一些数据类型。
【注1】我们只需要了解这些数据类型即可,在实际应用中没有必要使用这些数据类型。
【注2】Qt的基本数据类型定义在#include <QtGlobal>中,这个文件中也包括了很多宏(Macros)。
【注3】鼠标选中某个类,按下F2即可查看该类的源代码(类似于回调查看)!

3.2 日志输出

  1. 想在Qt中进行log输出,需要使用专门的类,其头文件名为QDebug(这对应了C中的printf、C++中的cout)
  2. 例子:qDebug() << "我很帅" << " * " << 10000;
  3. 【主要】修改完代码之后,我们应该先点击.pro文件进行重新构建,然后再点击左下角的三角形进行编译!!
  4. 如果我们想在点击Debug目录下的Debug.exe时也看到输出内容(即看到日志输出)的话,就需要修改.pro文件中的部分代码为CONFIG += c++11 console(原先只有CONFIG += c++11),此时我们在点击exe文件后,将会跳出一个终端窗口。

3.3 字符串类及其相关方法

  1. Qt中可以使用C中的char*、C++的std::string以及Qt自身的QByteArray或QString,来表示字符串类型。
  2. 对于QByteArray,我们可以使用相关函数完成字符串拼接、插入、删除等操作。例如void QByteArray::truncate(int pos)的作用即为从字节数组的pos位置将数组截断(前面部分留下,后面部分被删除)。此外,还可以完成子字符串查找和判断、遍历、查看字节数、类型转换等操作。
  3. 对于QString,其相关函数及其功能和QByteArray差不多。【注意】字符串大小写敏感即区分大小写的意思。
  4. 二者的区别包括:(1)QString可以对QByteArray进行进一步的封装(QByteArray是对char *的简单封装,而QString是对char *的深度封装。也因此,QByteArray可以直接转换为char *,而QString需要先转换为QByteArray);(2)QString可以设置字符串敏感而QByteArray不可以;(3)对于同一个字符串,QString和QByteArray计算长度得到的结果不同(QString的长度是字符个数,一个汉字算一个字符;QByteArray的长度是字符串占用的字节数,一个汉字占三个字节)。

3.4 QVariant类

  1. QVariant类中可以包括各种数据类型。在实际使用中,QVariant可以视作泛型
  2. 【注意】当我们在.h文件中声明一个方法时,可以按下alt + 回车键,从而跳转到.cpp文件中添加相关定义。该方法的测试也在.cpp文件中进行。—— 这也对应了.h和.cpp文件的功能,前者用于声明各种方法,后者用于定义各种方法的内容!
  3. 使用QVariant类不仅可以对Qt中的标准类型数据进行处理,也可以对自定义类型进行处理。这大大扩展了该类的实用性。
  4. 【注意】在使用自定义类型时,需要使用宏Q_DECLARE_METATYPE!—— 这好像在资料代码中有看到!!
  5. 【注意】按下F4,可以直接从.h文件跳转到.cpp文件。

3.5 坐标类QPoint

  1. 使用场景:移动某个窗口到某个位置。
  2. 作用:设置坐标、获取坐标、坐标值算数运算等。

3.6 直线类QLine

  1. 含义:两点确定一条直线,因此QLine其实就是一个封装了两个坐标点的类。
  2. 作用:设置两点的坐标、获取两点的坐标、获取二点中点的坐标、平移直线(平移两个点;根据调用函数的不同,返回值可能有,也可能无)、比较直线对象(比较两点的坐标是否同时相等)等

3.7 直线类QLine

  1. 作用:形容长度和宽度。
  2. 具体:设置或获取宽度和高度、交换高度和宽度、 高度和宽度的算数运算等。
  3. 【注意】设置参数时需要使用setXXX,而获取参数时直接使用XXX即可(XXX为参数名;获取时不使用getXXX)。

3.8 矩形类QRect

  1. 作用:描述一个矩形/窗口(集合了之前学的坐标类和尺寸类)。
  2. 具体:设置或获取重要点的坐标或者矩形的宽度高度等。

3.9 日期类QDate、时间类QTime和日期与时间类QDateTime

类似上面,略。
【注1】传入参数例如int month,传出参数例如int *year(即传出参数传出的是地址)。
【注2】QTime类可以设置或者获取毫秒。
【注3】我们最好可以使用QElapsedTimer类来计时(例如计算某个程序运行所需的时间),QTime类中的相关函数已经被废弃了(其实二者的函数名是一样的,只是类库名字不同而已)。
【注意】添加某个类的头文件的快捷方式:将鼠标放在该类的上方,按alt + 回车,便可以选择并添加相应的头文件了。

四、信号槽(signals & slots)(对应P29-P35)

4.1 信号与槽概述

  1. 【定义】信号槽就是一种事件处理机制。信号signal的本质就是事件,而槽slot/槽函数代表的就是事件的处理动作。我们无需关心事件捕捉以及信号发射(这两件事都是Qt框架内部实现的),而只需要定义事件的处理动作。信号槽又称观察者模式/发布-订阅模式。
  2. 【深入理解信号】 具体地,信号是由于用户对窗口或者空间进行了某些操作(例如按钮单击双击、窗口刷新、鼠标常用操作、键盘输入等),导致窗口或控件产生了某个特定事件,这时候Qt对应的窗口类会发出某个信号,以此对用户的挑选做出反应。我们可以将信号认为是对事件的描述。
  3. 【深入理解槽】 槽/槽函数其实是一类能对Qt框架中产生信号进行处理的函数。在Qt时,槽函数的所有者是某个类的实例对象。
  4. 【深入理解信号与槽的关系】 在Qt中,信号和槽函数本身都是独立的个体,二者并无关联。但有时因为有些特殊需求,需要将二者连接到一起,这可以通过调用QObject类中的connect函数来实现。该函数有四个参数,按照顺序分别是信号发出者、信号、信号接收者和事件处理动作(方法)。【注意】槽函数是由Qt框架调用的,我们只是通过connect函数将槽函数注册给Qt框架。在注册完毕之后,Qt框架就将不断帮助我们检测有无相关信号的发出(这一步不由connect函数实现,不要弄错了)。由此也可以看出,信号槽其实就是一种回调机制(函数的调用由框架来实现,不需要通过编写额外代码来实现)

4.2 标准信号槽使用【重要】

  1. 例子:实现以下功能——点击窗口上的按钮,关闭窗口(显然,按钮是信号发出者QPushBotton,而窗口是信号的接收者和处理者QWidget) 。
  2. 相关代码:
// 单击按钮发出的信号
[signal] void QAbstractButton::clicked(bool checked = false)
// 关闭窗口的槽函数
[slot] bool QWidget::close();

// 单击按钮关闭窗口(这行代码应该写在.cpp文件中)
connect(ui->closewindow, &QPsushBotton::clicked, this, &QMainWindow::close);

4.3 自定义信号槽使用【重要】

  1. 为了满足一些特定需求,我们有时需要自己去定义信号和槽函数。此时二者的连接依旧使用connect函数。
  2. 【注意】如果想要使用自定义的信号槽,那么我们必须编写新的类并且让这个类继承Qt的某些标准类。此外,还要满足以下两个条件:(1)该类必须从QObject类或其子类进行派生;(2)在定义类的头文件中加入Q_OBJECT宏。
  3. 【深入理解自定义信号】(1)信号是自定义类的成员函数,且返回值是void类型;(2)信号需要使用signals关键字进行声明,使用上类似于public;(3)信号函数只需要声明,不需要定义(即没有函数体实现);(4)不同信号之间可以发生重载(因为本质上都是函数,函数之间可以发生重载)。例如:
class Test : public QObject
{
	Q_OBJECT
signals:
	void testsignal();
	void testsignal(int a);
}
  1. 【深入理解自定义槽】(1)槽函数的返回值也是void类型;(2)槽函数也支持信号重载,且其参数与自定义信号在类型和个数上完全一致(后者发送,前者接收)。当然,也可以只取后者的一部分(相当于我只取一部分信号);(3)槽函数可以是自定义类的成员函数、全局函数、静态函数、lambda表达式(匿名函数);(4)槽函数可以使用关键字slots进行声明(Qt5中可以省略),例如public slots、private slots、protected slots(后两者只能在类内部使用);(5)和自定义信号不同,自定义槽函数是需要在相应.cpp文件中实现其函数体的。例如:
class Test : public QObject
{
// 此处不需要添加Q_OBJECT
public:
	void testSlot();
	static void testFunc();

public slots:
	void testSlot(int id);
}
  1. 【应用场景举例】—— 重要!!!
// 女朋友饿了,我请她吃饭
// class GirlFriend
// class Me

【注1】添加新的类的操作也是右键Qt项目名称,右键Add new!—— 很重要,解释了参考项目中其他文件的由来。注意在完成了这步之后,还需要在主头文件中包含这几个新.h文件,同时完成声明、例化相应类的操作。
【注2】在使用自定义信号和自定义槽函数的时候,通常需要同时添加新的按钮以及相应的槽函数。具体见视频P32!!—— 讲解了一个非常体现逻辑的例子,值得多看。

4.4 信号槽扩展

4.4.1 信号槽使用扩展

  1. 一个信号可以连接多个槽函数,发送一个信号有多个处理动作。此时,我们需要写多个connect连接,且槽函数的执行顺序与connect函数的调用顺序(书写顺序)是一致的(Qt5中是这样的;Qt4中随机)。
  2. 一个槽函数可以连接多个信号。多个不同的信号,处理动作是相通的。
  3. 信号可以连接信号。即信号接收者可以不用动作处理接收到的信号,而继续发生新的信号。—— 这其实有利于体现信号的一致性?
  4. 信号槽是可以断开的,通过调用disconnect函数即可,其参数与connect函数完全一致。

4.4.2 信号槽的两种连接方式(对应P34)

  1. Qt5和Qt4的信号连接方式不同。
  2. 注意当信号槽发生重载时,我们要么选用Qt4的连接方式,要么进行额外的信号函数指针声明(对应Qt5的连接方式)。前者在编写上更简单,但是一旦写错就很难定位(因为不会报相应的错)。因此我们仍然推荐使用后一种方式。

4.4.3 Lambda表达式

  1. Lambda表达式的本质就是一个一名函数,它在各种编程语言(C++、Java)中都可以使用,它能够提高代码效率,同时使程序更加灵活。
  2. 语法格式
[capture](params) opt -> ret {body;};
	- capture:	捕获列表
	- params:	参数列表
	- opt:		函数选项
	- ret:		返回值类型
	- body:		函数体
  1. 最简单的例子:
// 匿名函数的定义,代码执行这个匿名函数是不会被调用的
[](){
	qDebug() << "hello,我是一个lambda表达式...";
};

// 调用匿名函数
[](){
	qDebug() << "hello,我是一个lambda表达式...";
}();// 相比上面只加了一个(),这代表了参数列表(此处为空)。
  1. 【注意】据说Lambda表达式只在输出消息文本中使用,在复杂操作中基本不使用。
  2. 【注意】 弹幕:匿名函数相对于普通函数不需要出栈和入栈,效率更高。

五、定时器类QTimer(区别于时间类QTime)(P36-37)

  1. 作用:周期性地执行某些操作,或者制作一些动画效果(稚晖君?)
  2. 常用函数:setInterval、start、timeout(信号!)、setTimerType、signalShot(槽函数!)
  3. 【重要】 P37中讲解的例子或许能够帮助我们很好地理解参考项目!(这里还介绍了如何使得按钮上的文字根据点击进行相应变化!)

六、窗口类QWidget、QDialog、QMainWindow(P38-P56)

6.1 QWidget类(P38-P40)

  1. QWidget类继承于QObject类和QPaintDevice类(绘图设备类—— 感觉后续很可能会用到!!)。
  2. QWidget类是所有窗口类的父类,也是所有控件类(按钮、输入框、标签等)的基类。
  3. 我们在学习QWidget类时,主要关注其公共函数、公共槽函数以及信号三个部分的内容!
  4. 【关于公共函数】我们可以完成:设置宽度高度等几何参数、设置左上角图标和标题等操作。
  5. 【关于槽函数】我们可以完成:显示/隐藏/关闭窗口、窗口最大化/最小化/全屏显示等操作。
  6. 【关于信号】可以触发信号发射的事件:点击右键显示出菜单、图标或者标题发生变化等。
  7. 【注意】在设计界面上,我们可以直接右键点击按钮,然后点击转到槽,便可以添加与这个按钮相对应的槽函数(如clicked())!注意不要修改所给槽函数的名称。

6.2 QDialog类(P41-P50)

6.2.1 QDialog类自身(P41-P42)

  1. QDialog窗口有两种显示形式:(1)模态;(2)非模态。
  2. 同样地,我们在学习QDialog类时,主要关注其公共函数、公共槽函数以及信号三个部分的内容!
  3. 【关于公共函数】由于继承了QWidget类,所以可以使用QWidget类的公共函数。而QDialog类自身也有一些公共函数,但是很少使用。
  4. 【关于槽函数】我们可以完成:显示/隐藏/关闭窗口、窗口最大化/最小化/全屏显示等操作。
  5. 【关于信号】可以触发信号发射的事件:点击右键显示出菜单、图标或者标题发生变化等。

6.2.2 QDialog子类: QMessageBox(P43)【重要】

  1. 作用:给用户展示一些信息(包括提示信息、错误信息、询问信息等)(常见的界面提示音与这个类息息相关~)。
  2. 我们主要关注的是这个类的静态方法(about等)。

6.2.3 QDialog子类: QFileDialog(P44)【重要】

  1. 作用:打开文件或目录。(我们可以使用其来完成加载文件、选择目录等操作)
  2. 类似地,我们主要关注这个类的静态方法(getExistingDirectory等)。

6.2.4 QDialog子类: QFontDialog

作用:可以将选择的字体设置给单个或所有的窗口。关注点同上。

6.2.5 QDialog子类: QColorDialog

作用:可以将选择的颜色设置给单个或所有的窗口。同上。

6.2.4 QDialog子类: QInputDialog(P47-P48)【重要】

  1. 作用:得到能够和用户进行交互的对话框。
  2. 常用静态函数:getDouble、getInt、getItem、getMultiLineText、getText等

6.2.4 QDialog子类: QProgressDialog

  1. 作用:得到进度条窗口。
  2. 我们在学习QProgressDialog类时,主要关注其公共函数、公共槽函数以及信号三个部分的内容!

6.3 QMainWindow类(P51-P56)【重要】

QMainWindow类有两个特点:①可以包含菜单栏、工具栏、状态栏;②不能内嵌。
在这里插入图片描述

6.3.1 菜单栏

  1. 以word为例,菜单栏就是最上方的“打开”“格式”“引用”等。
  2. 常用信号:triggered

6.3.2 工具栏

  1. 工具栏可以有多个,位置可以设置(上下左右或者悬浮)。
  2. 设计界面中,点击左上角的toolbar(前提是已经添加)之后,便可以在右下角进行一些属性的设置。

6.3.3 状态栏

  1. 状态栏的位置在窗口的最下方。

6.3.4 停靠窗口(Dock Widget)

6.3.5 资源文件

  1. 定义:存储资源(图片文件、配置文件、小的音频文件)的文件??
  2. 作用:能够让我们不用每次调用文件时都使用相对路径的形式(具有换电脑就显示不出等弊端)。其原理是将首次使用的这些资源文件保存到一个存储文件中,这样之后即使我们换电脑了,该存储文件也会随着代码的编译加载而编译加载。
  3. 使用:选中项目名,点击右键Add new,选择Qt-Qt Resource进行添加。
  4. 备注:资源文件的后缀名是.qrc,它将出现在左侧栏的Resources中。在往项目中添加资源文件之前,我们首先要将各个文件放在与项目文件同级或者更深层次的目录中。放置完之后,我们还需要依次完成Add Prefix、Add Files、Copy Path等操作。

七、窗口布局

  1. 基本上我们需要制作Qt的窗口界面,都需要进行一系列的布局。 否则可能会出现控件不能显示、控件不能按照期望的大小显示、控件不能跟随窗口进行缩放等情况。
  2. 布局方式:三种——水平布局、垂直布局和网格布局,它们分别对应了设计界面中Layouts中的多种形式。
  3. 使用方式1:先拖入布局方式对应的图标,再将我们需要布局的按钮拖入图标内部(红框),这些按钮将会按照对应布局方式进行排列。
  4. 使用方式2:先拖入一个Widget窗口,然后再将各个按钮拖入Widget窗口内部,接着再进行布局。
  5. 备注1:已经设置好的布局方式,是可以在设计界面中进行修改的。
  6. 备注2:网格布局能够保证一些必要的对齐,而灵活使用弹簧可以保证一些间隙的实现。
  7. 备注3:我们可以在设计界面的右上角来确认哪些Widget没有进行布局。

X、Qwt概述

  1. Qwt是Qt的一个2D画图开发模块库,可以实现基于数据实时生成曲线图等等。
  2. 但是我们也有看到没有使用Qwt库,却也实现了曲线的实时绘制的视频。如

https://www.bilibili.com/video/BV125411U7SR/?spm_id_from=333.788.recommend_more_video.-1&vd_source=777a132b6bd4e162e4a6d378080957fc

  • 0
    点赞
  • 2
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页
评论

打赏作者

FengLu_

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值