Qt6 C++ 开发指南学习记录三

三、Qt框架功能概述

3.1 Qt6框架中的模块

Qt框架中的模块分为以下两大类:

  • Qt Essentials:Qt框架的基础模块,这些模块提供了Qt在所有平台上的基本功能。在安装Qt时,这些基础模块是自动安装的,无须选择。
  • Qt Addons:Qt框架的附加模块,这些是实现一些特定功能的模块。

3.1.1 Qt基础模块

Qt框架的基础模块提供了Qt在所有平台上的基本功能,它们在所有开发平台上都可用,在Qt 6所有版本上源代码和二进制代码是兼容的。
Qt框架的基础模块

模块 功能
Qt Core 这个模块是Qt框架的核心,定义了元对象系统对标准C++进行扩展
Qt GUI 提供用于GUI设计的一些基础类,可用于窗口系统集成、事件处理、字体和文字处理等
Qt Network 提供实现TCP/IP网络通信的一些类
Qt Widgets 提供用于创建GUI的各种界面组件类
Qt D-Bus D-Bus是实现进程间通信(Inter process communication,IPC)和远程过程调用(remote procedure call,RPC)的一种通信协议,这个模块提供实现D-Bus通信协议的一些类
Qt Test 提供一些对应用程序和库进行单元测试的类
Qt QML 提供用QML编程的框架,它定义了QML和基础引擎
Qt Quick 这个模块是用于开发QML应用程序的标准库,提供创建UI的一些基本类型
Qt Quick Controls 提供一套基于Qt Quick的控件,可用于创建复杂的UI
Qt Quick Dialogs 提供通过QML使用系统对话框的功能
Qt Quick Layouts 提供用于管理界面布局的QML类型
Qt Quick Test 提供QML应用程序的单元测试框架

3.1.2 Qt附加模块

Qt附加模块是一些能够实现特定功能的模块,用户安装Qt时可以选择性地安装这些附加模块。

模块 功能
Active Qt 用于开发使用ActiveX和COM控件的Windows应用程序
Qt 3D 支持二维和三维图形渲染,用于开发近实时的仿真系统
Qt 5 Core Compatiblity 提供一些Qt 5中有而Qt 6中没有的API,这是为了兼容Qt 5
Qt Bluetooth 提供访问蓝牙硬件的功能
Qt Charts 提供用于数据显示的一些二维图表组件
Qt Concurrent 提供一些类,使我们无须使用底层的线程控制就可以编写多线程应用程序
Qt Data Visualization 提供用于三维数据可视化显示的一些类
Qt Help 提供一些在应用程序中集成帮助文档的类
Qt Image Formats 支持附加图片格式的插件,格式包括TIFF、MNG和TGA等
Qt Multimedia 提供处理多媒体内容的一些类,处理方式包括播放音频和视频,通过麦克风和摄像头录制音频和视频
Qt Network Authorization 使Qt应用程序能访问在线账号或HTTP服务,而又不暴露用户密码
Qt NFC 提供访问近场通信(near field communication,NFC)硬件的功能
Qt OpenGL 提供一些便于在应用程序中使用OpenGL的类
Qt Positioning 通过GPS或WiFi定位,为应用程序提供定位信息
Qt Print Support 提供一些用于打印控制的类
Qt Remote Objects 提供一种进程间通信技术,可以在进程间或计算机之间方便地交换信息
Qt SCXML 用于通过SCXML(有限状态机规范)文件创建状态机
Qt Sensors 提供访问传感器硬件的功能,传感器包括加速度计、陀螺仪等
Qt Serial Bus 提供访问串行工业总线(如CAN和Modbus总线)的功能
Qt Serial Port 提供访问兼容RS232引脚的串行接口的功能
Qt Shader Tools 提供用于三维图形着色的工具
Qt SQL 提供一些使用SQL操作数据库的类
Qt SVG 提供显示SVG图片文件的类
Qt UI Tools 提供一些类,可以在程序运行时加载用Qt Designer设计的UI文件以动态创建UI
Qt Virtual Keyboard 实现不同输入法的虚拟键盘
Qt Wayland Compositor 实现了Wayland协议,能创建用户定制的显示服务
Qt WebChannel 用于实现服务器端(QML或C++应用程序)与客户端(HTML/JavaScript或QML应用程序)进行P2P通信
Qt WebEngine 提供一些类和函数,通过Chromium浏览器项目实现在应用程序中嵌入显示动态网页
Qt WebSockets 提供WebSocket通信功能。WebSocket是一种Web通信协议,可实现客户端程序与远程主机的双向通信

