Qt_QVariant
QVariant 是 Qt 框架中一个非常实用的类,它类似于 C++ 的 union,但功能更强大,可以安全地存储几乎所有常见的 Qt 数据类型和 C++ 基本类型。
为什么需要 QVariant
C++ 原生的 union 不允许包含有非默认构造函数或析构函数的类型,因此大多数 Qt 类无法放入 union 中。QVariant 解决了这个问题,广泛应用于 QObject::property()、数据库操作、信号槽传参等场景。
QVariant支持的类型
Variant 默认支持以下类型:
- C++ 基本类型:int、uint、bool、double、float、qlonglong、qulonglong
- Qt 核心类型:QString、QByteArray、QChar、QStringList、QDate、QTime、QDateTime、QUrl、QUuid
- 几何类型:QPoint、QPointF、QSize、QSizeF、QRect、QRectF、QLine、QLineF
- 容器类型:
QList<QVariant>(即 QVariantList)、QMap<QString, QVariant>(即 QVariantMap)、QHash<QString, QVariant>(即 QVariantHash) - JSON 类型:QJsonValue、QJsonObject、QJsonArray、QJsonDocument
- GUI 类型(需通过
value<T>() 访问):QColor、QFont、QPixmap、QBrush、QPen 等
基本用法
存储数据
cpp
// 通过构造函数
QVariant v1(123);
QVariant v2("hello");
QVariant v3(3.14);
// 通过 setValue()
QVariant v4;
v4.setValue(42);
// 通过静态方法 fromValue()
QVariant v5 = QVariant::fromValue(100);
读取数据
cpp
QVariant v(123);
int i = v.toInt(); // i = 123
QString s = v.toString(); // s = "123"
double d = v.toDouble(); // d = 123.0
bool b = v.toBool(); // b = true
// 模板方式(通用)
int val = v.value<int>();
类型判断与转换
cpp
QVariant v(42);
v.typeName(); // 返回 "int"
v.userType(); // 返回 QMetaType::Int
v.canConvert<QString>(); // 返回 true
v.canConvert<QColor>(); // 返回 false
// 强制转换
v.convert(QMetaType::QString); // 转换后存储 "42"
自定义类型的使用
对于自定义类型(struct 或 class),需要满足两个条件:
-
有默认构造函数和拷贝构造函数
-
使用 Q_DECLARE_METATYPE() 宏注册类型
cpp
// 头文件中定义并注册
struct Student {
int id;
QString name;
int age;
};
Q_DECLARE_METATYPE(Student)
// 使用
Student stu;
stu.id = 1;
stu.name = "张三";
stu.age = 18;
// 存储
QVariant var = QVariant::fromValue(stu);
// 读取
if (var.canConvert<Student>()) {
Student s = var.value<Student>();
qDebug() << s.name << s.age;
}
存储指针
cpp
// 保存
QVariant var = QVariant::fromValue((void*)somePointer);
// 获取
SomeType* ptr = (SomeType*)var.value<void*>();
处理不支持的基本类型
对于 short、char 等 QVariant 没有专用构造函数的类型,可以先转为 int 存取:
cpp
// char -> QVariant
QVariant var = 'B'; // 实际存储为 int(66)
char c = (char)var.toInt(); // 取出后转回 char
// short -> QVariant
short s = 12;
QVariant var2 = s; // 实际存储为 int(12)
short s2 = (short)var2.toInt();
常用 API 速查
| 方法 | 说明 |
|---|---|
setValue(const T &) |
存储值 |
fromValue(const T &) |
静态方法,创建含值的 QVariant |
toT() |
转换为具体类型(如 toInt()、toString()) |
value<T>() |
模板方式取值,适用于自定义类型 |
canConvert<T>() |
判断能否转换为类型 T |
convert(int) |
强制类型转换 |
type() / userType() |
获取存储类型 |
typeName() |
获取类型名称字符串 |
isNull() |
是否为空值 |
isValid() |
是否为有效类型 |
clear() |
清空为 UnknownType |
end~