Qt_QVariant

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),需要满足两个条件:

  1. 有默认构造函数和拷贝构造函数

  2. 使用 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~

相关推荐
fanruitian1 小时前
python else用法
开发语言·python
FRing031 小时前
JavaScript入门到精通二十六(变量提升、函数剩余参数、展开运算符、ES6箭头函数)
开发语言·前端·javascript·es6·箭头函数
云深麋鹿1 小时前
C++ | 基于红黑树实现mymap与myset
开发语言·c++
weixin_417396832 小时前
桌面云终端PXE启动失败怎么排查?从DHCP Option到镜像下发
开发语言·前端·php·技术·酒店·综合布线·弱电
某不知名網友2 小时前
ROS2进阶:服务通信、自定义SRV接口、参数服务器与基于服务的参数通信详解
java·开发语言·microsoft
java_nnnn3 小时前
LeetCode刷题滑动窗口(水果成篮+找到字符串中所有字母的异位词)Java
java·开发语言·leetcode
qetfw3 小时前
Bash 字符串处理:参数展开、序列与脚本执行方式
linux·开发语言·chrome·bash
小羊没烦恼!3 小时前
异步编程:线程概述及使用
java·开发语言·mysql·算法·c#
学Linux的语莫3 小时前
python中类的常见写法
开发语言·python·状态模式
需要8263 小时前
容器化 Java:镜像瘦身与 JVM 容器感知(cgroup)
java·开发语言·jvm