3.2 Qt全局定义

头文件<QtGlobal>包含Qt框架中的一些全局定义,包括基本数据类型、函数和宏。一般的Qt类的头文件都会包含这个头文件,所以用户程序中无须包含这个头文件就可以使用其中的定义。

3.2.1 数据类型定义

Qt为各种常见数据类型定义了类型符号,确保在各个平台各种基本数据类型都具有统一确定的长度。
<QtGlobal>中定义的数据类型

Qt数据类型 POSIX标准等效定义 字节数
qint8 signed char 1
qint16 signed short 2
qint32 signed int 4
qint64 long long int 8
qlonglong long long int 8
quint8 unsigned char 1
quint16 unsigned short 2
quint32 unsigned int 4
quint64 unsigned long long int 8
qulonglong unsigned long long int 8
uchar unsigned char 1
ushort unsigned short 2
uint unsigned int 4
ulong unsigned long 8
qreal double 8
qsizetype ssize_t 8
qfloat16 2

qreal默认表示8字节double类型的浮点数,如果Qt使用-qreal float选项进行配置,就表示4字节float类型的浮点数。
qfloat16Qt 5.9中增加的一种类型,用于表示16位的浮点数qfloat16不是在头文件<QtGlobal>中定义的,要使用qfloat16,需要包含头文件<QFloat16>
qsizetype是在Qt 5.10中增加的一种类型,等效于POSIX标准中的ssize_t,表示有符号整数。

3.2.2 函数

头文件<QtGlobal>中包含一些常用函数的定义,这些函数多以模板类型作为输入和输出参数类型。若存在doublefloat两种类型参数的overload型函数,只列出double类型参数的函数。
<QtGlobal>中的全局函数定义:

函数原型 功能
T qAbs(const T &value) 返回变量value的绝对值
const T &qBound(const T &min, const T &value, const T &max) 返回value限定在min~max的值
T qExchange(T &obj, U &&newValue) 将obj的值用newValue替换,返回obj的旧值
int qFpClassify(double val) 返回val的分类,包括FP_NAN(非数)、FP_INFINITE(正或负的无穷大)、FP_ZERO(零)等几种类型
bool qFuzzyCompare(double p1, double p2) 若p1和p2近似相等,返回true
bool qFuzzyIsNull(double d) 若参数d约等于0,返回true
double qInf() 返回无穷大的数
bool qIsFinite(double d) 若d是一个有限的数,返回true
bool qIsInf(double d) 若d是一个无穷大的数,返回true
bool qIsNaN(double d) 若d为非数,返回true
const T &qMax(const T &value1, const T &value2) 返回value1和value2中的较大值
const T &qMin(const T &value1, const T &value2) 返回value1和value2中的较小值
qint64 qRound64(double value) 将value近似为最接近的qint64类型整数
int qRound(double value) 将value近似为最接近的int类型整数

一些基础的数学运算函数在<QtMath>头文件中定义,这些函数,如三角运算函数、弧度与角度的转换函数等。

3.2.3 宏定义

<QtGlobal>头文件中定义了很多宏:

  • QT_VERSION表示Qt版本。这个宏展开为数值形式0xMMNNPP。例如Qt版本为Qt 6.2.3, 则QT_VERSION为0x060203。
  • Q_BYTE_ORDER表示系统内存中数据的字节序。Q_BIG_ENDIAN表示大端字节序,Q_LITTLE_ENDIAN表示小端字节序。在需要判断系统字节序时可以用到这几个宏,例如:
 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN 
 ... 
 #endif
  • Q_DECL_IMPORT和Q_DECL_EXPORT分别用于在使用或设计共享库时导入或导出库的内容。
  • Q_UNUSED(name)用于声明函数中未被使用的参数。当函数的输入参数在函数对应的代码里未被使用时,需要用这个宏声明,否则会出现编译警告。
  • foreach(variable, container)用于遍历容器的内容。
  • qDebug(const char *message, …)用于在debugger窗口显示信息。在Qt Creator中,debugger窗口就是Application Output窗口。qDebug()输出数据的格式与C语言的printf()函数的类似,可以格式化输出各种数据。qDebug()一般用于调试程序时显示一些中间信息。

3.3 Qt的元对象系统

Qt中引入了元对象系统对标准C++语言进行扩展,增加了信号与槽、属性系统、动态翻译等特性,为编写GUI应用程序提供了极大的方便。

