4.3 QVariant 类功能详解、应用示例与类型转换

4.3 QVariant 类功能详解、应用示例与类型转换

本系列博文旨在为 Qt 开发者提供一站式的学习资源,内容涵盖从基础控件使用到高级特性如多线程与图形编程等。如果你是第一次来到这里,可以先点击Qt 编程专栏简介,一起深入探索 Qt 的各个方面。

QVariant 是 Qt 提供的一个非常强大的类,它用于存储不同类型的数据,并支持多种类型之间的转换。QVariant 类被广泛应用于 Qt 的模型-视图框架、信号-槽机制、数据库操作、表格等场景中。它能将多种类型的数据封装到一个单一的对象中,并提供丰富的接口进行访问和类型转换。

QVariant 类功能概述
功能 描述
构造函数 支持从基本数据类型、QStringQByteArrayQDate 等多种类型初始化。
数据存储与访问 提供存储和访问不同类型数据的方法,如 toInt()toString()toBool() 等。
类型信息 提供获取当前存储数据类型的接口,如 type()canConvert() 等。
类型转换 支持数据类型的转换,可以通过 toType() 方法进行类型转换,支持 QVariant::toString()QVariant::toInt() 等。
比较操作 提供比较方法(如 ==!=<> 等)来比较 QVariant 对象。
持久化与序列化 可以方便地与 Qt 的模型-视图框架、数据库进行交互,通过 QVariantMap 等数据结构进行存储和管理。
常用接口
接口 功能描述 示例
bool canConvert(QMetaType type) const 判断当前 QVariant 对象是否能转换为指定的 QMetaType 类型。 QVariant v(42); bool canConvert = v.canConvert(QMetaType::fromType());
bool canConvert() const 判断当前 QVariant 是否可转换为其自身类型。 QVariant v(42); bool canConvert = v.canConvert();
bool canView() const 判断当前 QVariant 是否可以作为视图类型存在。 QVariant v(42); bool canView = v.canView();
void clear() 清空 QVariant 中存储的数据。 QVariant v(42); v.clear();
const void *constData() const 返回 QVariant 内部数据的常量指针。 QVariant v("Hello"); const void* data = v.constData();
bool convert(QMetaType targetType) 将当前 QVariant 对象转换为目标类型。 QVariant v(42); bool success = v.convert(QMetaType::fromType());
void *data() 返回 QVariant 内部数据的指针。 QVariant v("Hello"); void* data = v.data();
const void *data() const 返回 QVariant 内部数据的常量指针。 QVariant v("Hello"); const void* data = v.data();
bool isNull() const 判断 QVariant 是否为空(即没有有效数据)。 QVariant v; bool isNull = v.isNull();
bool isValid() const 判断 QVariant 是否有效。 QVariant v(42); bool isValid = v.isValid();
QMetaType metaType() const 获取当前 QVariant 对象的类型信息。 QVariant v(42); QMetaType type = v.metaType();
void setValue(T &&value) 设置 QVariant 的值,支持右值引用。 QVariant v; v.setValue(42);
void setValue(const QVariant &value) 设置 QVariant 的值,支持拷贝。 QVariant v; v.setValue(QVariant(42));
void setValue(QVariant &&value) 设置 QVariant 的值,支持右值引用赋值。 QVariant v; v.setValue(QVariant(42));
void swap(QVariant &other) 交换当前 QVariant 对象与另一个 QVariant 的值。 QVariant v1(42), v2("Hello"); v1.swap(v2);
QBitArray toBitArray() const QVariant 转换为 QBitArray QVariant v(1); QBitArray arr = v.toBitArray();
bool toBool() const QVariant 转换为布尔值。 QVariant v(true); bool b = v.toBool();
QByteArray toByteArray() const QVariant 转换为 QByteArray QVariant v("Hello"); QByteArray ba = v.toByteArray();
QChar toChar() const QVariant 转换为单一字符。 QVariant v("H"); QChar ch = v.toChar();
QDate toDate() const QVariant 转换为 QDate QVariant v("2024-11-01"); QDate date = v.toDate();
QDateTime toDateTime() const QVariant 转换为 QDateTime QVariant v("2024-11-01 12:00:00"); QDateTime dt = v.toDateTime();
double toDouble(bool *ok = nullptr) const QVariant 转换为 double,并返回是否成功。 QVariant v(42.5); double d = v.toDouble();
QEasingCurve toEasingCurve() const QVariant 转换为 QEasingCurve QVariant v(QEasingCurve::InOutQuad); QEasingCurve curve = v.toEasingCurve();
float toFloat(bool *ok = nullptr) const QVariant 转换为 float,并返回是否成功。 QVariant v(42.5f); float f = v.toFloat();
QHash toHash() const QVariant 转换为 QHash QVariant v(QHash{{"key", 42}}); QHash hash = v.toHash();
int toInt(bool *ok = nullptr) const QVariant 转换为 int,并返回是否成功。 QVariant v(42); int i = v.toInt();
QJsonArray toJsonArray() const QVariant 转换为 QJsonArray QVariant v(QJsonArray{1, 2, 3}); QJsonArray jsonArray = v.toJsonArray();
QJsonDocument toJsonDocument() const QVariant 转换为 QJsonDocument QVariant v(QJsonDocument(QJsonObject{{"key", 42}})); QJsonDocument jsonDoc = v.toJsonDocument();
QJsonObject toJsonObject() const QVariant 转换为 QJsonObject QVariant v(QJsonObject{{"key", 42}}); QJsonObject jsonObject = v.toJsonObject();
QJsonValue toJsonValue() const QVariant 转换为 QJsonValue QVariant v(42); QJsonValue jsonValue = v.toJsonValue();
QLine toLine() const QVariant 转换为 QLine QVariant v(QLine(0, 0, 10, 10)); QLine line = v.toLine();
QLineF toLineF() const QVariant 转换为 QLineF QVariant v(QLineF(0, 0, 10.5, 10.5)); QLineF lineF = v.toLineF();
QList toList() const QVariant 转换为 QList QVariant v(QList{1, 2, 3}); QList list = v.toList();
QLocale toLocale() const QVariant 转换为 QLocale QVariant v(QLocale::English); QLocale locale = v.toLocale();
qlonglong toLongLong(bool *ok = nullptr) const QVariant 转换为 qlonglong,并返回是否成功。 QVariant v(1234567890LL); qlonglong ll = v.toLongLong();
QMap toMap() const QVariant 转换为 QMap QVariant v(QMap{{"key", 42}}); QMap map = v.toMap();
QModelIndex toModelIndex() const QVariant 转换为 QModelIndex QVariant v(QModelIndex()); QModelIndex modelIndex = v.toModelIndex();
QPersistentModelIndex toPersistentModelIndex() const QVariant 转换为 QPersistentModelIndex QVariant v(QPersistentModelIndex()); QPersistentModelIndex persistentModelIndex = v.toPersistentModelIndex();
QPoint toPoint() const QVariant 转换为 QPoint QVariant v(QPoint(10, 20)); QPoint point = v.toPoint();
QPointF toPointF() const QVariant 转换为 QPointF QVariant v(QPointF(10.5, 20.5)); QPointF pointF = v.toPointF();
qreal toReal(bool *ok = nullptr) const QVariant 转换为 qreal,并返回是否成功。 QVariant v(42.5); qreal real = v.toReal();
QRect toRect() const QVariant 转换为 QRect QVariant v(QRect(0, 0, 10, 10)); QRect rect = v.toRect();
QRectF toRectF() const QVariant 转换为 QRectF QVariant v(QRectF(0, 0, 10.5, 10.5)); QRectF rectF = v.toRectF();
QRegularExpression toRegularExpression() const QVariant 转换为 QRegularExpression QVariant v(QRegularExpression("\\d+")); QRegularExpression regex = v.toRegularExpression();
QSize toSize() const QVariant 转换为 QSize QVariant v(QSize(10, 20)); QSize size = v.toSize();
QSizeF toSizeF() const QVariant 转换为 QSizeF QVariant v(QSizeF(10.5, 20.5)); QSizeF sizeF = v.toSizeF();
QString toString() const QVariant 转换为 QString QVariant v("Hello"); QString str = v.toString();
QStringList toStringList() const QVariant 转换为 QStringList QVariant v(QStringList{"Hello", "World"}); QStringList strList = v.toStringList();
QTime toTime() const QVariant 转换为 QTime QVariant v("12:30:00"); QTime time = v.toTime();
uint toUInt(bool *ok = nullptr) const QVariant 转换为 uint,并返回是否成功。 QVariant v(42); uint ui = v.toUInt();
qulonglong toULongLong(bool *ok = nullptr) const QVariant 转换为 qulonglong,并返回是否成功。 QVariant v(1234567890ULL); qulonglong ull = v.toULongLong();
QUrl toUrl() const QVariant 转换为 QUrl QVariant v(QUrl("https://www.qt.io")); QUrl url = v.toUrl();
QUuid toUuid() const QVariant 转换为 QUuid QVariant v(QUuid::createUuid()); QUuid uuid = v.toUuid();
int typeId() const 获取 QVariant 存储数据的类型ID。 QVariant v(42); int typeId = v.typeId();
const char *typeName() const 获取 QVariant 存储数据的类型名称。 QVariant v(42); const char* typeName = v.typeName();
int userType() const 获取用户自定义类型的 ID。 QVariant v(QMetaType::fromType()); int userType = v.userType();
T value() const 获取 QVariant 中存储的值,返回类型为 T QVariant v(42); int value = v.value();
T view() 返回对存储数据的视图,通常用于常量引用类型。 QVariant v(42); int view = v.view();

