文章目录
一、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();