3.3.1 元对象系统概述

Qt的元对象系统的功能建立在以下三个方面:

  • QObject类是所有使用元对象系统的类的基类。
  • 必须在一个类的开头部分插入宏Q_OBJECT,这样这个类才可以使用元对象系统的特性。
  • MOC为每个QObject的子类提供必要的代码来实现元对象系统的特性。

构建项目时,MOC会读取C++源文件,当它发现类的定义里有Q_OBJECT宏时,它就会为这个类生成另一个包含元对象支持代码的C++源文件,这个生成的源文件连同类的实现文件一起被标准C++编译器编译和连接。
1、QObject类
QObject类是所有使用元对象系统的类的基类,也就是说,如果一个类的父类或上层父类是QObject,它就可以使用信号与槽、属性等特性。
QObject类与元对象系统特性相关的函数:

特性 函数 功能
元对象 QMetaObject *metaObject() 返回这个对象的元对象
元对象 QMetaObject staticMetaObject 这是类的静态变量,不是函数,存储了类的元对象
类型信息 bool inherits() 判断这个对象是不是某个类的子类的实例
动态翻译 QString tr() 类的静态函数,返回一个字符串的翻译版本
对象树 QObjectList &children() 返回子对象列表
对象树 QObject *parent() 返回父对象指针
对象树 void setParent() 设置父对象
对象树 T findChild() 按照对象名称,查找可被转换为类型T的子对象
对象树 QList findChildren() 返回符合名称和类型条件的子对象列表
信号与槽 QMetaObject::Connection connect() 设置信号与槽关联
信号与槽 bool disconnect() 解除信号与槽的关联
信号与槽 bool blockSignals() 设置是否阻止对象发射任何信号
信号与槽 bool signalsBlocked() 若返回值为 true,表示对象被阻止发射信号
属性系统 QList dynamicPropertyNames() 返回所有动态属性名称
属性系统 bool setProperty() 设置属性值,或添加动态属性
属性系统 QVariant property() 返回属性值

元对象系统的特性是通过QObject的一些函数实现的:

  1. 元对象(meta object)。每个QObject及其子类的实例都有一个元对象,这个元对象是自动创建的。静态变量staticMetaObject就是这个元对象,函数metaObject()返回这个元对象指针。
// 获取一个对象的元对象有两种方式
QPushButton *btn= new QPushButton(); 
const QMetaObject *metaPtr= btn->metaObject(); //获取元对象指针
const QMetaObject metaObj= btn->staticMetaObject; //获取元对象
  1. 类型信息。QObject的inherits()函数可以判断对象是不是从某个类继承的类的实例。
  2. 动态翻译。函数tr()用于返回一个字符串的翻译版本,在设计多语言界面的应用程序时需要用到tr()函数。
  3. 对象树(object tree)。对象树指的是表示对象间从属关系的树状结构。QObject类的parent()函数返回其父对象,children()函数返回其子对象,findChildren()函数可以返回某些子对象或所有子对象。窗口和窗口上的组件就构成对象树,窗口可以访问任何一个界面组件。对象树中的某个对象被删除时,它的子对象会被自动删除,所以,一个窗口被删除时,它上面的所有界面组件也会被自动删除。
  4. 信号与槽。通过在一个类的定义中插入宏Q_OBJECT,我们就可以使用Qt扩展的C++语言特性编程。
  5. 属性系统。在类的定义代码中可以用宏Q_PROPERTY定义属性,QObject的setProperty()函数会设置属性的值或定义动态属性;property()函数会返回属性的值。

2、QMetaObject类
每个QObject及其子类的实例都有一个自动创建的元对象,元对象是QMetaObject类型的实例。元对象存储了类的实例所属类的各种元数据,包括类信息元数据、方法元数据、属性元数据等,所以,元对象实质上是对类的描述。
QMetaObject类的主要接口函数:

