Qt扫盲-QVariant理论使用总结

一、概述

QVariant 是一个用来存放变体数据的工具类,因为c++禁止 union 包含具有非默认构造函数或析构函数的类型,所以大多数有趣的Qt类不能在Union中使用。如果没有QVariant,这对于QObject::property()和 数据库工作 等来说将是一个问题。

QVariant对象一次只保存一种 type() 的一个值。(有些 type()是多值的,例如字符串列表。)我们可以找出变量T的类型,使用 convert() 将其转换为不同的类型,使用toT()函数(例如toSize())获取其值,并使用 canConvert() 检查该类型是否可以转换为特定类型。为了安全起见,都是建议先看看能不能转换再转换。

二、使用用例

QVariant 提供了很多名为 toT() 的方法 (例如toInt()、toString())是const。如果询问存储的类型,它们会返回存储对象的副本。如果指定的类型可以根据存储的类型生成,toT()会进行复制和转换,而不会改变对象本身。

下面是一些示例代码来演示QVariant的使用:

  QDataStream out(...);
  QVariant v(123);                // The variant now contains an int
  int x = v.toInt();              // x = 123
  out << v;                       // Writes a type tag and an int to out
  v = QVariant("hello");          // The variant now contains a QByteArray
  v = QVariant(tr("hello"));      // The variant now contains a QString
  int y = v.toInt();              // y = 0 since v cannot be converted to an int
  QString s = v.toString();       // s = tr("hello")  (see QObject::tr())
  out << v;                       // Writes a type tag and a QString to out
  ...
  QDataStream in(...);            // (opening the previously written stream)
  in >> v;                        // Reads an Int variant
  int z = v.toInt();              // z = 123
  qDebug("Type is %s",            // prints "Type is int"
          v.typeName());
  v = v.toInt() + 100;            // The variant now hold the value 223
  v = QVariant(QStringList());

我们甚至可以将 QList<QVariant> 和 QMap<QString, QVariant> 的值存储在一个 QVariant 中,这样我们就可以轻松地构造任意类型的任意复杂的数据结构。这是非常强大和通用的,但与在标准数据结构中存储特定类型相比,这种转换是被证明内存和速度效率更低。

QVariant还支持null值的概念,我们可以定义一个没有值的类型。但是请注意,QVariant类型只有在设置了值时才能强制转换。

  QVariant x, y(QString()), z(QString(""));
  x.convert(QVariant::Int);
  // x.isNull() == true
  // y.isNull() == true, z.isNull() == false

QVariant可以被扩展以支持enum类型之外的其他类型。详见创建自定义Qt类型。

三、关于GUI类型的说明

因为QVariant是 Qt Core 模块的一部分,它不能提供到Qt GUI中定义的数据类型(如QColor、QImage和QPixmap)的转换函数。换句话说,没有toColor()函数。相反,我们可以使用 QVariant::value() 或 qvariant_cast() 模板函数。例如:

  QVariant variant;
  ...
  QColor color = variant.value<QColor>();

提供了这个功能的话很多类型就可以转换的。这个就很强大的。

对于QVariant支持的所有数据类型,包括gui相关类型,都会自动进行逆转换(例如,从QColor到QVariant):

  QColor color = palette().background().color();
  QVariant variant = color;

四、连续使用canConvert()和convert()

当连续使用canConvert()和convert()时,可能canConvert()返回true,但convert()返回false。这通常是因为canConvert()只报告QVariant在给定适当数据的情况下进行类型转换的一般能力;仍然有可能提供不能实际转换的数据。

例如,当调用包含字符串的变量时,canConvert(Int)将返回true,因为原则上,QVariant能够将数字字符串转换为整数。但是,如果字符串中包含非数字字符,则不能将其转换为整数,而且转换将失败。

因此,要成功转换,两个函数都返回true很重要。

因为准换的时候也得考虑能不转成功,canConvert() 只指示能转,也就是QVarent 支持转的功能,但是 convert() 指示是否已经转换成功的。

猜你喜欢

转载自blog.csdn.net/qq_43680827/article/details/132940987
今日推荐