2.1 Qt6框架中的模块
Qt框架中的模块可以分为两大类:
- Qt Essentials:Qt框架的基础模块,提供了Qt在所有平台上的基本功能。
- Qt Addons:Qt框架的附加模块,实现一些特定功能的模块。
2.1.1 Qt基础模块
模块 | 功能 |
Qt Core | Qt框架的核心,定义了元对象系统对标准C++进行扩展 |
Qt GUI | 提供GUI设计的一些基础类 |
Qt Network | 提供实现TCP/IP网络通信的一些类 |
Qt Widgets | 提供创建GUI的各种窗口组件类 |
Qt D-Bus | 提供实现D-Bus通信协议的一些类,D-Bus是实现进程间通信(inter process communication,IPC)和远程过程调用(remote procedure call,RPC)的一种通信协议 |
Qt Test | 提供对应用程序和库进行单元测试的一些类 |
Qt QML | 提供用QML编程的框架,定义了QML和基础引擎 |
Qt Quick | 用于开发QML应用程序的标准库,提供创建UI的一些基本类型 |
Qt Quick Controls | 提供一套基于Qt Quick的控件,用于创建复杂的UI |
Qt Quick Dialogs | 提供通过QML使用系统对话框的功能 |
Qt Quick Layout | 提供用于管理界面布局的QML类型 |
Qt Quick Test | 提供QML应用程序的单元测试框架 |
Qt Core模块是Qt框架的核心,其他模块都依赖此模块,Qt GUI模块提供用于开发GUI应用程序的必要的类。在创建GUI项目时,qmake/CMake项目配置文件中会自动加入模块支持/导入、链接语句。
QT += core gui
find_package(Qt6 COMPONENTS Widgets REQUIRED) #查找Qt6,导入指定块
target_link_libraries(项目名 PRIVATE Qt6::Widgets)
2.1.2 Qt附加模块
模块 | 功能 |
Active Qt | 用于开发使用ActiveX和COM控件的Windows应用程序 |
Qt 3D | 支持二维和三维图形渲染,用于开发近实时的仿真系统 |
Qt 5 Core Compatibility | 提供Qt5中有而Qt6中没有的API,为了兼容Qt5 |
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 | 提供访问串行工业总线的功能 |
Qt Serial Port | 提供访问兼容RS232引脚的串行接口的功能 |
Qt Shader Tools | 提供用于三维图形着色的工具 |
Qt SQL | 提供使用SQL操作数据库的一些类 |
Qt SVG | 提供显示SVG图片文件的类 |
Qt UI Tools | 提供可以在程序运行时加载用Qt Dsigner设计的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通信协议,可实现客户端与远程主机的双向通信 |
2.2 Qt全局定义
头文件<QtGlobal>包含Qt框架中的一些全局定义,包括基本数据类型、函数和宏。一般的Qt类的头文件都会包含这个头文件,所以用户程序中无序包含这个头文件就可以使用其中的定义。
2.2.1 基本数据类型
为了确保在各个平台上各种基本数据类型都有统一的长度,Qt为各种常见基本数据类型定义了类型别名
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 |
qunit32 | unsigned int | 4 |
qunit64 | usigned long long int | 8 |
qulonglong | usigned 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 | float | 2 |
qreal默认表示8字节double类型的浮点数,若Qt使用-qreal float选项进行配置,就表示4字节float类型的浮点数。
qfloat16是Qt5.9中增加的一种类型,用于表示4字节float类型的浮点数。qfloat16不是在头文件<QtGlobal>中定义的,而是在头文件<QFloat16>。
qsizetype是在Qt5.10中增加的一种类型,表示有符号整数。
2.2.2 函数
template <typename T>
函数原型 | 功能 |
| 返回变量value的绝对值 |
| 返回value限定在min~max的值 |
| 将obj的值用newValue替换,返回obj的旧值 |
| 返回val的分类,包括FP_NAN(非数)、FP_INFINITE(正或负的无穷大)、FP_ZERO(零)等几种类型 |
| 若p1和p2近似相等,返回true |
| 若参数d约等于0,返回true |
| 返回无穷大的数 |
| 若d是一个有限的数,返回true |
| 若d是一个无穷大的数,返回true |
| 若d为非数,返回true |
| 返回value1和value2中的较大值 |
| 返回value1和value2中的较小值 |
| 将value近似为最接近的qint64类型整数 |
| 将value近似为最接近的int类型整数 |
还有一些基础的数学运算在<QtMath>头文件中定义。
2.2.3 宏定义
- QT_VERSION表示Qt版本,宏展开为0xMMNNPP。例如Qt版本为Qt6.2.3,则QT_VERSION宏展开为0x060203。
- Q_BYTE_ORDER表示系统内存中数据的字节序;Q_BUG_ENDIAN表示大端字节序;Q_LITTLE_ENDIAN表示小端字节序。
- Q_DECL_IMPORT和Q_DECL_EXPORT分别表示在使用或设计共享库时导入或导出库的内容。
- Q_UNUSED(parameter)用于声明函数中未被使用的参数,避免编译警告。
- foreach(variable,container)用于遍历容器的内容。
- qDebug(const char *message,...)用于在debugger窗口显示信息。在Qt Creator中,debugger窗口就是Application Output窗口。qDebug()与C语言的printf()函数的类似,可以格式化输出。
2.3 Qt的元对象系统
Qt中引入了元对象系统对标准C++语言进行扩展,增加了信号与槽、属性系统、动态翻译等特性,为编写GUI应用程序提供了极大的方便。
2.3.1 元对象概述
Qt的元对象系统的功能建立在以下3个方面
- QObject类是所有使用元对象的类的基类。
- 在一个类中插入宏Q_OBJECT,该类就可以使用元对象系统的特性。
- MOC为每个QObject的子类提供必要的代码来实现元对象系统的特性。
构建项目时,MOC会读取C++头文件,当它发现类的声明中有Q_OBJECT宏时,它就会为该类生成另一个包含元对象系统支持支持的C++源文件,生成的源文件与类的实现源文件一起被标准C++编译和链接。
QObject类
QObject类与元对象系统特性相关的一些接口函数:
特性 | 成员函数原型/静态数据成员 | 功能 |
元对象 |
| 返回对象的元对象指针 |
| 元对象 | |
类型信息 |
| 判断对象是否为类className的子类 |
动态翻译 |
| 返回字符串sourceText的翻译版本 |
对象树 |
| 返回子对象列表 |
| 返回父对象指针 | |
| 设置父对象 | |
| 返回可被转换为类型T且对象名为name的子对象 | |
| 返回可被转换为类型T且对象名为name的子对象列表 | |
| 返回对象名为name的子对象列表 | |
| 返回可被转换为类型T且正则化名为name的子对象列表 | |
信号与槽 |
| 设置信号与槽的关联 |
| 解除信号与槽的关联 | |
| 设置是否阻止对象发射信号 | |
| 返回对象是否被阻止发射信号 | |
属性系统 |
| 返回对象的动态属性列表 |
| 设置属性name的值为value,或定义动态属性 | |
| 返回属性name的属性值 |
(1)元对象
每个QObject及其子类的对象都有一个自动创建的元对象,即静态数据成员staticMetaObject。成员函数metaObject()返回对象的元对象。获取一个对象的元对象有两种方式:
const QmetaObject *metaPtr=<objcet name>->metaObject();
const QmetaObject *metaObj=<objcet name>->staticMetaObject;
(2)类型信息
成员函数inherits()可以判断对象是否为指定类的子类。
(3)动态翻译
成员函数tr()用于返回指定字符串的翻译版本,在设计多语言界面的应用程序时需要用到tr()函数。
(4)对象树
对象树:表示对象间从属关系的树状结构。右侧对象检查器就可显示对象树。
成员函数children()返回子对象列表,parent()返回父对象指针,findChildren()可以返回子对象或子对象列表
(5)信号与槽
可以在类中signals部分定义信号,在private|public slots部分定义槽函数。
(6)属性系统
可以在类中用宏Q_PROPERTY定义属性。成员函数setProperty()会设置指定属性的值,或定义动态属性,property()会返回指定属性的属性值。
QMetaObject类
元对象的类型为QMetaObject类。元对象存储了对应对象所属类的各种元数据,包括类信息元数据、方法元数据、属性元数据等。
QMetaObject类的主要接口函数:
分组 | 成员函数原型 | 功能 |
类的信息 |
| 返回类名 |
| 返回元对象的元类型 | |
| 返回类的直接父类的元对象 | |
| 判断类是否为元对象metaObject的类的子类 | |
| 创建类的对象,可以给构造函数传递最多10个参数 | |
类信息元 |
| 返回序号为index的一条类信息元数据,类信息是在类中用宏Q_CLASSINFO定义的一条信息 |
| 返回名为name的类信息的序号 | |
| 返回类的类信息条数 | |
| 返回类的第一条类信息的序号 | |
构造函数元数据 |
| 返回类的指定序号index的构造函数元数据 |
| 返回类的正则化名为constructor的构造函数的序号 | |
| 返回类的构造函数个数 | |
方法元数据 |
| 返回类的序号为index的成员函数的方法元数据 |
| 返回类的成员函数method的序号 | |
| 返回类的成员函数个数 | |
| 返回类的第一个成员函数的序号 | |
枚举类型元数据 |
| 返回序号为index的枚举类型元数据 |
| 返回枚举类型name的序号 | |
| 返回类的枚举类型个数 | |
| 返回类的第一个枚举类型的序号 | |
属性元数据 |
| 返回序号为index的属性的元数据 |
| 返回属性name的序号 | |
| 返回类的属性个数 | |
| 返回类的第一个属性的序号 | |
信号与槽 |
| 返回信号signal的序号 |
| 返回槽函数slot的序号 | |
静态成员函数 |
| 判断信号与槽函数的参数是否兼容 |
| 迭代搜索object的所有子对象,将匹配的信号与槽关联 | |
| 执行QObject对象obj的成员函数member | |
| 返回成员函数method的正则化名。 |
2.3.2 运行时类型信息
(1)函数QMetaObject::className()。这个函数返回类名。
(2)函数QObject::inherits()。这个函数判断对象是否为指定类的子类。
(3)函数QMetaObject::superClass()。这个函数返回类的直接父类的元对象。
(4)函数qobject_cast<type>()。这个函数将指定对象转换为指定子类型type。
2.3.3 属性系统
属性定义
使用宏Q_PROPERTY定义属性。
Q_PROPERTY(<type> <name>
(READ <getFunction> [WRITE <setFunction>]|
MEMBER <memberName> [READ <getFunction>] [WRITE <setFunction>])
[RESET <resetFunction>]
[NOTIFY <notifySignal>]
[REVISION <int> | REVISION(<int>[,<int>])]
[DESIGNABLE <bool>]
[SCRIPTABLE <bool>]
[USER <bool>]
[BINDABLE <bindableProperty>]
[CONSTANT]
[FINAL]
[REQUIRED])
宏Q_PROPERTY定义一个值类型为type,名称为name的属性。
READ:指定一个读取属性值的函数,没有MEMBER关键字时必须设置。
WRITE;指定一个写入属性值的函数。
MEMBER;指定一个数据成员与属性关联,使之成为可读可写的属性。
RESET:指定一个设置属性默认值的函数。
NOTIFY:指定一个信号,当属性值变化时发射此信号。
DESIGNABLE:表示属性是否在Qt Designer的属性编辑器里可见,默认值为true。
USER:表示属性是否可编辑,默认值为false。
CONSTANT:表示属性值为常数,不能有WRITE和NOTIFY关键字。
FINAL:表示属性不能被子类重载。
属性使用
在Qt类库中,很多基于QObject的子类都定义了属性,特别是基于QWidget的界面组件类。Qt Designer的属性编辑器显示了一个界面组件的各种属性,可以在进行可视化UI设计时修改组件的属性值。可读的属性通常有一个用于读取属性值的函数,函数名一般与属性名相同;可写的属性通常有一个用于设置属性值的函数。函数名一般为"setName"。
QObject类提供了两个函数直接通过属性名来访问属性。其中QObject::property()函数读取属性值,QObject::setProperty()函数设置属性值。
QMetaObject类提供了元对象的类的属性元数据。属性元数据类为QMetaProperty,它有各种函数可以返回属性的一些特性:
QVariant::Type type() const
const char *typeName() const
const char *name()const
bool isReadable() const
bool isWritable() const
bool isResettable() const
bool hasNotifySignal() const
bool isDesignable() const
bool isUser() const
bool isConstant() const
bool isFinal() const
动态属性
函数QObject::setProperty()设置属性值时,若属性不存在,则为对象定义一个新的属性,成为动态属性。动态属性时针对对象定义的,所以只能使用函数QObject::property()返回动态属性的属性值。
附加的类信息
使用宏Q_CLASSINFO定义类信息。
Q_CLASSINFO(name,value)
QMetaObject类提供了元对象的类信息元数据。类信息元数据类为QMetaClassInfo类,它只有两个函数:
const char *name() const
const char *value() const
2.3.4 信号与槽
connect()函数
函数connect()有一种成员函数形式,还有多种静态成员函数形式。一般使用静态成员函数形式。
静态成员函数QObject::connect()有多种参数形式:
(1)
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection);
用法:
connect(sender,SIGNAL(signal(signal parameters)),receiver,SLOT(slot(slot parameters)));
使用了宏SIGNAL()和SLOT()指定信号和槽函数,若信号和槽函数有参数,还需要注明参数类型。
(2)
static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection);
- 信号与槽函数都唯一时、信号重载,槽函数唯一时的用法:
connect(sender,&senderClass::signal,receiver,&receiverClass::slot)
信号重载,槽函数唯一时,将会根据槽函数参数个数选择相应的信号进行关联。
- 信号与槽函数都重载时的用法:
connect(sender,&senderClass::signal,receiver,qOverload<type>(&receiverClass::slot))
模版函数qOverload()的作用是根据指定参数类型type明确关联的槽函数。
connect()函数的形参最后都有一个参数type,它是枚举类型Qt::ConnectionType,默认值为Qt::AutoConnection。枚举类型Qt::ConnectionType表示信号与槽的关联方式。
- Qt::AutoConnection:若接收者与发射者在同一个线程中,就使用Qt::DirectConnection方式,否则使用Qt::QueuedConnection方式。
- Qt::DirectConnection:信号发射时槽函数立即执行,槽函数与信号在同一个线程中。
- Qt::QueuedConnection:在事件循环回到接受者线程后执行槽函数,槽函数与信号在不同的线程中。
- Qt::BlockingQueuedConnection:与Qt::QueuedConnection相似,区别是信号线程会阻塞,直到槽函数运行完毕。当信号与槽函数在同一个线程中时绝对不能使用这种方式,否则会造成死锁。
disconnect()函数
函数disconnect()用于解除信号与槽的关联,有2种成员函数形式和4种静态函数形式。
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method);
static bool disconnect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method);
bool disconnect(const char *signal = nullptr, const QObject *receiver = nullptr, const char *method = nullptr) const;
bool disconnect(const QObject *receiver, const char *method = nullptr) const;
static bool disconnect(const QMetaObject::Connection &connection);
template <typename PointerToMemberFunction>
static bool disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method);
(1)解除一个指定发射者所有信号的关联
disconnect(sender,nullptr,nullptr,nullptr);//1
sender->disconnect();//3
(2)解除一个指定信号所有的关联
disconnect(sender,SIGNAL(signal(signal parameters)),nullptr,nullptr);//1
sender->disconnect(SIGNAL(signal parameters));//3
(3)解除一个指定发送者与一个指定接收者所有的关联
disconnect(sender,nullptr,receiver,nullptr);//1
sender->disconnect(receiver);//4
(4)解除一个指定信号与槽的关联
disconnect(sender,SIGNAL(signal(signal parameters)),reciver,SLOT(slot(slot parameters)));//1
sender()函数
sender()是QObject类的一个protected函数,在一个槽函数里调用函数sender()可以获取发送者的QObject对象指针。
自定义信号及其使用
(1)在类的signals部分定义函数,称为信号
void signal(signal parameters);
信号函数无需实现。
(2)发射信号
emit signal(signal arguments);
至于是否有与此信号关联的槽函数,信号发射者并不关心。
2.3.5 对象树
使用QObject及其子类创建的对象(统称为QObject对象)是以对象树的形式来组织的。创建一个QObject对象时若设置一个父对象,则它就会被添加到父对象的子对象列表中。一个父对象被删除时,其全部子对象就会被自动删除。
这种对象树的结构对于窗口上的对象管理特别有用。界面组件都有父对象,也就是组件的容器组件。对于不可见的QObject对象也可以设置窗口作为父对象。窗口是一个窗口对象树的最上层节点。
QObject类的构造函数有一个参数parent,用于设置对象的父对象。QObject类有一些函数可以在运行时访问对象树中的对象。
(1)函数children()。这个函数返回子对象列表。
(2)函数findChild()。这个函数返回可被转换为类型T且对象名为name的子对象。参数options表示查找方式,默认值Qt::FindChildrenRecursively表示递归查找。Qt::FIndDirectChildrenOnly表示只查找直接子对象。
(3)函数findChildren()。这个函数返回可被转换为类型T且对象名为name或正则化名为re的子对象列表。若不指定对象名,则返回可被转换为类型T的对象列表。
2.4 容器类
Qt提供了多个模版容器类,比标准模版库(STL)中的容器类更轻巧、使用更安全且更易于使用。这些容器类时隐式共享和可重入的,而且它们进行了速度和存储上 优化,因而可以减小可执行文件大小。此外,它们是线程安全的,作为只读容器时可被多个线程访问。
Qt的容器类分为顺序容器(sequential container)类和关联容器(associative container)类。
2.4.1 顺序容器类
Qt6的顺序容器类有QList、QVector、QStack和QQueue。Qt6中对QList和QVector的改动较大,Qt6中的QVector是QList的别名。另外,QList的底层采用了Qt5中的QVector的机制。
QList<T>类
实现的数据结构:顺序表。
(1)定义和初始化一个元素类型为T的列表
QList(); //创建一个空列表
QList(std::initializer_list<T> args); //创建并用初始化列表args初始化一个列表
QList(qsizetype size); //创建一个元素个数为size的列表,每个元素被初始化为0
QList(qsizetype size, QList::parameter_type value); //创建一个元素个数为size的列表,每个元素被初始化为value
(2)判断列表是否为空表
bool isEmpty() const;
(3)返回列表的元素个数,即列表长度
qsizetype count() const;
qsizetype size() const;
(4)访问列表元素
//返回下标为i的元素
QList::reference operator[](qsizetype i);
QList::const_reference operator[](qsizetype i) const;
QList::const_reference at(qsizetype i) const;
T value(qsizetype i) const; //返回下标为i的元素的值
//返回列表的第一个元素
T &first();
const T &first() const;
//返回列表的最后一个元素
T &last();
const T &last() const;
(5)增加列表元素
//在列表末尾添加元素value
void append(QList::parameter_type value);
QList<T> &operator<<(QList::parameter_type value);
//移动元素value到列表末尾
void append(QList::rvalue_ref value);
QList<T> &operator<<(QList::rvalue_ref value);
//在列表末尾添加列表value/other的元素
void append(const QList<T> &value);
QList<T> &operator<<(const QList<T> &other);
//移动列表value/other的元素到列表末尾
void append(QList<T> &&value);
QList<T> &operator<<(QList<T> &&other)
(6)删除列表元素
void remove(qsizetype i, qsizetype n = 1); //以下标i开始删除n个元素
template <typename AT>
qsizetype removeAll(const AT &t); //删除等于t的元素,返回删除的元素个数
void removeAt(qsizetype i); //删除下标为i的元素
void removeFirst(); //删除列表的第一个元素
void removeLast(); //删除列表的最后一个元素
T takeAt(qsizetype i); //删除下标为i的元素,返回被删除的元素
QList::value_type takeFirst(); //删除列表的第一个元素,返回被删除的第一个元素
QList::value_type takeLast(); //删除列表的最后一个元素,返回被删除的最后一个元素
void clear(); //删除所有元素
(7)替换列表元素
void replace(qsizetype i, QList::parameter_type value); //替换下标为i的元素为value
void replace(qsizetype i, QList::rvalue_ref value); //移动替换下标为i的元素为value
QList是Qt中常用的容器类,很多函数的输入参数或返回值是QList列表。还有一些情况下是将某种类型的QList列表用typedef定义别名。
typedef QList<T(*)> TList;
QStack<T>类
QStack是QList的子类。实现的数据结构:栈。
(1)进栈
void push(const T &t); //在栈顶添加一个元素t
(2)出栈
T pop(); //删除并且返回栈顶元素
(3)返回栈顶元素
T &top();
const T &top() const;
QQueue<T>类
QQueue是QList的子类。实现的数据结构:队列。
(1)入队
void enqueue(const T &t); //在队尾添加一个元素t
(2)出队
T dequeue(); //删除并返回队头元素
(3)返回队头元素
T &head();
const T &head() const;
2.4.2 关联容器类
Qt还提供关联容器类QSet、QMap、QMultiMap、QHash、QMultiHash。QMultiMap和QMultiHash支持一个键关联多个值。QHash类和QMultiHash类使用哈希(hash)函数进行查找,查找速度更快。
QSet<T>类
QSet是基于哈希表的集合模板类。内部是用QHash类实现的。
(1)定义和初始化一个元素类型为T的集合
QSet(); //创建一个空集合
QSet(std::initializer_list<T> list); //创建并用初始化列表list初始化一个集合
(2)判断集合是否为空集
bool empty() const;
bool isEmpty() const;
(3)返回集合的元素个数
qsizetype count() const;
qsizetype size() const;
(4)增加集合元素
//添加元素value
QSet::iterator insert(const T &value);
QSet<T> &operator|=(const T &value);
(5)删除集合元素
//删除元素value
bool remove(const T &value);
QSet<T> &operator-=(const T &value);
void clear(); //删除所有元素
(6)集合运算
- 并
QSet<T>& unite(const QSet<T> &other);
QSet<T>& operator|=(const QSet<T> &other);
QSet<T> operator|(const QSet<T> &other) const;
- 交
QSet<T> &intersect(const QSet<T> &other);
QSet<T> &operator&=(const QSet<T> &other);
QSet<T> operator&(const QSet<T> o&other) const;
- 差
QSet<T> &subtract(const QSet<T> &other);
QSet<T> &operator-=(const QSet<T> &other);
QSet<T> operator-(const QSet<T> &other) const;
(7)集合关系
- 判断集合是否包含元素
bool contains(const T &value) const;
- 判断集合是否包含另一个集合
bool contains(const QSet<T> &other) const;
QMap<Key,T>类
QMap定义一个字典(关联数组)。QMap是按照键的顺序存储数据的,因此QMap的键必须有"<"运算符,用于判断顺序。
(1)定义和初始化一个元素类型为(Key,T)的字典
QMap(); //创建一个空字典
QMap(std::initializer_list<std::pair<Key,T>> list); //创建并用初始化列表list初始化一个字典
(2)判断字典是否为空字典
bool empty() const;
bool isEmpty() const;
(3)返回字典的元素个数
QMap::size_type count() const;
QMap::size_type size() const;
(4)访问字典元素
//返回键为key的元素的值
T &operator[](const Key &key);
T operator[](const Key &key) const;
T value(const Key &key, const T &defaultValue = T()) const; //返回键为key的元素的值,若字典没有键为key的元素,则返回默认值defaultValue
//返回字典的第一个元素的值
T &first();
const T &first() const;
//返回字典的最后一个元素的值
T &last();
const T &last() const;
(5)增加字典元素
//添加元素(key,value)
QMap::iterator insert(const Key &key, const T &value);
//添加字典map的元素
void insert(const QMap<Key, T> &map);
//移动字典map的元素
void insert(QMap<Key, T> &&map);
(6)删除字典元素
QMap::size_type remove(const Key &key); //删除键为key的元素,返回删除的元素个数
T QMap::take(const Key &key); //删除键为key的元素,返回删除的元素的值
void clear(); //删除所有元素
QMultiMap<Key,T>类
QMultiMap定义一个多值映射表。
(1)定义和初始化一个元素类型为(Key,T)的多值映射表。
QMultiMap(); //创建一个空表
QMultiMap(std::initializer_list<std::pair<Key, T>> list); //创建并用初始化列表list初始化一个多值映射表
(2)判断表是否为空表
bool empty() const;
bool isEmpty() const;
(3)返回表的元素个数
QMultiMap::size_type count() const;
QMultiMap::size_type size() const;
(4)访问表的元素
T value(const Key &key, const T &defaultValue = T()) const; //返回键为key的元素的最近添加的值
QList<T> values(const Key &key) const; //返回键为key的元素的值列表
//返回表的第一个元素的最近添加的值
T &first();
const T &first() const
//返回表的最后一个元素的最近添加的值
T &last();
const T &last() const
(5)增加表元素
QMultiMap::iterator insert(const Key &key, const T &value); //添加元素(key,value)
(6)删除表元素
QMultiMap::size_type remove(const Key &key); //删除键为key的元素,返回被删除的元素个数
QMultiMap::size_type QMultiMap::remove(const Key &key, const T &value); //删除元素(key,value),返回被删除的元素个数
T take(const Key &key); //删除键为key的元素,返回被删除的元素的最近添加的值
void clear(); //删除所有元素
(7)替换表元素
QMultiMap::iterator replace(const Key &key, const T &value); //替换键为key的元素的最近添加的值为value
QHash<Key,T>类
QHash是基于哈希表的字典模版类。
(1)定义和初始化一个元素类型为(Key,T)的哈希字典
QHash(); //创建一个空字典
QHash(std::initializer_list<std::pair<Key, T>> list); //创建并用初始化列表list初始化一个字典
(2)判断字典是否为空字典
bool empty() const;
bool isEmpty() const;
(3)返回字典的元素个数
qsizetype count() const;
qsizetype size() const;
(4)访问字典元素
//返回键为key的元素的值
T &operator[](const Key &key);
const T operator[](const Key &key) const;
T value(const Key &key) const; 返回键为key的元素的值
T value(const Key &key, const T &defaultValue) const; //返回键为key的元素的值,若字典没有键为key的元素,则返回默认值defaultValue
(5)增加字典元素
QHash::iterator insert(const Key &key, const T &value); //添加元素(key,value)
void insert(const QHash<Key, T> &other); //添加字典other的元素
(6)删除字典元素
bool remove(const Key &key); //删除键为key的元素
T take(const Key &key); //删除键为key的元素,返回被删除的元素的值
void clear(); //删除所有元素
QMultiHash<Key,T>类
2.4.3 遍历容器的数据
迭代器(iterator)用于遍历容器内的数据项,有STL类型的迭代器和Java类型的迭代器。STL类型的迭代器效率更高,Java类型的迭代器是为了向后兼容。Qt还提高了一个宏foreach用于遍历容器内的所有数据项。Qt6的程序设计推荐使用STL类型的迭代器。
STL类型的迭代器概述
每一个容器类有两个STL类型的迭代器:一个用于只读访问,另一个用于读写访问。
容器类 | 只读迭代器 | 读写迭代器 |
QList<T>、QStack<T>、QQueue<T> | QList<T>::const_iterator、QList<T>::const_reverse_iterator | QList<T>::iterator、QList<T>::reverse_iterator |
QSet<T> | QSet<T>::const_iterator、QSet<T>::const_reverse_iterator | QSet<T>::iterator、QSet<T>::reverse_iterator |
QMap<Key,T>、QMultiMap<Key,T> | QMap<Key,T>::const_iterator、QMap<Key,T>::const_reverse_iterator | QMap<Key,T>::iterator、QMap<Key,T>::reverse_iterator |
QHash<Key,T>、QMultiHash<Key,T> | QHash<Key,T>::const_iterator、QHash<Key,T>::const_iterator | QHash<Key,T>::iterator、QHash<Key,T>::reverse_iterator |
STL类型的迭代器直接指向容器元素。“++”运算符使迭代器指向下一个元素,“*”运算符访问迭代器指向的元素。
函数container::begin()/container::rbegin()返回指向容器的正向/反向第一个元素的迭代器,函数container::end()/container::constrend()返回指向容器的正向/反向一个虚拟的表示末尾位置元素的迭代器。
顺序容器类的迭代器用法
*iterator访问指向的元素。
关联容器类的迭代器用法
*iterator、iterator.value()访问指向的元素的值,iterator.key()访问指向的元素的键。
隐式共享
隐式共享是对象的管理方法,在返回对象时只返回对象的指针,而不实际复制对象,只有在修改对象时才实际复制对象。
使用foreach遍历容器数据
foreach(variable,container){ //变量variable的类型必须时容器container的元素类型
...
}
2.5 其他常用的基础类
2.5.1 QVariant类
QVariant是Qt中的一种万能数据类型。
QVariant变量可以使用成员函数toT()和value<T>()返回将数据转换为具体类型T的数据。toT()函数包括:toBool()、toChar()、toFloat()、toDouble()、toInt()、toUInt()、toString()、toStringList()、toTime()等。
可以在定义QVariant变量时,通过其构造函数为其初始化。QVariant有很多参数形式的构造函数,基本覆盖toT函数涉及的类型。
可以使用成员函数setValue()为QVariant变量赋值。
2.5.2 QFlags类
QFlags<Enum>是一个模版类,其中Enum是枚举类型。QFlags用于定义枚举值的或运算组合,称为枚举类型Enum的标志类型。
enum1|enum2
实际上创建了一个QFlags<Enum>类型的临时变量。相当于:
QFlags<Enum> flags=enum1|enum2;
QFlags类支持位运算。
QFlags类有一个成员函数testFlag()可以测试某个枚举值是否包含在此标志变量中。
2.5.3 QRandomGenerator类
随机数发生器和随机数种子
Qt6中已经舍弃了Qt5中产生随机数的函数qrand()和qsrand(),取而代之的是QRandomGenerator类,它可以产生高质量的随机数。在创建QRandomGenerator对象(随机数发生器)时可以通过构造函数提供一个数作为随机数种子。
QRandomGenerator(quint32 seedValue=1);
参数seedValue是随机数种子。
QRandomGenerator有一个静态函数securelySeeded()可以创建一个随机数发生器,其随机数种子使用的是静态函数QRandomGenerator::system()创建的系统随机数发生器生成的随机数。
QRandomGenerator securelySeeded();
全局的随机数发生器
QRandomGenerator有两个静态函数会返回随机数发生器。
(1)返回系统随机数发生器
static QRandomGenerator *system();
这个发生器利用操作系统的一些特性生成随机数,在常用的操作系统上,使用这个发生器的随机数生成密码是安全的。这个发生器是线程安全的。可以在任何线程中使用。这个生成器可能会使用硬件的随机数发生器,所以不要用它生成大量的随机数,可以用它生成的随机数作为另一个QRandomGenerator对象的随机数种子。
(2)返回全局随机发生器
static QRandomGenerator *global();
这个发生器是Qt自动用静态函数securelySeeded()设置随机数种子初始化的。
QRandomGenerator的接口函数
(1)生成随机数
//生成32位随机正整数
quint32 generate();
quint32 operator()() const;
quint64 generate64(); //生成64位随机正整数
double generateDouble(); //生成[0,1)区间内的浮点数
(2)生成指定范围内的随机数
int bounded(int highest); //生成[0,highest)区间内的int随机正整数
quint32 bounded(quint32 highest); //生成[0,highest)区间内的quint32随机正整数
quint64 bounded(quint64 highest); //生成[0,highest)区间内的quint64随机正整数
double bounded(double highest); //生成[0,highest)区间内的double随机浮点数
int bounded(int lowest,int highest); //生成[lowest,highest)区间内的int随机整数
qint64 bounded(qint64 lowest,qint64 highest); //生成[lowest,highest)区间内的qint64随机整数
quint32 bounded(quint32 lowest,quint32 highest); //生成[lowest,highest)区间内的int随机正整数