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>



函数原型

功能

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>头文件中定义。

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类与元对象系统特性相关的一些接口函数:



特性

成员函数原型/静态数据成员

功能

元对象

const QMetaObject *metaObject() const;

返回对象的元对象指针

const QMetaObject staticMetaObject;

元对象

类型信息

bool inherits(const char *className) const;

判断对象是否为类className的子类

动态翻译

static QString tr(const char *sourceText, const char *disambiguation = nullptr, int n = -1);

返回字符串sourceText的翻译版本

对象树

const QObjectList &children() const;

返回子对象列表

QObject *parent() const;

返回父对象指针

void setParent(QObject *parent);

设置父对象

template <typename T>
T findChild(const QString &name = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const;

返回可被转换为类型T且对象名为name的子对象

template <typename T> 
QList<T> findChildren(const QString &name, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const;

返回可被转换为类型T且对象名为name的子对象列表

template <typename T>
QList<T> QObject::findChildren(Qt::FindChildOptions options = Qt::FindChildrenRecursively) const;

返回对象名为name的子对象列表

template <typename T>
QList<T> findChildren(const QRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const

返回可被转换为类型T且正则化名为name的子对象列表

信号与槽

static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection);
static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection);
QMetaObject::Connection connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type = Qt::AutoConnection) const;
template <typename PointerToMemberFunction> 
static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection);
template <typename PointerToMemberFunction, typename Functor> 
static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor);
template <typename PointerToMemberFunction, typename Functor> 
static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection);

设置信号与槽的关联

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);

解除信号与槽的关联

bool blockSignals(bool block);

设置是否阻止对象发射信号

bool signalsBlocked() const;

返回对象是否被阻止发射信号

属性系统

QList<QByteArray> dynamicPropertyNames() const;

返回对象的动态属性列表

bool setProperty(const char *name, const QVariant &value);

设置属性name的值为value,或定义动态属性

QVariant property(const char *name) const;

返回属性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类的主要接口函数:



分组

成员函数原型

功能

类的信息

const char *className() const;

返回类名

QMetaType metaType() const;

返回元对象的元类型

const QMetaObject *superClass() const;

返回类的直接父类的元对象

bool inherits(const QMetaObject *metaObject) const;

判断类是否为元对象metaObject的类的子类

QObject *newInstance(QGenericArgument val0 = QGenericArgument(nullptr), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument()) const;

创建类的对象,可以给构造函数传递最多10个参数

类信息元

QMetaClassInfo classInfo(int index) const;

返回序号为index的一条类信息元数据,类信息是在类中用宏Q_CLASSINFO定义的一条信息

int indexOfClassInfo(const char *name) const;

返回名为name的类信息的序号

int classInfoCount() const;

返回类的类信息条数

int classInfoOffset() const;

返回类的第一条类信息的序号

构造函数元数据

QMetaMethod constructor(int index) const;

返回类的指定序号index的构造函数元数据

int indexOfConstructor(const char *constructor) const;

返回类的正则化名为constructor的构造函数的序号

int constructorCount() const;

返回类的构造函数个数

方法元数据

QMetaMethod method(int index) const;

返回类的序号为index的成员函数的方法元数据

int indexOfMethod(const char *method) const;

返回类的成员函数method的序号

int QMetaObject::methodCount() const;

返回类的成员函数个数

int QMetaObject::methodOffset() const;

返回类的第一个成员函数的序号

枚举类型元数据

QMetaEnum enumerator(int index) const

返回序号为index的枚举类型元数据

int indexOfEnumerator(const char *name) const

返回枚举类型name的序号

int enumeratorCount() const

返回类的枚举类型个数

int enumeratorOffset() const

返回类的第一个枚举类型的序号

属性元数据

QMetaProperty property(int index) const

返回序号为index的属性的元数据

int indexOfProperty(const char *name) const

返回属性name的序号

int propertyCount() const

返回类的属性个数

int propertyOffset() const

返回类的第一个属性的序号

信号与槽

int indexOfSignal(const char *signal) const

返回信号signal的序号

int QMetaObject::indexOfSlot(const char *slot) const

返回槽函数slot的序号

静态成员函数

static bool checkConnectArgs(const char *signal, const char *method)

判断信号与槽函数的参数是否兼容

static void connectSlotsByName(QObject *object)

迭代搜索object的所有子对象,将匹配的信号与槽关联

static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0 = QGenericArgument(nullptr), QGenericArgument val1 = QGenericArgument(), QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument(), QGenericArgument val4 = QGenericArgument(), QGenericArgument val5 = QGenericArgument(), QGenericArgument val6 = QGenericArgument(), QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument())

执行QObject对象obj的成员函数member

static QByteArray normalizedSignature(const char *method)

返回成员函数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类型的迭代器直接指向容器元素。“++”运算符使迭代器指向下一个元素,“*”运算符访问迭代器指向的元素。




qt 指定架构_c++


函数container::begin()/container::rbegin()返回指向容器的正向/反向第一个元素的迭代器,函数container::end()/container::constrend()返回指向容器的正向/反向一个虚拟的表示末尾位置元素的迭代器。

顺序容器类的迭代器用法 

*iterator访问指向的元素。

关联容器类的迭代器用法

*iterator、iterator.value()访问指向的元素的值,iterator.key()访问指向的元素的键。

隐式共享

隐式共享是对象的管理方法,在返回对象时只返回对象的指针,而不实际复制对象,只有在修改对象时才实际复制对象。

使用foreach遍历容器数据

foreach(variable,container){    //变量variable的类型必须时容器container的元素类型
    ...
}


qt 指定架构_Powered by 金山文档_02


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随机正整数