当前位置: 首页 > news >正文

Qt开发:QVariant的使用

文章目录

    • 一、QVariant介绍
    • 二、QVariant 的基本使用
    • 三、QVariant 作为容器(QVariantList / QVariantMap)
    • 四、QVariant中常用的静态函数
    • 五、 QVariant存储和传输自定义类型
    • 六、QVariant的典型应用场景

一、QVariant介绍

QVariant 是 Qt 提供的一个通用数据类型,它可以存储多种类型的数据,包括基本类型(如 int、double、QString)、复杂类型(如 QByteArray、QDateTime)、以及自定义类型。

二、QVariant 的基本使用

QVariant 的创建
可以直接通过构造函数存储不同类型的数据:

#include <QApplication>
#include <QVariant>
#include <QString>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QVariant v1(42);               // 存储 int
    QVariant v2(3.14);             // 存储 double
    QVariant v3(QString("Hello")); // 存储 QString
    QVariant v4(QByteArray("data")); // 存储 QByteArray

    qDebug() << v1.toInt();    // 42
    qDebug() << v2.toDouble(); // 3.14
    qDebug() << v3.toString(); // "Hello"
    qDebug() << v4.toByteArray(); // "data"

    return a.exec();
}

输出结果:
在这里插入图片描述
QMap与QVariant的结合使用:

include <QApplication>
#include <QVariant>
#include <QDebug>
#include <QMap>
#include <QString>
#include <QColor>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QMap<QString, QVariant> qMap;
    qMap["int"] = 200; // 整型
    qMap["double"] = 99.99; // 浮点型
    qMap["string"] = "Good"; // 字符串
    qMap["color"] = QColor(255, 255, 0);

    // 输出:转换函数来处理
    qDebug() << qMap["int"] << "," <<  qMap["int"].toInt();
    qDebug() << qMap["double"] << "," << qMap["double"].toDouble();
    qDebug() << qMap["string"] << "," << qMap["string"].toString();
    qDebug() << qMap["color"] << "," << qMap["color"].value<QColor>();

    return a.exec();
}

输出结果:
在这里插入图片描述
QStringList与QVariant的结合使用:

#include <QApplication>
#include <QVariant>
#include <QString>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 创建一个字符串列表:QStringList
    QStringList qSList;
    qSList << "A" << "B" << "C" << "D" << "E" << "F";

    QVariant qVlist(qSList); // 将列表存储在一个QVariant变量中
    if (qVlist.type() == QVariant::StringList) {
        for (const auto &value : qVlist.toStringList()) {
            qDebug() << value; //输出列表数据信息
        }
    }

    return a.exec();
}

输出结果:
在这里插入图片描述

检查类型
使用 typeName() 或 typeId() 方法来检查 QVariant 存储的数据类型:

QVariant v(123.456);
qDebug() << "Type:" << v.typeName(); // "double"

// 判断是否可以转换为特定类型
if (v.canConvert<double>()) {
   qDebug() << "Can convert to double";
}

QVariant 类型转换
QVariant 提供 toType() 方法来转换数据:

QVariant v("123");

int intValue = v.toInt();       // 123
double doubleValue = v.toDouble(); // 123.0
QString strValue = v.toString(); // "123"

三、QVariant 作为容器(QVariantList / QVariantMap)

QVariantList 相当于 QList,可存储不同类型的数据:

QVariantList list;
list << 10 << 3.14 << "Qt" << QVariant(QDateTime::currentDateTime());

for (const QVariant &item : list) {
    qDebug() << item;
}

QVariantMap 类似于 QMap<QString, QVariant>,可以用作字典:

QVariantMap map;
map["name"] = "Alice";
map["age"] = 25;
map["height"] = 1.68;

qDebug() << map["name"].toString();   // "Alice"
qDebug() << map["age"].toInt();       // 25
qDebug() << map["height"].toDouble(); // 1.68

四、QVariant中常用的静态函数

static QVariant fromStdVariant(const std::variant<Types...> &value);

该方法用于将 std::variant<Types…> 转换为 QVariant,使其可以与 Qt 类型系统兼容。可以存储多种类型,并在 Qt 组件(如 QSettings、QAbstractItemModel)中使用。

#include <QVariant>
#include <QDebug>
#include <variant>

int main() {
    std::variant<int, double, QString> myVariant = 42;
    QVariant qvar = QVariant::fromStdVariant(myVariant);
    qDebug() << "Stored QVariant:" << qvar; // 42

    myVariant = 3.14;
    qvar = QVariant::fromStdVariant(myVariant);
    qDebug() << "Stored QVariant:" << qvar.toDouble(); // 3.14

    myVariant = QString("Hello Qt");
    qvar = QVariant::fromStdVariant(myVariant);
    qDebug() << "Stored QVariant:" << qvar.toString(); // "Hello Qt"
}

输出结果:
在这里插入图片描述
注意:

  • std::variant 只能存储其中一个类型的值,而 QVariant 可灵活存储任意支持的类型。
  • fromStdVariant() 适用于 C++17 及以上的标准。
template<typename T>
static QVariant fromValue(const T &value);

注意:

  • 该方法用于将任意类型的值包装到 QVariant 中。
  • 适用于 Qt 内置类型以及用户自定义类型(需 Q_DECLARE_METATYPE)。
    通过 QVariant::value() 获取存储的值。
