QVariant Class
The QVariant class acts like a union for the most common Qt data types. More...
| Header: | #include <QVariant> |
| qmake: | QT += core |
Related Non-Members
| typedef | QVariantHash |
| typedef | QVariantList |
| typedef | QVariantMap |
Detailed Description
Because C++ forbids unions from including types that have non-default constructors or destructors, most interesting Qt classes cannot be used in unions. Without QVariant, this would be a problem for QObject::property() and for database work, etc.
A QVariant object holds a single value of a single type() at a time. (Some type()s are multi-valued, for example a string list.) You can find out what type, T, the variant holds, convert it to a different type using convert(), get its value using one of the toT() functions (e.g., toSize()) and check whether the type can be converted to a particular type using canConvert().
The methods named toT() (e.g., toInt(), toString()) are const. If you ask for the stored type, they return a copy of the stored object. If you ask for a type that can be generated from the stored type, toT() copies and converts and leaves the object itself unchanged. If you ask for a type that cannot be generated from the stored type, the result depends on the type; see the function documentation for details.
Here is some example code to demonstrate the use of 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());
You can even store QList<QVariant> and QMap<QString, QVariant> values in a variant, so you can easily construct arbitrarily complex data structures of arbitrary types. This is very powerful and versatile, but may prove less memory and speed efficient than storing specific types in standard data structures.
QVariant also supports the notion of null values, where you can have a defined type with no value set. However, note that QVariant types can only be cast when they have had a value set.
QVariant x, y(QString()), z(QString("")); x.convert(QVariant::Int); // x.isNull() == true // y.isNull() == true, z.isNull() == false
QVariant can be extended to support other types than those mentioned in the Type enum. See Creating Custom Qt Types for details.
A Note on GUI Types
Because QVariant is part of the Qt Core module, it cannot provide conversion functions to data types defined in Qt GUI, such as QColor, QImage, and QPixmap. In other words, there is no toColor() function. Instead, you can use the QVariant::value() or the qvariant_cast() template function. For example:
QVariant variant; ... QColor color = variant.value<QColor>();
The inverse conversion (e.g., from QColor to QVariant) is automatic for all data types supported by QVariant, including GUI-related types:
QColor color = palette().background().color(); QVariant variant = color;
Using canConvert() and convert() Consecutively
When using canConvert() and convert() consecutively, it is possible for canConvert() to return true, but convert() to return false. This is typically because canConvert() only reports the general ability of QVariant to convert between types given suitable data; it is still possible to supply data which cannot actually be converted.
For example, canConvert(Int) would return true when called on a variant containing a string because, in principle, QVariant is able to convert strings of numbers to integers. However, if the string contains non-numeric characters, it cannot be converted to an integer, and any attempt to convert it will fail. Hence, it is important to have both functions return true for a successful conversion.
See also QMetaType.