目录
一. 核心数据类型 (Core Datatypes)
1、QString
2、QByteArray
3、QVariant
4、QList, QVector, QMap, QHash, QSet
QList: 有序列表,支持重复元素。
QVector高效的动态数组
QMap: 基于红黑树的有序映射容器
QHash: 基于哈希表的无序映射容器
QSet: 集合类,存储不重复的元素
应用场景及比较
5、QDate, QTime, QDateTime
QDate提供日期操作
QTime提供时间操作
QDateTime日期和时间运算操作
二. 文件和目录 (File and Directory Handling)
三. 事件系统 (Event System)
四. 多线程和并发 (Multithreading and Concurrency)
五. 国际化和本地化 (Internationalization and Localization)
六. 进程和进程间通信 (Process and Inter-Process Communication - IPC)
七. 插件支持 (Plugin Support)
八. 文本编解码 (Text Codecs)
九. 动态库加载 (Dynamic Library Loading)
十. 全局函数
十一. 其他实用工具
QtCore 是 Qt 框架的核心模块,提供了众多基础功能,用于开发平台无关的应用程序。QtCore 包含了处理数据类型、事件循环、线程管理、文件和文本操作、国际化支持等一系列功能。
QtCore 提供了一些常用的数据类型类,用于表示不同类型的数据。
QString
是 Qt 提供的字符串类,用于存储和操作 Unicode 字符串。它支持各种字符串操作,如拼接、查找、替换和大小写转换。
核心代码示例:
#include
#include
int main() {
// ======================
// [1] 字符串拼接演示
// ======================
QString greetingPart1 = "Hello";
QString greetingPart2 = "World";
// 方法1:使用 + 运算符
QString concatenatedByPlus = greetingPart1 + " " + greetingPart2;
// 方法2:使用链式 append()
QString concatenatedByAppend = greetingPart1
.append(" ")
.append(greetingPart2);
// 方法3:使用格式化 arg()
QString formattedString = QString("%1 %2")
.arg(greetingPart1)
.arg(greetingPart2);
qDebug() << "Plus operator:" << concatenatedByPlus; // 输出: "Hello World"
qDebug() << "Append method:" << concatenatedByAppend; // 输出: "Hello World"
qDebug() << "Formatted arg():" << formattedString; // 输出: "Hello World"
// ======================
// [2] 字符串查找操作
// ======================
const QString sampleText = "This is a test string.";
// 查找第一个匹配项
const int firstTestIndex = sampleText.indexOf("test"); // 返回 10
// 查找最后出现的's'
const int lastSIndex = sampleText.lastIndexOf("s"); // 返回 19
// 存在性检查
const bool hasString = sampleText.contains("string"); // 返回 true
qDebug() << "\nFirst 'test' at index:" << firstTestIndex;
qDebug() << "Last 's' at index:" << lastSIndex;
qDebug() << "Contains 'string':" << hasString;
// ======================
// [3] 字符串替换操作
// ======================
QString originalText = sampleText;
// 全局替换所有"is"为"was"
QString globalReplaced = originalText.replace("is", "was");
// 位置替换:从索引5开始替换2个字符
QString positionalReplaced = originalText.replace(5, 2, "was");
qDebug() << "\nGlobal replacement:" << globalReplaced; // "Thwas was a test string."
qDebug() << "Positional replacement:" << positionalReplaced; // "Thiswas a test string."
// ======================
// [4] 大小写转换操作
// ======================
const QString lowerText = sampleText.toLower(); // 全小写
const QString upperText = sampleText.toUpper(); // 全大写
qDebug() << "\nLowercase:" << lowerText; // "this is a test string."
qDebug() << "Uppercase:" << upperText; // "THIS IS A TEST STRING."
return 0;
}
QByteArray
是一个字节数组类,常用于处理二进制数据。它提供了类似 QString
的操作方法,但针对的是字节而非字符。
核心代码示例:
#include
#include
int main() {
// ======================
// [1] 字节数组拼接演示
// ======================
QByteArray greetingPart1 = "Hello";
QByteArray greetingPart2 = "World";
// 方法1:使用 + 运算符
QByteArray concatenatedByPlus = greetingPart1 + " " + greetingPart2;
qDebug() << "Plus operator:" << concatenatedByPlus.data(); // 输出: "Hello World"
// 方法2:使用链式 append()
QByteArray concatenatedByAppend = greetingPart1
.append(" ")
.append(greetingPart2);
qDebug() << "Append method:" << concatenatedByAppend.data(); // 输出: "Hello World"
qDebug() << "--------------------";
// ======================
// [2] 字节数组查找操作
// ======================
const QByteArray sampleData = "This is a test byte array.";
// 查找第一个匹配项
const int firstTestIndex = sampleData.indexOf("test"); // 返回 10
// 查找最后出现的 'e'
const int lastEIndex = sampleData.lastIndexOf("e"); // 返回 20
// 存在性检查
const bool hasByte = sampleData.contains("byte"); // 返回 true
qDebug() << "First 'test' at index:" << firstTestIndex;
qDebug() << "Last 'e' at index:" << lastEIndex;
qDebug() << "Contains 'byte':" << hasByte;
qDebug() << "--------------------";
// ======================
// [3] 字节数组替换操作
// ======================
QByteArray originalData = sampleData;
// 全局替换所有 "is" 为 "was"
QByteArray globalReplaced = originalData.replace("is", "was");
// 位置替换:从索引5开始替换2个字符
QByteArray positionalReplaced = originalData.replace(5, 2, "was");
qDebug() << "Global replacement:" << globalReplaced.data(); // "Thwas was a test byte array."
qDebug() << "Positional replacement:" << positionalReplaced.data(); // "Thiswas a test byte array."
qDebug() << "--------------------";
// ======================
// [4] 大小写转换操作 (仅适用于 ASCII 字符)
// ======================
const QByteArray lowerData = sampleData.toLower(); // 全小写
const QByteArray upperData = sampleData.toUpper(); // 全大写
qDebug() << "Lowercase:" << lowerData.data(); // "this is a test byte array."
qDebug() << "Uppercase:" << upperData.data(); // "THIS IS A TEST BYTE ARRAY."
return 0;
}
QVariant
是一个通用的数据容器类,能够存储任意类型的数据(如整数、字符串、日期等),并且能够在不同类型之间转换。
核心代码示例:
#include
#include
#include
#include
int main() {
// ======================
// [1] 存储不同类型的数据
// ======================
// 存储一个整数
QVariant intVariant = 123;
qDebug() << "Stored integer:" << intVariant.toInt();
// 存储一个字符串
QVariant stringVariant = "Hello, QVariant!";
qDebug() << "Stored string:" << stringVariant.toString();
// 存储一个日期
QVariant dateVariant = QDate(2025, 3, 24);
qDebug() << "Stored date:" << dateVariant.toDate();
// 存储一个浮点数
QVariant doubleVariant = 3.14159;
qDebug() << "Stored double:" << doubleVariant.toDouble();
qDebug() << "--------------------";
// ======================
// [2] 获取存储的值并进行类型转换
// ======================
// 将存储的整数转换为字符串
QString intAsString = intVariant.toString();
qDebug() << "Integer as string:" << intAsString;
// 尝试将存储的字符串转换为整数
bool conversionSuccess;
int stringAsInt = stringVariant.toInt(&conversionSuccess);
if (conversionSuccess) {
qDebug() << "String as integer:" << stringAsInt;
} else {
qDebug() << "String cannot be converted to integer.";
}
// 尝试将存储的日期转换为字符串
QString dateAsString = dateVariant.toString(); // 默认格式
qDebug() << "Date as string (default format):" << dateAsString;
QString formattedDateAsString = dateVariant.toDate().toString("yyyy-MM-dd"); // 指定格式
qDebug() << "Date as string (custom format):" << formattedDateAsString;
// 尝试将存储的整数转换为日期
QDate intAsDate = intVariant.toDate();
if (intAsDate.isValid()) {
qDebug() << "Integer as date:" << intAsDate;
} else {
qDebug() << "Integer cannot be converted to date.";
}
qDebug() << "--------------------";
// ======================
// [3] 检查 QVariant 中存储的数据类型
// ======================
qDebug() << "Type of intVariant:" << intVariant.type();
qDebug() << "Type name of intVariant:" << intVariant.typeName();
qDebug() << "Type of stringVariant:" << stringVariant.type();
qDebug() << "Type name of stringVariant:" << stringVariant.typeName();
qDebug() << "Type of dateVariant:" << dateVariant.type();
qDebug() << "Type name of dateVariant:" << dateVariant.typeName();
return 0;
}
// ======================
// console
// ======================
//Stored integer: 123
//Stored string: "Hello, QVariant!"
//Stored date: QDate("2025-03-24")
//Stored double: 3.14159
//--------------------
//Integer as string: "123"
//String cannot be converted to integer.
//Date as string (default format): "2025-03-24"
//Date as string (custom format): "2025-03-24"
//Integer cannot be converted to date.
//--------------------
//Type of intVariant: QVariant::int
//Type name of intVariant: int
//Type of stringVariant: QVariant::QString
//Type name of stringVariant: QString
//Type of dateVariant: QVariant::QDate
//Type name of dateVariant: QDate
QtCore 提供了一系列容器类,这些容器具有高效的存储和查找功能。
QList
: 有序列表,支持重复元素。QList
是 Qt 框架中最常用的通用容器类之一,用于存储一个有序的元素列表。它具有以下关键特点:
详细说明:
有序列表 (Ordered List): 元素在 QList
中按照它们被插入的顺序存储。你可以通过索引(从 0 开始)来访问特定位置的元素。
支持重复元素 (Supports Duplicate Elements): 你可以在 QList
中存储多个相同值的元素。
动态大小 (Dynamic Size): QList
的大小可以根据需要动态地增长或缩小。你不需要在创建时指定列表的大小。
基于索引访问 (Index-based Access): 可以使用整数索引快速访问列表中的任何元素,类似于数组。
隐式共享 (Implicit Sharing - Copy-on-Write): QList
使用隐式共享技术,这意味着在复制 QList
对象时,实际的数据不会被立即复制。只有当其中一个副本被修改时,才会发生数据的复制。这在传递和返回 QList
对象时可以提高性能。
性能特点:
append()
, prepend()
): 通常是快速的(平均时间复杂度为 O(1))。insert()
): 如果插入位置不在列表的末尾或开头,可能需要移动其他元素,时间复杂度为 O(n),其中 n 是列表中元素的数量。removeAt()
): 可能需要移动其他元素,时间复杂度为 O(n)。核心代码示例:
#include
#include
#include
#include // 需包含此头文件以使用 std::sort
int main() {
// ======================
// [1] 创建和初始化 QList
// ======================
QList stringList;
QList intList = {10, 20, 30, 20}; // 使用初始化列表
qDebug() << "Initial intList:" << intList; // 输出: (10, 20, 30, 20)
// ======================
// [2] 添加元素
// ======================
stringList.append("Apple");
stringList.prepend("Banana");
stringList.insert(1, "Orange"); // 在索引 1 的位置插入 "Orange"
qDebug() << "stringList after adding elements:" << stringList; // 输出: ("Banana", "Orange", "Apple")
// ======================
// [3] 访问元素
// ======================
qDebug() << "First element of stringList:" << stringList[0]; // 使用运算符
qDebug() << "Second element of stringList:" << stringList.at(1); // 使用 at() 函数 (更安全,会进行边界检查)
// ======================
// [4] 获取列表大小
// ======================
qDebug() << "Size of stringList:" << stringList.size(); // 或 stringList.count();
// ======================
// [5] 检查列表是否为空
// ======================
qDebug() << "Is stringList empty:" << stringList.isEmpty();
// ======================
// [6] 移除元素
// ======================
intList.removeAt(2); // 移除索引为 2 的元素 (值为 30)
qDebug() << "intList after removing index 2:" << intList; // 输出: (10, 20, 20)
stringList.removeOne("Orange"); // 移除第一个值为 "Orange" 的元素
qDebug() << "stringList after removing \"Orange\":" << stringList; // 输出: ("Banana", "Apple")
intList.removeAll(20); // 移除所有值为 20 的元素
qDebug() << "intList after removing all 20s:" << intList; // 输出: (10)
// ======================
// [7] 清空列表
// ======================
stringList.clear();
qDebug() << "Is stringList empty after clearing:" << stringList.isEmpty();
// ======================
// [8] 遍历列表
// ======================
QList numbers = {1, 2, 3, 4, 5};
qDebug() << "Iterating numbers (using index):";
for (int i = 0; i < numbers.size(); ++i) {
qDebug() << numbers[i];
}
qDebug() << "Iterating numbers (using range-based for loop):";
for (int number : numbers) {
qDebug() << number;
}
qDebug() << "Iterating numbers (using iterator):";
QListIterator iterator(numbers);
while (iterator.hasNext()) {
qDebug() << iterator.next();
}
qDebug() << "Iterating numbers (using mutable iterator to modify elements):";
QMutableListIterator mutableIterator(numbers);
while (mutableIterator.hasNext()) {
if (mutableIterator.next() % 2 == 0) {
mutableIterator.setValue(mutableIterator.value() * 10); // 将偶数乘以 10
}
}
qDebug() << "Modified numbers:" << numbers; // 输出: (1, 20, 3, 40, 5)
// ======================
// [9] 查找元素
// ======================
QList values = {5, 10, 15, 10, 20};
qDebug() << "Does values contain 10:" << values.contains(10); // 输出: true
qDebug() << "First index of 10:" << values.indexOf(10); // 输出: 1
qDebug() << "Last index of 10:" << values.lastIndexOf(10); // 输出: 3
// ======================
// [10] 排序
// ======================
QList unsortedList = {3, 1, 4, 1, 5, 9, 2, 6};
std::sort(unsortedList.begin(), unsortedList.end(), std::greater());
qDebug() << "Sorted unsortedList:" << unsortedList; // 输出: (1, 1, 2, 3, 4, 5, 6, 9)
return 0;
}
// ======================
// console
// ======================
//Initial intList: (10, 20, 30, 20)
//stringList after adding elements: ("Banana", "Orange", "Apple")
//First element of stringList: "Banana"
//Second element of stringList: "Orange"
//Size of stringList: 3
//Is stringList empty: false
//intList after removing index 2: (10, 20, 20)
//stringList after removing "Orange": ("Banana", "Apple")
//intList after removing all 20s: (10)
//Is stringList empty after clearing: true
//Iterating numbers (using index):
//1
//2
//3
//4
//5
//Iterating numbers (using range-based for loop):
//1
//2
//3
//4
//5
//Iterating numbers (using iterator):
//1
//2
//3
//4
//5
//Iterating numbers (using mutable iterator to modify elements):
//Modified numbers: (1, 20, 3, 40, 5)
//Does values contain 10: true
//First index of 10: 1
//Last index of 10: 3
//Sorted unsortedList: (9, 6, 5, 4, 3, 2, 1, 1)
QVector高效的动态数组
与 QList
相比,QVector
的主要特点是其元素在内存中是连续存储的,这带来了特定的性能优势。
详细说明:
高效的动态数组 (Efficient Dynamic Array): QVector
将其所有元素存储在一段连续的内存区域中。这意味着你可以像访问普通数组一样通过索引快速地访问任何元素。当 QVector
的容量不足以容纳新的元素时,它会重新分配一块更大的连续内存,并将现有元素复制到新的内存区域。
连续存储 (Contiguous Storage): 这是 QVector
最关键的特性。由于元素在内存中是紧密排列的,因此可以实现非常快速的随机访问和高效的迭代。
动态大小 (Dynamic Size): 类似于 QList
, QVector
的大小也可以根据需要动态地增长或缩小。
基于索引访问 (Index-based Access): 可以使用整数索引(从 0 开始)以常量时间复杂度 O(1) 访问任何元素。
支持重复元素 (Supports Duplicate Elements): QVector
允许存储多个相同值的元素。
隐式共享 (Implicit Sharing - Copy-on-Write): QVector
也实现了隐式共享,这有助于在复制 QVector
对象时减少不必要的内存拷贝。
性能特点:
随机访问 (Access by Index): O(1) - 这是 QVector
最主要的优势。由于元素存储在连续的内存中,通过索引访问元素非常快。
在末尾添加或删除元素 (append()
, push_back()
, removeLast()
): 平均 O(1) - 通常很快,但在需要重新分配内存时可能会暂时变慢。
在开头添加或删除元素 (prepend()
, removeFirst()
): O(n) - 在开头插入或删除元素需要将所有其他元素向后或向前移动一个位置,因此效率较低。
在任意位置插入或删除元素 (insert()
, removeAt()
): O(n) - 同样需要移动后续元素,效率较低,特别是对于大型 QVector
。
迭代 (Iteration): 非常高效,因为内存是连续的,可以很好地利用 CPU 的缓存机制。
核心代码示例:
#include
#include
#include
#include // 引入 std::sort
int main() {
// ======================
// [1] 创建和初始化 QVector
// ======================
QVector vector1;
QVector vector2 = {"Red", "Green", "Blue"}; // 使用初始化列表
qDebug() << "Initial vector2:" << vector2; // 输出: ("Red", "Green", "Blue")
// ======================
// [2] 添加元素
// ======================
vector1.append(10);
vector1.push_back(20); // 等同于 append()
vector1.insert(1, 15); // 在索引 1 的位置插入 15 (效率较低,可能导致元素移动)
qDebug() << "vector1 after adding elements:" << vector1; // 输出: (10, 15, 20)
// ======================
// [3] 访问元素
// ======================
qDebug() << "First element of vector2:" << vector2[0]; // 使用运算符
qDebug() << "Second element of vector1:" << vector1.at(1); // 使用 at() 函数 (更安全,会进行边界检查)
// ======================
// [4] 获取大小和容量
// ======================
qDebug() << "Size of vector1:" << vector1.size();
qDebug() << "Capacity of vector1:" << vector1.capacity(); // 实际分配的内存大小
// ======================
// [5] 预留空间 (提高效率)
// ======================
QVector largeVector;
largeVector.reserve(1000); // 预先分配 1000 个元素的空间,避免频繁的重新分配
for (int i = 0; i < 1000; ++i) {
largeVector.append(i); // 添加元素会更高效
}
qDebug() << "Size of largeVector:" << largeVector.size();
qDebug() << "Capacity of largeVector:" << largeVector.capacity();
// ======================
// [6] 移除元素
// ======================
vector1.removeAt(0); // 移除索引 0 的元素 (效率较低)
qDebug() << "vector1 after removing index 0:" << vector1; // 输出: (15, 20)
vector2.removeOne("Green"); // 移除第一个值为 "Green" 的元素
qDebug() << "vector2 after removing \"Green\":" << vector2; // 输出: ("Red", "Blue")
vector1.removeLast(); // 移除最后一个元素 (高效)
qDebug() << "vector1 after removing last element:" << vector1; // 输出: (15)
vector2.clear(); // 清空 vector
qDebug() << "Is vector2 empty after clearing:" << vector2.isEmpty();
// ======================
// [7] 遍历 vector
// ======================
QVector numbers = {5, 2, 8, 1, 9};
qDebug() << "Iterating numbers (using index):";
for (int i = 0; i < numbers.size(); ++i) {
qDebug() << numbers[i];
}
qDebug() << "Iterating numbers (using range-based for loop):";
for (int number : numbers) {
qDebug() << number;
}
qDebug() << "Iterating numbers (using iterator):";
QVectorIterator iterator(numbers);
while (iterator.hasNext()) {
qDebug() << iterator.next();
}
// ======================
// [8] 排序
// ======================
std::sort(numbers.begin(), numbers.end()); // 使用 std::sort 对 QVector 进行排序
qDebug() << "Sorted numbers:" << numbers; // 输出: (1, 2, 5, 8, 9)
return 0;
}
// ======================
// console
// ======================
//Initial vector2: QVector("Red", "Green", "Blue")
//vector1 after adding elements: QVector(10, 15, 20)
//First element of vector2: "Red"
//Second element of vector1: 15
//Size of vector1: 3
//Capacity of vector1: 10
//Size of largeVector: 1000
//Capacity of largeVector: 1000
//vector1 after removing index 0: QVector(15, 20)
//vector2 after removing "Green": QVector("Red", "Blue")
//vector1 after removing last element: QVector(15)
//Is vector2 empty after clearing: true
//Iterating numbers (using index):
//5
//2
//8
//1
//9
//Iterating numbers (using range-based for loop):
//5
//2
//8
//1
//9
//Iterating numbers (using iterator):
//5
//2
//8
//1
//9
//Sorted numbers: QVector(1, 2, 5, 8, 9)
QMap
: 基于红黑树的有序映射容器QMap
是 Qt 框架提供的一个关联容器类,它实现了一个有序的映射(map)。这意味着它存储的是键-值对 (key-value pairs),并且这些键值对是按照键的顺序进行排序的。QMap
的底层实现是基于红黑树 (Red-Black Tree),这是一种自平衡的二叉搜索树,保证了在各种操作下的高效性能。
详细说明:
基于红黑树 (Red-Black Tree): QMap
内部使用红黑树数据结构。红黑树的自平衡特性确保了即使在频繁的插入和删除操作后,树的高度仍然保持在对数级别,从而保证了高效的查找、插入和删除操作。
有序映射 (Ordered Map): 存储在 QMap
中的键值对会根据其键进行排序。默认情况下,排序是使用键类型的 <
运算符进行的。这意味着当你遍历 QMap
时,你会按照键的升序访问这些键值对。
键-值对 (Key-Value Pairs): QMap
存储的是键和值之间的关联。每个键在 QMap
中必须是唯一的(默认情况下)。如果你尝试插入一个已存在的键,新的值会替换旧的值。
唯一键 (Unique Keys): 默认情况下,QMap
只允许每个键存在一个对应的值。如果需要存储具有相同键的多个值,可以使用 QMultiMap
类。
动态大小 (Dynamic Size): QMap
的大小可以根据需要动态地增长或缩小。
性能特点 (由于红黑树的特性):
核心代码示例:
#include
#include
#include
int main() {
// ======================
// [1] 创建和初始化 QMap
// ======================
QMap ageMap;
// ======================
// [2] 插入键值对
// ======================
ageMap.insert("Alice", 30);
ageMap["Bob"] = 25; // 使用运算符插入或修改值
ageMap.insert("Charlie", 35);
qDebug() << "Initial ageMap:" << ageMap; // 输出: {{"Alice", 30}, {"Bob", 25}, {"Charlie", 35}} (注意键的排序)
// ======================
// [3] 访问值
// ======================
qDebug() << "Alice's age:" << ageMap["Alice"];
qDebug() << "Bob's age:" << ageMap.value("Bob"); // 使用 value() 函数
// ======================
// [4] 检查键是否存在
// ======================
qDebug() << "Does ageMap contain key \"Alice\":" << ageMap.contains("Alice");
qDebug() << "Number of occurrences of key \"David\":" << ageMap.count("David"); // 如果不存在,返回 0
// ======================
// [5] 获取映射大小
// ======================
qDebug() << "Size of ageMap:" << ageMap.size(); // 或 ageMap.count();
// ======================
// [6] 检查映射是否为空
// ======================
qDebug() << "Is ageMap empty:" << ageMap.isEmpty();
// ======================
// [7] 移除键值对
// ======================
ageMap.remove("Bob");
qDebug() << "ageMap after removing \"Bob\":" << ageMap; // 输出: {{"Alice", 30}, {"Charlie", 35}}
// ======================
// [8] 清空映射
// ======================
// ageMap.clear();
// qDebug() << "Is ageMap empty after clearing:" << ageMap.isEmpty();
// ======================
// [9] 遍历映射 (按键的排序顺序)
// ======================
qDebug() << "Iterating ageMap (using iterator):";
QMapIterator iterator(ageMap);
while (iterator.hasNext()) {
iterator.next();
qDebug() << iterator.key() << ":" << iterator.value();
}
//Qt5
qDebug() << "Qt5 Iterating ageMap (using range-based for loop - C++11):";
for (const auto& key : ageMap.keys()) {
qDebug() << key << ":" << ageMap[key];
}
// Qt 6
qDebug() << "Qt6 Iterating ageMap (using range-based for loop - C++11):";
for (auto it = ageMap.keyValueBegin(); it != ageMap.keyValueEnd(); ++it) {
const auto& pair = *it;
qDebug() << pair.first << ":" << pair.second;
}
// ======================
// [10] 获取所有键和值
// ======================
QList keys = ageMap.keys();
QList values = ageMap.values();
qDebug() << "All keys:" << keys; // 输出: ("Alice", "Charlie")
qDebug() << "All values:" << values; // 输出: (30, 35)
return 0;
}
// ======================
// console
// ======================
//Initial ageMap: QMap(("Alice", 30)("Bob", 25)("Charlie", 35))
//Alice's age: 30
//Bob's age: 25
//Does ageMap contain key "Alice": true
//Number of occurrences of key "David": 0
//Size of ageMap: 3
//Is ageMap empty: false
//ageMap after removing "Bob": QMap(("Alice", 30)("Charlie", 35))
//Iterating ageMap (using iterator):
//"Alice" : 30
//"Charlie" : 35
//Qt5 Iterating ageMap (using range-based for loop - C++11):
//"Alice" : 30
//"Charlie" : 35
//Qt6 Iterating ageMap (using range-based for loop - C++11):
//"Alice" : 30
//"Charlie" : 35
//All keys: ("Alice", "Charlie")
//All values: (30, 35)
QHash
: 基于哈希表的无序映射容器QHash
是 Qt 框架提供的另一个关联容器类,它实现了一个无序的映射(map)。与 QMap
不同,QHash
的底层实现是基于哈希表(Hash Table),这使得它在平均情况下提供了非常快速的查找、插入和删除操作。
详细说明:
基于哈希表 (Hash Table): QHash
内部使用哈希表数据结构。哈希表通过使用哈希函数将键映射到存储桶(buckets)中的索引,从而实现快速的平均时间复杂度。
无序映射 (Unordered Map): 存储在 QHash
中的键值对没有特定的顺序。当你遍历 QHash
时,元素的顺序可能与插入顺序不同,并且在不同的运行或不同的数据情况下可能会发生变化。你不应该依赖于 QHash
的迭代顺序。
键-值对 (Key-Value Pairs): QHash
存储的是键和值之间的关联。每个键在 QHash
中必须是唯一的(默认情况下)。如果你尝试插入一个已存在的键,新的值会替换旧的值。
唯一键 (Unique Keys): 默认情况下,QHash
只允许每个键存在一个对应的值。如果需要存储具有相同键的多个值,可以使用 QMultiHash
类。
动态大小 (Dynamic Size): QHash
的大小可以根据需要动态地增长或缩小。
键类型的要求: 作为哈希表的实现,QHash
要求其键类型必须是可哈希的。这意味着 Qt 必须能够为键类型计算一个哈希值。Qt 为许多内置类型(如 int
, QString
等)提供了默认的哈希函数。对于自定义类型,你需要提供一个全局的 qHash()
函数的特化版本。
性能特点 (由于哈希表的特性):
核心代码示例:
#include
#include
#include
int main() {
// ======================
// [1] 创建和初始化 QHash
// ======================
QHash scoreMap;
// ======================
// [2] 插入键值对
// ======================
scoreMap.insert("Alice", 95);
scoreMap["Bob"] = 88; // 使用运算符插入或修改值
scoreMap.insert("Charlie", 92);
qDebug() << "Initial scoreMap:" << scoreMap; // 输出顺序不确定
// ======================
// [3] 访问值
// ======================
qDebug() << "Alice's score:" << scoreMap["Alice"];
qDebug() << "Bob's score:" << scoreMap.value("Bob"); // 使用 value() 函数
// ======================
// [4] 检查键是否存在
// ======================
qDebug() << "Does scoreMap contain key \"Alice\":" << scoreMap.contains("Alice");
qDebug() << "Number of occurrences of key \"David\":" << scoreMap.count("David"); // 如果不存在,返回 0
// ======================
// [5] 获取哈希表大小
// ======================
qDebug() << "Size of scoreMap:" << scoreMap.size(); // 或 scoreMap.count();
// ======================
// [6] 检查哈希表是否为空
// ======================
qDebug() << "Is scoreMap empty:" << scoreMap.isEmpty();
// ======================
// [7] 移除键值对
// ======================
scoreMap.remove("Bob");
qDebug() << "scoreMap after removing \"Bob\":" << scoreMap; // 输出顺序不确定
// ======================
// [8] 清空哈希表
// ======================
// scoreMap.clear();
// qDebug() << "Is scoreMap empty after clearing:" << scoreMap.isEmpty();
// ======================
// [9] 遍历哈希表 (顺序不确定)
// ======================
qDebug() << "Iterating scoreMap (using iterator):";
QHashIterator iterator(scoreMap);
while (iterator.hasNext()) {
iterator.next();
qDebug() << iterator.key() << ":" << iterator.value();
}
//Qt5
qDebug() << "Qt5 Iterating ageMap (using range-based for loop - C++11):";
for (const auto& key : scoreMap.keys()) {
qDebug() << key << ":" << scoreMap[key];
}
// Qt 6
qDebug() << "Qt6 Iterating ageMap (using range-based for loop - C++11):";
for (auto it = scoreMap.keyValueBegin(); it != scoreMap.keyValueEnd(); ++it) {
const auto& pair = *it;
qDebug() << pair.first << ":" << pair.second;
}
// ======================
// [10] 获取所有键和值 (顺序不确定)
// ======================
QList keys = scoreMap.keys();
QList values = scoreMap.values();
qDebug() << "All keys:" << keys; // 输出顺序不确定
qDebug() << "All values:" << values; // 输出顺序不确定
return 0;
}
// ======================
// console
// ======================
//Initial scoreMap: QHash(("Bob", 88)("Alice", 95)("Charlie", 92))
//Alice's score: 95
//Bob's score: 88
//Does scoreMap contain key "Alice": true
//Number of occurrences of key "David": 0
//Size of scoreMap: 3
//Is scoreMap empty: false
//scoreMap after removing "Bob": QHash(("Alice", 95)("Charlie", 92))
//Iterating scoreMap (using iterator):
//"Alice" : 95
//"Charlie" : 92
//Qt5 Iterating ageMap (using range-based for loop - C++11):
//"Alice" : 95
//"Charlie" : 92
//Qt6 Iterating ageMap (using range-based for loop - C++11):
//"Alice" : 95
//"Charlie" : 92
//All keys: ("Alice", "Charlie")
//All values: (95, 92)
QSet
: 集合类,存储不重复的元素QSet
是 Qt 框架提供的一个容器类,用于存储一组不重复的元素。它实现了数学上集合的概念,确保每个元素在集合中只出现一次。
详细说明:
存储不重复的元素 (Stores Unique Elements): 这是 QSet
最核心的特性。当你尝试向 QSet
中插入一个已经存在的元素时,该操作会被忽略,集合中只会保留该元素的一个实例。
无序集合 (Unordered Collection): QSet
中的元素没有特定的顺序。当你遍历一个 QSet
时,元素的顺序可能与它们被插入的顺序不同,并且在不同的运行或不同的数据情况下可能会发生变化。你不应该依赖于 QSet
的迭代顺序。
基于哈希表 (Likely Hash Table Implementation): 尽管 Qt 的文档没有明确指出,但 QSet
通常基于哈希表(类似于 QHash
)实现,以提供高效的插入、删除和查找操作。
动态大小 (Dynamic Size): QSet
的大小可以根据需要动态地增长或缩小。
快速成员测试 (Fast Membership Testing): 由于通常基于哈希表实现,检查一个元素是否存在于 QSet
中是一个非常快速的操作(平均时间复杂度为 O(1))。
元素类型的要求: 类似于 QHash
,QSet
要求其存储的元素类型必须是可哈希的。这意味着 Qt 必须能够为元素类型计算一个哈希值。Qt 为许多内置类型提供了默认的哈希函数。对于自定义类型,你需要提供一个全局的 qHash()
函数的特化版本。
性能特点 (通常基于哈希表的特性):
核心代码示例:
#include
#include
#include
#include // 用于 std::includes
int main() {
// ======================
// [1] 创建和初始化 QSet
// ======================
QSet numberSet;
QSet nameSet = {"Alice", "Bob", "Charlie", "Alice"}; // 注意 "Alice" 只会被存储一次
qDebug() << "Initial nameSet:" << nameSet; // 输出顺序不确定,但 "Alice" 只会出现一次
// ======================
// [2] 插入元素
// ======================
numberSet.insert(10);
numberSet.insert(20);
numberSet.insert(10); // 尝试插入重复元素,会被忽略
nameSet << "David"; // 使用 << 运算符插入元素
qDebug() << "numberSet after adding elements:" << numberSet; // 输出顺序不确定,但只包含 10 和 20
qDebug() << "nameSet after adding elements:" << nameSet; // 输出顺序不确定,包含 "Alice", "Bob", "Charlie", "David"
// ======================
// [3] 检查元素是否存在
// ======================
qDebug() << "Does numberSet contain 20:" << numberSet.contains(20); // 输出: true
qDebug() << "Does nameSet contain \"Eve\":" << nameSet.contains("Eve"); // 输出: false
// ======================
// [4] 获取集合大小
// ======================
qDebug() << "Size of numberSet:" << numberSet.size(); // 或 numberSet.count();
qDebug() << "Size of nameSet:" << nameSet.size();
// ======================
// [5] 检查集合是否为空
// ======================
qDebug() << "Is numberSet empty:" << numberSet.isEmpty();
// ======================
// [6] 移除元素
// ======================
numberSet.remove(10);
qDebug() << "numberSet after removing 10:" << numberSet; // 输出顺序不确定,可能只包含 20
// ======================
// [7] 清空集合
// ======================
// nameSet.clear();
// qDebug() << "Is nameSet empty after clearing:" << nameSet.isEmpty();
// ======================
// [8] 遍历集合 (顺序不确定)
// ======================
qDebug() << "Iterating numberSet (using range-based for loop - C++11):";
for (int number : numberSet) {
qDebug() << number;
}
qDebug() << "Iterating nameSet (using iterator):";
QSetIterator iterator(nameSet);
while (iterator.hasNext()) {
qDebug() << iterator.next();
}
// ======================
// [9] 集合操作
// ======================
QSet set1 = {1, 2, 3};
QSet set2 = {3, 4, 5};
// 并集
QSet unionSet = set1 | set2; // 或使用 set1.united(set2)
qDebug() << "Union of set1 and set2:" << unionSet; // 输出顺序不确定,包含 1, 2, 3, 4, 5
// 交集
QSet intersectSet = set1 & set2; // 或使用 set1.intersect(set2)
qDebug() << "Intersection of set1 and set2:" << intersectSet; // 输出顺序不确定,包含 3
// 差集
QSet differenceSet = set1;
differenceSet.subtract(set2);
qDebug() << "Difference of set1 and set2 (set1 - set2):" << differenceSet; // 输出顺序不确定,包含 1, 2
// 子集判断
QSet superset = {1, 2, 3, 4};
bool isSubset = std::includes(superset.begin(), superset.end(), set1.begin(), set1.end());
qDebug() << "Is set1 a subset of {1, 2, 3, 4}:" << isSubset; // 输出: true
return 0;
}
// ======================
// console
// ======================
//Initial nameSet: QSet("Alice", "Bob", "Charlie")
//numberSet after adding elements: QSet(20, 10)
//nameSet after adding elements: QSet("David", "Alice", "Bob", "Charlie")
//Does numberSet contain 20: true
//Does nameSet contain "Eve": false
//Size of numberSet: 2
//Size of nameSet: 4
//Is numberSet empty: false
//numberSet after removing 10: QSet(20)
//Iterating numberSet (using range-based for loop - C++11):
//20
//Iterating nameSet (using iterator):
//"David"
//"Alice"
//"Bob"
//"Charlie"
//Union of set1 and set2: QSet(4, 5, 2, 3, 1)
//Intersection of set1 and set2: QSet(3)
//Difference of set1 and set2 (set1 - set2): QSet(2, 1)
//Is set1 a subset of {1, 2, 3, 4}: false
应用场景:
1. QList
:
QList
是一个很好的默认选择。QListView
或 QComboBox
中存储字符串列表。2. QVector
:
reserve()
预先分配内存,提高效率。QList
略高。3. QMap
:
4. QHash
:
QMap
更快。5. QSet
:
比较说明:
特性 |
QList |
QVector |
QMap |
QHash |
QSet |
---|---|---|---|---|---|
Order(顺序) |
有序 (按插入顺序) |
有序 (按插入顺序,内存连续) |
有序 (按键排序,基于红黑树) |
无序 (顺序不确定,基于哈希表) |
无序 (顺序不确定,基于哈希表) |
Duplicates(重复元素) |
允许重复元素 |
允许重复元素 |
不允许重复键 (后插入的替换前一个) |
不允许重复键 (后插入的替换前一个) |
不允许重复元素 |
Implementation(实现) |
通常为指针数组或直接存储 (视元素大小) |
动态数组 (内存连续) |
红黑树 |
哈希表 |
通常为哈希表 |
Random Access(随机访问) |
较好 (通常接近 O(1)) |
优秀 (O(1)) |
O(log n) (按键) |
平均 O(1) (按键) |
平均 O(1) (检查元素是否存在) |
Insert/Delete (Middle)(中间插入/删除) |
较慢 (O(n)) |
较慢 (O(n)) |
O(log n) |
平均 O(1),最坏 O(n) |
平均 O(1),最坏 O(n) |
Insert/Delete (End)(末尾插入/删除) |
很快 (平均 O(1)) |
很快 (平均 O(1)) |
O(log n) |
平均 O(1),最坏 O(n) |
平均 O(1),最坏 O(n) |
Insert/Delete (Beginning)(开头插入/删除) |
很快 (平均 O(1)) |
较慢 (O(n)) |
O(log n) |
平均 O(1),最坏 O(n) |
平均 O(1),最坏 O(n) |
Lookup (by Key)(按键查找) |
O(n) (需要遍历) |
O(n) (需要遍历) |
O(log n) |
平均 O(1),最坏 O(n) |
N/A (用于检查元素是否存在) |
Memory Usage(内存使用) |
可能略高 (如果存储指针) |
通常更紧凑 (内存连续) |
可能较高 (红黑树节点开销) |
可能较高 (哈希表可能预留空间) |
可能较高 (哈希表可能预留空间) |
Key Requirement(键要求) |
N/A |
N/A |
键类型必须支持 < 运算符 (用于排序) |
键类型必须可哈希 (提供 qHash() 函数) |
元素类型必须可哈希 (提供 qHash() 函数) |
补充说明:
QList vs. QVector
QList 在开头操作(如 prepend())上更高效,但在随机访问和迭代上可能不如 QVector,因为后者内存连续,缓存性能更好。
如果需要频繁随机访问或高性能迭代,优先选择 QVector。
QMap vs. QHash
QMap 适合需要按键顺序访问的场景,而 QHash 在不关心顺序时提供更快的平均性能。
选择时可考虑:键顺序重要用 QMap,性能优先用 QHash。
QSet
与 QHash 的键集类似,专注于唯一元素管理和快速存在性检查。
QDate
提供日期操作QDate
类用于表示一个公历日期,包含年、月和日。它不包含任何时间信息。
主要特点:
创建 QDate
对象:
QDate(int year, int month, int day)
。QDate::fromJulianDay(qint64 julianDay)
。QDate::currentDate()
。访问日期组成部分:
year()
: 返回年份。month()
: 返回月份 (1-12)。day()
: 返回当月的天数 (1-31)。dayOfWeek()
: 返回星期几 (1=Monday, 7=Sunday)。dayOfYear()
: 返回一年中的第几天 (1-365 或 366)。日期有效性:
isValid()
: 检查日期是否有效(例如,日期是否存在于公历中)。日期比较:
==
, !=
, <
, >
, <=
, >=
) 比较两个 QDate
对象。日期操作:
addDays(int days)
: 返回一个新的 QDate
对象,表示当前日期加上指定的天数。addMonths(int months)
: 返回一个新的 QDate
对象,表示当前日期加上指定的月数。addYears(int years)
: 返回一个新的 QDate
对象,表示当前日期加上指定的年数。daysInMonth()
: 返回当前日期所在月份的天数。daysInYear()
: 返回当前日期所在年份的天数。daysTo(const QDate &other)
: 返回当前日期到另一个日期之间的天数差。日期格式化为字符串:
toString(const QString &format)
: 将日期格式化为指定的字符串。常用的格式包括:
"yyyy-MM-dd"
(例如: 2025-03-24)"dd.MM.yyyy"
(例如: 24.03.2025)"yyyyMMdd"
(例如: 20250324)"ddd MMMM d yyyy"
(例如: Mon March 24 2025)从字符串解析日期:
QDate::fromString(const QString &string, const QString &format)
: 从具有指定格式的字符串创建一个 QDate
对象。如果解析失败,返回一个无效的日期。QDate
核心代码示例:
#include
#include
int main() {
// ======================
// [1] 创建 QDate 对象
// ======================
QDate today = QDate::currentDate();
QDate specificDate(2024, 12, 25); // 特定日期
QDate invalidDate; // 无效日期
qDebug() << "Today's date:" << today.toString("yyyy-MM-dd");
qDebug() << "Specific date:" << specificDate.toString();
qDebug() << "Is specificDate valid?" << specificDate.isValid();
qDebug() << "Is invalidDate valid?" << invalidDate.isValid();
// ======================
// [2] 访问日期组成部分
// ======================
qDebug() << "Year of today:" << today.year();
qDebug() << "Month of today:" << today.month();
qDebug() << "Day of today:" << today.day();
qDebug() << "Day of week for today:" << today.dayOfWeek(); // 1 = Monday, 7 = Sunday
// ======================
// [3] 日期比较
// ======================
if (today > specificDate) {
qDebug() << "Today is after Christmas 2024.";
} else {
qDebug() << "Today is before or on Christmas 2024.";
}
// ======================
// [4] 日期操作
// ======================
QDate nextWeek = today.addDays(7);
qDebug() << "Date one week from today:" << nextWeek.toString();
// ======================
// [5] 从字符串解析日期
// ======================
QString dateString = "2026/01/01";
QDate parsedDate = QDate::fromString(dateString, "yyyy/MM/dd");
if (parsedDate.isValid()) {
qDebug() << "Parsed date:" << parsedDate.toString();
} else {
qDebug() << "Failed to parse date string.";
}
return 0;
}
// ======================
// console
// ======================
//Today's date: "2025-03-24"
//Specific date: "Wed Dec 25 2024"
//Is specificDate valid? true
//Is invalidDate valid? false
//Year of today: 2025
//Month of today: 3
//Day of today: 24
//Day of week for today: 1
//Today is after Christmas 2024.
//Date one week from today: "Mon Mar 31 2025"
//Parsed date: "Thu Jan 1 2026"
QTime
提供时间操作QTime
类用于表示一天中的时间,包含小时、分钟、秒和毫秒。它不包含任何日期信息。
主要特点:
创建 QTime
对象:
QTime(int hour, int minute, int second = 0, int msec = 0)
。QTime::currentTime()
。访问时间组成部分:
hour()
: 返回小时 (0-23)。minute()
: 返回分钟 (0-59)。second()
: 返回秒 (0-59)。msec()
: 返回毫秒 (0-999)。时间有效性:
isValid()
: 检查时间是否有效。时间比较:
==
, !=
, <
, >
, <=
, >=
) 比较两个 QTime
对象。时间操作:
addMSecs(int msecs)
: 返回一个新的 QTime
对象,表示当前时间加上指定的毫秒数。时间格式化为字符串:
toString(const QString &format)
: 将时间格式化为指定的字符串。常用的格式包括:
"hh:mm:ss"
(例如: 04:15:26)"HH:mm:ss.zzz"
(例如: 04:15:26.123)"h:mm ap"
(例如: 4:15 AM)从字符串解析时间:
QTime::fromString(const QString &string, const QString &format)
: 从具有指定格式的字符串创建一个 QTime
对象。如果解析失败,返回一个无效的时间。QTime
核心代码示例:
#include
#include
int main() {
// ======================
// [1] 创建 QTime 对象
// ======================
QTime now = QTime::currentTime(); // 当前时间
QTime specificTime(10, 30, 0); // 特定时间:10:30:00
QTime invalidTime; // 无效时间
qDebug() << "Current time:" << now.toString("hh:mm:ss.zzz"); // 输出当前时间,包含毫秒
qDebug() << "Specific time:" << specificTime.toString(); // 输出特定时间
qDebug() << "Is specificTime valid?" << specificTime.isValid(); // 检查特定时间是否有效
qDebug() << "Is invalidTime valid?" << invalidTime.isValid(); // 检查无效时间是否有效
// ======================
// [2] 访问时间组成部分
// ======================
qDebug() << "Hour:" << now.hour(); // 当前小时
qDebug() << "Minute:" << now.minute(); // 当前分钟
qDebug() << "Second:" << now.second(); // 当前秒
qDebug() << "Millisecond:" << now.msec(); // 当前毫秒
// ======================
// [3] 时间比较
// ======================
if (now > specificTime) {
qDebug() << "Current time is after 10:30 AM.";
} else {
qDebug() << "Current time is before or at 10:30 AM.";
}
// ======================
// [4] 时间操作
// ======================
QTime laterTime = now.addMSecs(1500); // 加 1.5 秒
qDebug() << "Time 1.5 seconds later:" << laterTime.toString("hh:mm:ss.zzz"); // 输出加 1.5 秒后的时间
// ======================
// [5] 从字符串解析时间
// ======================
QString timeString = "14:45"; // 时间字符串
QTime parsedTime = QTime::fromString(timeString, "hh:mm"); // 解析时间字符串
if (parsedTime.isValid()) {
qDebug() << "Parsed time:" << parsedTime.toString(); // 输出解析后的时间
} else {
qDebug() << "Failed to parse time string."; // 解析失败
}
return 0;
}
// ======================
// console
// ======================
//Current time: "19:27:50.886"
//Specific time: "10:30:00"
//Is specificTime valid? true
//Is invalidTime valid? false
//Hour: 19
//Minute: 27
//Second: 50
//Millisecond: 886
//Current time is after 10:30 AM.
//Time 1.5 seconds later: "19:27:52.386"
//Parsed time: "14:45:00"
QDateTime
日期和时间运算操作QDateTime 类结合了 QDate 和 QTime 的功能,用于表示一个特定的日期和时间点。它还可以处理时区信息(使用 QTimeZone 类)。
主要特点:
创建 QDateTime 对象:
默认构造函数: 创建一个无效的日期时间(QDateTime())。
从 QDate 和 QTime 对象创建: QDateTime(const QDate &date, const QTime &time, const QTimeZone &timeZone = QTimeZone::LocalTime) (Qt 6) 或 QDateTime(const QDate &date, const QTime &time) (Qt 5,默认本地时区)。
指定年、月、日、小时、分钟、秒、毫秒: Qt 5 中支持通过 QDate 和 QTime 间接实现;Qt 6 无直接构造函数,需组合使用其他方法。
获取当前系统日期和时间: QDateTime::currentDateTime() (本地时区) 和 QDateTime::currentDateTimeUtc() (UTC 时区)。
从 Unix 时间戳创建: QDateTime::fromSecsSinceEpoch(qint64 secs, const QTimeZone &timeZone) (自 1970-01-01 UTC 以来的秒数,默认本地时区) 和 QDateTime::fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone) (自 1970-01-01 UTC 以来的毫秒数,默认本地时区)。
访问日期和时间组成部分:
date(): 返回关联的 QDate 对象。
time(): 返回关联的 QTime 对象。
以及 year(), month(), day(), hour(), minute(), second(), msec() 等方法(返回 int 类型)。
日期时间有效性:
isValid(): 检查日期时间是否有效。
时区处理:
timeZone(): 返回当前关联的 QTimeZone 对象。
setTimeZone(const QTimeZone &timeZone): 设置新的时区。
toLocalTime(): 返回一个新的 QDateTime 对象,表示本地时区时间。
toUTC(): 返回一个新的 QDateTime 对象,表示 UTC 时区时间。
日期时间比较:
可以使用标准的比较运算符 (==, !=, <, >, <=, >=) 比较两个 QDateTime 对象。比较时会将对象转换为 UTC 时间点进行比较。
日期时间操作:
addDays(qint64 days), addMonths(int months), addYears(int years), addMSecs(qint64 msecs), addSecs(qint64 secs) 等: 返回一个新的 QDateTime 对象,表示当前日期时间加上指定的时间间隔。
secsTo(const QDateTime &other): 返回当前日期时间到另一个日期时间之间的秒数差(qint64 类型)。
msecsTo(const QDateTime &other): 返回当前日期时间到另一个日期时间之间的毫秒数差(qint64 类型)。
日期时间格式化为字符串:
toString(const QString &format): 将日期时间格式化为指定的字符串;若不指定格式,则使用默认本地化格式。常用格式包括:
"yyyy-MM-dd hh:mm:ss" (例如: 2025-03-24 04:15:26,12 小时制)
"yyyy-MM-ddTHH:mm:ssZ" (ISO 8601 格式,UTC 时间,例如: 2025-03-24T16:15:26Z)
"ddd MMMM d yyyy hh:mm:ss" (例如: Mon March 24 2025 04:15:26)
从字符串解析日期时间:
QDateTime::fromString(const QString &string, const QString &format): 从具有指定格式的字符串创建一个 QDateTime 对象,默认使用本地时区。若需指定时区,可在创建后使用 setTimeZone()。如果解析失败,返回一个无效的日期时间。
转换为 Unix 时间戳:
toSecsSinceEpoch(): 返回自 1970-01-01T00:00:00 UTC 以来的秒数(qint64 类型)。
toMSecsSinceEpoch(): 返回自 1970-01-01T00:00:00 UTC 以来的毫秒数(qint64 类型)。
QDateTime 核心代码示例:
#include
#include
#include
int main() {
// ======================
// [1] 创建 QDateTime 对象
// ======================
QDateTime now = QDateTime::currentDateTime(); // 获取当前本地日期和时间
QDateTime specificDateTime(QDate(2024, 12, 25), QTime(0, 0, 0)); // 创建一个特定的日期和时间:2024年12月25日 00:00:00
QDateTime utcDateTime = QDateTime::currentDateTimeUtc(); // 获取当前 UTC 日期和时间
qDebug() << "Current local date and time:" << now.toString("yyyy-MM-dd hh:mm:ss.zzz"); // 输出当前本地日期和时间
qDebug() << "Christmas 2024:" << specificDateTime.toString(); // 输出圣诞节日期和时间
qDebug() << "Current UTC date and time:" << utcDateTime.toString("yyyy-MM-dd hh:mm:ss UTC"); // 输出当前 UTC 日期和时间
// ======================
// [2] 访问日期和时间组成部分
// ======================
qDebug() << "Date part of now:" << now.date().toString(); // 获取日期部分并格式化为字符串
qDebug() << "Time part of now:" << now.time().toString(); // 获取时间部分并格式化为字符串
qDebug() << "Year:" << now.date().year(); // 获取年份
qDebug() << "Month:" << now.date().month(); // 获取月份
qDebug() << "Day:" << now.date().day(); // 获取日
qDebug() << "Hour:" << now.time().hour(); // 获取小时
qDebug() << "Minute:" << now.time().minute(); // 获取分钟
qDebug() << "Second:" << now.time().second(); // 获取秒
qDebug() << "Millisecond:" << now.time().msec(); // 获取毫秒
// ======================
// [3] 时区处理
// ======================
QTimeZone easternTime("America/New_York"); // 创建一个纽约时区对象
QDateTime newYorkDateTime = QDateTime::currentDateTime(); // 获取当前本地日期和时间
newYorkDateTime.setTimeZone(easternTime); // 设置为纽约时区
qDebug() << "Current date and time in New York:" << newYorkDateTime.toString("yyyy-MM-dd hh:mm:ss zzz"); // 输出纽约时区的日期和时间
qDebug() << "New York time converted to UTC:" << newYorkDateTime.toUTC().toString("yyyy-MM-dd hh:mm:ss UTC"); // 将纽约时间转换为 UTC 并输出
// ======================
// [4] 日期时间比较
// ======================
if (now > specificDateTime) {
qDebug() << "Current time is after Christmas 2024.";
} else {
qDebug() << "Current time is before or on Christmas 2024.";
}
// ======================
// [5] 日期时间操作
// ======================
QDateTime nextHour = now.addSecs(3600); // 计算一小时后的日期和时间 (1 小时 = 3600 秒)
qDebug() << "Date and time one hour later:" << nextHour.toString("yyyy-MM-dd hh:mm:ss"); // 输出一小时后的日期和时间
// ======================
// [6] 从字符串解析日期时间
// ======================
QString dateTimeString = "2027-07-15 10:00:00"; // 日期时间字符串
QDateTime parsedDateTime = QDateTime::fromString(dateTimeString, "yyyy-MM-dd hh:mm:ss"); // 使用指定格式解析日期时间字符串
if (parsedDateTime.isValid()) {
qDebug() << "Parsed date and time:" << parsedDateTime.toString(); // 输出解析后的日期和时间
} else {
qDebug() << "Failed to parse date and time string."; // 解析失败
}
// ======================
// [7] 转换为 Unix 时间戳
// ======================
qDebug() << "Current time as Unix timestamp (seconds since epoch):" << now.toSecsSinceEpoch(); // 输出当前时间的 Unix 时间戳(秒)
return 0;
}
// ======================
// console
// ======================
//Current local date and time: "2025-03-24 20:15:05.317"
//Christmas 2024: "Wed Dec 25 00:00:00 2024"
//Current UTC date and time: "2025-03-24 12:15:05 UTC"
//Date part of now: "Mon Mar 24 2025"
//Time part of now: "20:15:05"
//Year: 2025
//Month: 3
//Day: 24
//Hour: 20
//Minute: 15
//Second: 5
//Millisecond: 317
//Current date and time in New York: "2025-03-24 20:15:05 320"
//New York time converted to UTC: "2025-03-25 00:15:05 UTC"
//Current time is after Christmas 2024.
//Date and time one hour later: "2025-03-24 21:15:05"
//Parsed date and time: "Thu Jul 15 10:00:00 2027"
//Current time as Unix timestamp (seconds since epoch): 1742818505
QFile
QFile
类用于文件的打开、读取、写入和关闭。它支持文本和二进制模式。
QDir
QDir
类提供了对文件系统目录的操作,如列出目录内容、创建目录和删除目录等。
QFileInfo
QFileInfo
提供文件和目录的元数据(如文件大小、修改时间、权限等)。
QTextStream
QTextStream
用于文本文件的读取和写入,支持 UTF-8、UTF-16 等多种编码格式。
QDataStream
QDataStream
用于二进制数据的序列化和反序列化,常用于高效地存储和传输数据。
QBuffer
基于 QByteArray 的 I/O 接口。
QEvent
QEvent
是 Qt 的事件类,用于表示用户交互、系统事件等。
QObject
QObject
是 Qt 所有对象的基类。它支持信号和槽机制、事件处理等功能。
QTimer
QTimer
类用于定时任务,它提供定时器功能,允许在指定时间间隔后触发某个操作。
QCoreApplication
QCoreApplication
是应用程序核心类,负责启动事件循环和管理应用程序的生命周期。
QEventLoop
事件循环管理类。
QMetaObject:
支持元对象系统,提供动态方法调用和属性访问。
QThread
QThread
提供了线程管理的功能,允许开发者创建和管理线程。
同步工具QMutex、QReadWriteLock、QSemaphore、QWaitCondition
QMutex:互斥锁,确保线程安全。
QReadWriteLock:读写锁,适用于多读少写场景。
QSemaphore:信号量,控制资源访问。
QWaitCondition:线程等待条件。
QThreadPool 和 QRunnable
线程池管理。
原子操作
QAtomicInt 和 QAtomicPointer 提供线程安全的原子操作。
QtConcurrent
QtConcurrent
提供了对并行计算的高层次抽象。它允许开发者简洁地进行多线程任务处理,如并行遍历、过滤等操作。
QLocale
QLocale
类用于管理语言、区域设置等本地化信息,能够根据不同的区域设置显示日期、时间、数字等格式。
QTranslator
QTranslator
用于加载翻译文件,以便将应用程序界面翻译成不同的语言。
QProcess
QProcess
类用于启动外部进程并与其进行交互,支持进程输入输出流的管理。
QLocalSocket, QLocalServer
QLocalSocket
: 本地套接字,用于与本地进程进行通信。
QLocalServer
: 本地服务器,用于监听来自其他进程的连接请求。
QSharedMemory
QSharedMemory
提供了进程间共享内存的访问,允许多个进程共享同一块内存区域。
QPluginLoader
QPluginLoader
用于加载动态插件,使得应用程序能够在运行时加载和卸载插件。
QFactoryInterface
QFactoryInterface
是插件接口,插件可以实现特定功能,并通过该接口供应用程序使用。
QTextCodec
QTextCodec
用于文本编码和解码,支持多种字符集,如 UTF-8、GBK、ISO-8859-1 等。
QLibrary
QLibrary
用于加载动态链接库,并提供访问其导出函数的能力,支持跨平台的动态库管理。
qAbs
计算绝对值。
qDebug、qWarning、qCritical
调试和日志输出。
qInstallMsgHandler
安装消息处理程序。
qVersion
返回 Qt 版本。
qRegisterResourceData 和 qUnregisterResourceData:
资源数据管理。
QUrl
URL 解析和生成。
QRandomGenerator
线程安全的随机数生成。
QCryptographicHas
加密哈希类(如 MD5、SHA-256)。
QJsonDocument、QJsonArray、QJsonObject、QJsonValue
JSON 处理:
QRegularExpression
Perl 兼容的正则表达式。
QSettings
跨平台应用设置存储。
QStandardPaths
返回标准目录路径。
QDebug
调试输出工具。
QCalendar
支持多种日历系统。
QDeadlineTimer
截止时间管理。