模拟案例:QVariant 的应用

以下是一个使用 QVariant 存储并转换不同数据类型的示例:

#include 
#include 
#include 

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

    // 使用 QVariant 存储整数
    QVariant var1 = 42;
    qDebug() << "var1 (int):" << var1.toInt();

    // 使用 QVariant 存储字符串
    QVariant var2 = "Hello, QVariant!";
    qDebug() << "var2 (QString):" << var2.toString();

    // 转换 QVariant 存储的数据类型
    QVariant var3 = 42.5;
    qDebug() << "var3 (double):" << var3.toDouble();

    // 判断是否可以转换类型
    qDebug() << "Can var1 convert to QString?" << var1.canConvert(QMetaType::fromType<QString>());
    
    // 使用 setValue 设置新的值
    var3.setValue(100);
    qDebug() << "After setValue, var3 (int):" << var3.toInt();

    return a.exec();
}
常见数据类型与转换

QVariant 支持许多常见的数据类型,可以存储和转换以下类型的数据:

  • 基础类型intfloatdoubleboolcharlongshort 等。

  • Qt 类型QStringQDateQTimeQDateTimeQByteArrayQColorQPointQSizeQRect 等。

  • STL 类型std::stringstd::vector 等。

  • 自定义类型:可以通过 Q_DECLARE_METATYPE 声明自定义类型以支持存储到 QVariant 中。

