QVariant

PyQt6.QtCore.QVariant

Description

The QVariant class acts like a union for the most common Qt data types.

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 property() and for database work, etc.

A QVariant object holds a single value of a single typeId() at a time. (Some types 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. A variant is null if the variant contains no initialized value, or contains a null pointer.

# QVariant x, y(QString()), z(QString(""));
# x.convert(QMetaType::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 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(QMetaType::fromType<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.

Methods

__init__()

Constructs an invalid variant.


__init__(Any)

TODO


__init__(QVariant)

Constructs a copy of the variant, p, passed as the argument to this constructor.


canConvert(QMetaType) bool

Returns true if the variant’s type can be cast to the requested type, type. Such casting is done automatically when calling the toInt(), toBool(), … methods.

See also

canConvert().


canView(QMetaType) bool

TODO


clear()

Convert this variant to type UnknownType and free up any resources used.


convert(QMetaType) bool

Casts the variant to the requested type, targetType. If the cast cannot be done, the variant is still changed to the requested type, but is left in a cleared null state similar to that constructed by QVariant(Type).

Returns true if the current type of the variant was successfully cast; otherwise returns false.

A QVariant containing a pointer to a type derived from QObject will also convert and return true for this function if a qobject_cast to the type described by targetType would succeed. Note that this only works for QObject subclasses which use the Q_OBJECT macro.

Note: converting QVariants that are null due to not being initialized or having failed a previous conversion will always fail, changing the type, remaining null, and returning false.

See also

canConvert(), clear().


__eq__(Any) bool

TODO


isNull() bool

Returns true if this is a null variant, false otherwise.

A variant is considered null if it contains no initialized value or a null pointer.

Note: This behavior has been changed from Qt 5, where would also return true if the variant contained an object of a builtin type with an method that returned true for that object.

See also

convert().


isValid() bool

Returns true if the storage type of this variant is not UnknownType; otherwise returns false.


load(QDataStream)

Internal function for loading a variant from stream s. Use the stream operators instead.


metaType() QMetaType

Returns the QMetaType of the value stored in the variant.


__ne__(Any) bool

TODO


save(QDataStream)

Internal function for saving a variant to the stream s. Use the stream operators instead.


swap(QVariant)

Swaps this variant with other. This operation is very fast and never fails.


typeId() int

TODO


typeName() str

Returns the name of the type stored in the variant. The returned strings describe the C++ datatype used to store the data: for example, “QFont”, “QString”, or “QVariantList”. An Invalid variant returns 0.


userType() int

TODO


value() Any

Returns the stored value converted to the template type T. Call canConvert() to find out whether a type can be converted. If the value cannot be converted, a default-constructed value will be returned.

If the type T is supported by QVariant, this function behaves exactly as toString(), toInt() etc.

Example:

# QVariant v;

# MyCustomStruct c;
# if (v.canConvert<MyCustomStruct>())
#     c = v.value<MyCustomStruct>();

# v = 7;
# int i = v.value<int>();                        // same as v.toInt()
# QString s = v.value<QString>();                // same as v.toString(), s is now "7"
# MyCustomStruct c2 = v.value<MyCustomStruct>(); // conversion failed, c2 is empty

If the QVariant contains a pointer to a type derived from QObject then T may be any QObject type. If the pointer stored in the QVariant can be qobject_cast to T, then that result is returned. Otherwise nullptr is returned. Note that this only works for QObject subclasses which use the Q_OBJECT macro.

If the QVariant contains a sequential container and T is QVariantList, the elements of the container will be converted into QVariants and returned as a QVariantList.


# QList<int> intList = {7, 11, 42};

# QVariant variant = QVariant::fromValue(intList);
# if (variant.canConvert<QVariantList>()) {
#     QSequentialIterable iterable = variant.value<QSequentialIterable>();
#     // Can use foreach:
#     foreach (const QVariant &v, iterable) {
#         qDebug() << v;
#     }
#     // Can use C++11 range-for:
#     for (const QVariant &v : iterable) {
#         qDebug() << v;
#     }
#     // Can use iterators:
#     QSequentialIterable::const_iterator it = iterable.begin();
#     const QSequentialIterable::const_iterator end = iterable.end();
#     for ( ; it != end; ++it) {
#         qDebug() << *it;
#     }
# }

See also

setValue(), fromValue(), canConvert(), Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE().