Qt开发:QVariant的使用

发布于:2025-03-25 ⋅ 阅读:(33) ⋅ 点赞:(0)

一、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();