分组 函数原型 功能
类的信息 char *className() 返回这个类的类名称
类的信息 QMetaType metaType() 返回这个元对象的元类型
类的信息 QMetaObject *superClass() 返回这个类的上层父类的元对象
类的信息 bool inherits(QMetaObject *metaObject) 返回true表示这个类继承自metaObject描述的类,否则返回false
类的信息 QObject newInstance(***) 创建这个类的一个实例,可以给构造函数传递最多10个参数
类信息元数据 QMetaClassInfo classInfo(int index) 返回序号为index的一条类信息的元数据,类信息是在类中用宏Q_CLASSINFO定义的一条信息
类信息元数据 int indexOfClassInfo(char *name) 返回名称为name的类信息的序号,序号可用于classInfo()函数
类信息元数据 int classInfoCount() 返回这个类的类信息条数
类信息元数据 int classInfoOffset() 返回这个类的第一条类信息的序号
构造函数元数据 int constructorCount() 返回这个类的构造函数的个数
构造函数元数据 QMetaMethod constructor(int index) 返回这个类的序号为index的构造函数的元数据
方法元数据 int indexOfConstructor(char *constructor) 返回一个构造函数的序号,constructor包括正则化之后的函数名和参数名
方法元数据 QMetaMethod method(int index) 返回序号为index的方法的元数据
方法元数据 int methodCount() 返回这个类的方法的个数,包括基类中定义的方法,方法包括一般的成员函数,还包括信号和槽
方法元数据 int methodOffset() 返回这个类的第一个方法的序号
方法元数据 int indexOfMethod(char *method) 返回名称为method的方法的序号
枚举类型元数据 QMetaEnum enumerator(int index) 返回序号为index的枚举类型的元数据
枚举类型元数据 int enumeratorCount() 返回这个类的枚举类型个数
枚举类型元数据 int enumeratorOffset() 返回这个类的第一个枚举类型的序号
枚举类型元数据 int indexOfEnumerator(char *name) 返回名称为name的枚举类型的序号
属性元数据 QMetaProperty property(int index) 返回序号为index的属性的元数据
属性元数据 int propertyCount() 返回这个类的属性的个数
属性元数据 int propertyOffset() 返回这个类的第一个属性的序号
属性元数据 int indexOfProperty(char *name) 返回名称为name的属性的序号
信号与槽 int indexOfSignal(char *signal) 返回名称为signal的信号的序号
信号与槽 int indexOfSlot(char *slot) 返回名称为slot的槽函数的序号
静态函数 bool checkConnectArgs(****) 检查信号与槽函数的参数是否兼容
静态函数 void connectSlotsByName(QObject *object) 迭代搜索object的所有子对象,将匹配的信号和槽连接起来
静态函数 bool invokeMethod(****) 运行QObject对象的某个方法,包括信号、槽或成员函数
静态函数 QByteArray normalizedSignature(char *method) 将方法method的名称和参数字符串正则化,去除多余空格。函数返回的结果可用于 checkConnectArgs()、indexOfConstructor()等函数

通过QMetaObject类的这些函数,我们可以在运行时获取一个QObject对象的类信息和各种元数据。类的元数据又分为多种类型,且有专门的类来描述。

3.3.2 运行时类型信息

通过使用QObjectQMetaObject提供的以下一些接口函数,我们可以在运行时获得一个对象的类名称以及其父类的名称,判断其是否从某个类继承而来。要实现这些功能,我们并不需要C++编译器的运行时类型信息(run-time type informationRTTI)支持。

  1. 函数 QMetaObject::className()。
// 函数可在运行时返回类名称的字符串
QPushButton *btn= new QPushButton(); 
const QMetaObject *meta= btn->metaObject(); //获取对象的元对象指针
QString str= QString(meta->className()); //str= "QPushButton"
  1. 函数QObject::inherits()。
// 函数可以判断一个对象是不是继承自某个类的实例,顶层的父类是QObject。
QPushButton *btn= new QPushButton(); 
bool result= btn->inherits("QPushButton"); //true 
result= btn->inherits("QObject"); //true 
result= btn->inherits("QWidget"); //true 
result= btn->inherits("QCheckBox"); //false

如果一个类是多重继承的,其中一个父类是QObject,那么inherits("QObject")会返回true
3. 函数QMetaObject::superClass()。

// 函数返回该元对象所描述类的父类的元对象,通过父类的元对象可以获取父类的一些元数据
QPushButton *btn= new QPushButton(); 
const QMetaObject *meta= btn->metaObject(); 
QString str1= QString(meta->className()); //str1="QPushButton" 

const QMetaObject *metaSuper= btn->metaObject()->superClass(); 
QString str2= QString(metaSuper->className()); //str2="QAbstractButton"
  1. 函数qobject_cast()。
// 个函数是头文件<QObject>中定义的一个非成员函数,对于QObject及其子类的对象,可以使用函数qobject_cast()进行动态类型转换。
// 如果自定义的类要支持函数qobject_cast(),那么自定义的类需要直接或间接继承自QObject,且在类定义中插入宏Q_OBJECT。
QObject *btn
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Agent XXX

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值