#include <QVariant>
#include <QDebug>

int main() {
    QVariant qv1 = QVariant::fromValue(123);
    QVariant qv2 = QVariant::fromValue(3.14);
    QVariant qv3 = QVariant::fromValue(QString("Qt"));

    qDebug() << qv1.toInt();     // 123
    qDebug() << qv2.toDouble();  // 3.14
    qDebug() << qv3.toString();  // "Qt"
}
static QVariant::Type nameToType(const char *name);

注意:

  • 该方法用于将 类型名称(字符串)转换为 QVariant::Type 枚举值;仅支持 QVariant 内置类型,不支持自定义类型。
  • nameToType() 主要用于动态类型转换,如 JSON 解析或配置解析。
#include <QVariant>
#include <QDebug>

int main() {
    QVariant::Type type1 = QVariant::nameToType("int");
    QVariant::Type type2 = QVariant::nameToType("QString");
    QVariant::Type type3 = QVariant::nameToType("double");

    qDebug() << type1; // QVariant::Int
    qDebug() << type2; // QVariant::String
    qDebug() << type3; // QVariant::Double
}

输出结果:
在这里插入图片描述

static const char *typeToName(int typeId);

注意:

  • 该方法用于 将 QVariant::Type 枚举值转换回字符串名称。
  • typeToName() 可用于调试 QVariant 存储的类型,适用于反射机制或 QMetaType 相关操作。
    也可用于 QMetaType 类型 ID 获取类型名称。
#include <QApplication>
#include <QVariant>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    qDebug() << QVariant::typeToName(QVariant::Int);       // "int"
    qDebug() << QVariant::typeToName(QVariant::String);    // "QString"
    qDebug() << QVariant::typeToName(QVariant::Double);    // "double"

    return a.exec();
}

输出结果:
在这里插入图片描述
结合 QMetaType使用:

#include <QApplication>
#include <QVariant>
#include <QDebug>
#include <QMetaType>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    int typeId = QMetaType::QString;
    qDebug() << "Type ID:" << typeId;
    qDebug() << "Type Name:" << QVariant::typeToName(typeId); // "QString"


    return a.exec();
}

输出结果:
在这里插入图片描述

五、 QVariant存储和传输自定义类型

注册自定义类型
如果需要在 QVariant 中存储自定义类型,需要使用 Q_DECLARE_METATYPE 并注册:

#include <QApplication>
#include <QVariant>
#include <QDebug>

struct Person {
    QString name;
    int age;
};
Q_DECLARE_METATYPE(Person) // 声明元类型

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    qRegisterMetaType<Person>("Person"); // 注册自定义类型

    Person p = {"John Doe", 30};
    QVariant v = QVariant::fromValue(p);

    // 判断是否可以转换操作
    if (v.canConvert<Person>()) {
        Person p2 = v.value<Person>(); // 取出数据
        qDebug() << p2.name << p2.age; // 输出: "John Doe 30"

        Person p3 = qvariant_cast<Person>(v);
        qDebug() << p3.name << p3.age; // 输出: "John Doe 30"
    }

    return a.exec();
}

输出结果:
在这里插入图片描述

六、QVariant的典型应用场景

QSettings配置存储

QSettings settings("MyApp", "Config");
settings.setValue("username", "admin");
settings.setValue("volume", 50);

QString username = settings.value("username").toString();
int volume = settings.value("volume").toInt();

QAbstractItemModel数据存储

QVariant data = model->data(index, Qt::DisplayRole);
if (data.isValid()) {
    qDebug() << data.toString();
}

设置动态属性

QWidget widget;
widget.setProperty("customValue", 123);
int value = widget.property("customValue").toInt();

相关文章:

  • 精选前端面试题(持续更新中ing)
  • 初级:异常处理面试题深度解析
  • Uni-Mol:一个通用的三维分子表征学习框架
  • 蓝桥杯——嵌入式学习日记
  • 深度剖析:C++ 版本高斯混合模型在高维数据上提速的核心因素
  • 国际数字影像产业园官网:文创产业前沿资讯汇聚地
  • 硅基流动:推理加速,告别“服务器繁忙,请稍后再试”
  • 模型解释与可解释AI实战
  • 涨薪技术|k8s设计原理
  • Python高级——实现简单名片管理系统
  • 【sql靶场】过滤绕过第26-27a关保姆级教程
  • AVL(平衡二叉树)
  • 【前端】 el-form-item的label由于字数多自行换行调整
  • 常考计算机操作系统面试习题(二)(下)
  • Spring Boot深度解析:从核心原理到最佳实践
  • C语言字符函数,字符串函数以及内存函数
  • 腾讯云大模型知识引擎x deepseek:打造智能服装搭配新体验
  • Kubernetes 故障排查指南
  • Linux启动之__vet_atags
  • 23种设计模式-外观(Facade)设计模式
  • 全国游泳冠军赛:孙杨、潘展乐同进400自决赛,今晚将正面对决
  • 女子七年后才知银行卡被盗刷18万元,警方抓获其前男友
  • 新华时评:让医德医风建设为健康中国护航
  • 上海高院与上海妇联签协议,建立反家暴常态化联动协作机制
  • “一百零一个愿望——汉字艺术展”亮相意大利威尼斯
  • 哪种“网红减肥法”比较靠谱?医学专家和运动专家共同解答