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还支持null值的概念,我们可以定义一个没有值的类型。但是请注意,QVariant类型只有在设置了值时才能强制转换。
QVariant x, y(QString()), z(QString(""));
x.convert(QVariant::Int);
// x.isNull() == true
// y.isNull() == true, z.isNull() == false
QVariant可以被扩展以支持enum类型之外的其他类型。详见创建自定义Qt类型。
因为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()返回true,但convert()返回false。这通常是因为canConvert()只报告QVariant在给定适当数据的情况下进行类型转换的一般能力;仍然有可能提供不能实际转换的数据。
例如,当调用包含字符串的变量时,canConvert(Int)将返回true,因为原则上,QVariant能够将数字字符串转换为整数。但是,如果字符串中包含非数字字符,则不能将其转换为整数,而且转换将失败。
因此,要成功转换,两个函数都返回true很重要。
因为准换的时候也得考虑能不转成功,canConvert() 只指示能转,也就是QVarent 支持转的功能,但是 convert() 指示是否已经转换成功的。