QVariant 典型应用示例
  1. 创建 QVariant 对象并访问数据
QVariant variant1 = 42;           // 存储整数
QVariant variant2 = 3.14;         // 存储浮点数
QVariant variant3 = "Hello";      // 存储字符串

int intValue = variant1.toInt(); // 将 QVariant 转换为 int 类型
double doubleValue = variant2.toDouble(); // 转换为 double 类型
QString stringValue = variant3.toString(); // 转换为 QString 类型

qDebug() << intValue << doubleValue << stringValue;
// 输出:42 3.14 Hello
  1. 通过 QVariant 存储 Qt 类型
QVariant variantDate = QDate(2024, 11, 27); // 存储 QDate
QVariant variantColor = QColor(255, 0, 0);  // 存储 QColor

QDate date = variantDate.toDate();
QColor color = variantColor.value<QColor>();

qDebug() << date.toString() << color.name();
// 输出:2024-11-27 #ff0000
  1. QVariant 与模型-视图框架

QVariant 在 Qt 的模型-视图框架中起着重要作用,数据通常通过 QVariant 来封装并传递。

QVariant variantData = model->data(index);
if (variantData.canConvert<int>()) {
  int value = variantData.toInt();
  qDebug() << "Data is of type int:" << value;
}
  1. 类型转换

QVariant 支持多种类型转换,可以通过 toType() 方法进行数据类型的转换。

QVariant variantInt = 100;
QString stringValue = variantInt.toString();  // 将 int 转换为 QString
qDebug() << stringValue; // 输出:100
  1. 比较两个 QVariant 对象

QVariant 提供了方便的比较运算符来比较两个对象是否相等。

QVariant variant1 = 100;
QVariant variant2 = 100;
QVariant variant3 = 200;

if (variant1 == variant2) {
  qDebug() << "variant1 is equal to variant2";  // 输出:variant1 is equal to variant2
}

if (variant1 != variant3) {
  qDebug() << "variant1 is not equal to variant3";  // 输出:variant1 is not equal to variant3
}
  1. 与 STL 类型转换

QVariant 可以与 STL 类型进行转换,如 std::stringstd::vector 等。

std::string stdString = "Hello from STL";
QVariant variant = QVariant::fromValue(stdString);
std::string convertedString = variant.value<std::string>();

qDebug() << QString::fromStdString(convertedString);
// 输出:Hello from STL
  1. 存储自定义类型

如果你需要存储自定义类型,可以通过 Q_DECLARE_METATYPEqVariantFromValue() 来实现。

struct MyStruct {
  int a;
  double b;
};

Q_DECLARE_METATYPE(MyStruct)

MyStruct myStruct = { 1, 3.14 };
QVariant variant = QVariant::fromValue(myStruct);

MyStruct retrievedStruct = variant.value<MyStruct>();
qDebug() << "a:" << retrievedStruct.a << "b:" << retrievedStruct.b;
总结

QVariant 是一个非常强大的数据封装类,它能够存储多种类型的数据,并支持类型转换。无论是基本数据类型、Qt 数据类型,还是自定义类型,都可以通过 QVariant 进行管理。它是 Qt 框架中实现模型-视图、信号槽、数据库操作等机制的重要组成部分。通过合理使用 QVariant,可以大大简化跨类型的数据操作和转换,提高程序的灵活性与可扩展性。

你可能感兴趣的:(Qt,编程,qt,c++)