1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
7 ** This file is part of the QtCore module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include "qbitarray.h"
44 #include "qbytearray.h"
45 #include "qdatastream.h"
48 #include "qdatetime.h"
49 #include "qeasingcurve.h"
52 #include "qstringlist.h"
56 #ifndef QT_BOOTSTRAPPED
57 #include "qabstractitemmodel.h"
59 #include "private/qvariant_p.h"
60 #include "qmetatype_p.h"
62 #ifndef QT_NO_GEOM_VARIANT
83 static const QVariant::Handler *Handlers[QModulesPrivate::ModulesCount];
85 const QVariant::Handler *operator[] (const int typeId) const
87 return Handlers[QModulesPrivate::moduleForType(typeId)];
90 void registerHandler(const QModulesPrivate::Names name, const QVariant::Handler *handler)
92 Handlers[name] = handler;
95 inline void unregisterHandler(const QModulesPrivate::Names name);
101 struct TypeDefiniton {
102 static const bool IsAvailable = true;
105 // Ignore these types, as incomplete
106 #ifdef QT_BOOTSTRAPPED
107 template<> struct TypeDefiniton<QEasingCurve> { static const bool IsAvailable = false; };
108 template<> struct TypeDefiniton<QModelIndex> { static const bool IsAvailable = false; };
110 #ifdef QT_NO_GEOM_VARIANT
111 template<> struct TypeDefiniton<QRect> { static const bool IsAvailable = false; };
112 template<> struct TypeDefiniton<QRectF> { static const bool IsAvailable = false; };
113 template<> struct TypeDefiniton<QSize> { static const bool IsAvailable = false; };
114 template<> struct TypeDefiniton<QSizeF> { static const bool IsAvailable = false; };
115 template<> struct TypeDefiniton<QLine> { static const bool IsAvailable = false; };
116 template<> struct TypeDefiniton<QLineF> { static const bool IsAvailable = false; };
117 template<> struct TypeDefiniton<QPoint> { static const bool IsAvailable = false; };
118 template<> struct TypeDefiniton<QPointF> { static const bool IsAvailable = false; };
121 struct CoreTypesFilter {
124 static const bool IsAccepted = QTypeModuleInfo<T>::IsCore && TypeDefiniton<T>::IsAvailable;
127 } // annonymous used to hide TypeDefiniton
129 namespace { // annonymous used to hide QVariant handlers
131 static void construct(QVariant::Private *x, const void *copy)
133 QVariantConstructor<CoreTypesFilter> constructor(x, copy);
134 QMetaTypeSwitcher::switcher<void>(constructor, x->type, 0);
137 static void clear(QVariant::Private *d)
139 QVariantDestructor<CoreTypesFilter> cleaner(d);
140 QMetaTypeSwitcher::switcher<void>(cleaner, d->type, 0);
143 static bool isNull(const QVariant::Private *d)
145 QVariantIsNull<CoreTypesFilter> isNull(d);
146 return QMetaTypeSwitcher::switcher<bool>(isNull, d->type, 0);
152 Compares \a a to \a b. The caller guarantees that \a a and \a b
153 are of the same type.
155 static bool compare(const QVariant::Private *a, const QVariant::Private *b)
157 QVariantComparator<CoreTypesFilter> comparator(a, b);
158 return QMetaTypeSwitcher::switcher<bool>(comparator, a->type, 0);
164 static qlonglong qMetaTypeNumber(const QVariant::Private *d)
169 case QMetaType::LongLong:
171 case QMetaType::Char:
172 return qlonglong(d->data.c);
173 case QMetaType::Short:
174 return qlonglong(d->data.s);
175 case QMetaType::Long:
176 return qlonglong(d->data.l);
177 case QMetaType::Float:
178 return qRound64(d->data.f);
179 case QVariant::Double:
180 return qRound64(d->data.d);
186 static qulonglong qMetaTypeUNumber(const QVariant::Private *d)
191 case QVariant::ULongLong:
193 case QMetaType::UChar:
195 case QMetaType::UShort:
197 case QMetaType::ULong:
204 static qlonglong qConvertToNumber(const QVariant::Private *d, bool *ok)
208 switch (uint(d->type)) {
209 case QVariant::String:
210 return v_cast<QString>(d)->toLongLong(ok);
212 return v_cast<QChar>(d)->unicode();
213 case QVariant::ByteArray:
214 return v_cast<QByteArray>(d)->toLongLong(ok);
216 return qlonglong(d->data.b);
217 case QVariant::Double:
219 case QMetaType::Char:
220 case QMetaType::Short:
221 case QMetaType::Long:
222 case QMetaType::Float:
223 case QMetaType::LongLong:
224 return qMetaTypeNumber(d);
225 case QVariant::ULongLong:
227 case QMetaType::UChar:
228 case QMetaType::UShort:
229 case QMetaType::ULong:
230 return qlonglong(qMetaTypeUNumber(d));
237 static qulonglong qConvertToUnsignedNumber(const QVariant::Private *d, bool *ok)
241 switch (uint(d->type)) {
242 case QVariant::String:
243 return v_cast<QString>(d)->toULongLong(ok);
245 return v_cast<QChar>(d)->unicode();
246 case QVariant::ByteArray:
247 return v_cast<QByteArray>(d)->toULongLong(ok);
249 return qulonglong(d->data.b);
250 case QVariant::Double:
252 case QMetaType::Char:
253 case QMetaType::Short:
254 case QMetaType::Long:
255 case QMetaType::Float:
256 case QMetaType::LongLong:
257 return qulonglong(qMetaTypeNumber(d));
258 case QVariant::ULongLong:
260 case QMetaType::UChar:
261 case QMetaType::UShort:
262 case QMetaType::ULong:
263 return qMetaTypeUNumber(d);
267 return Q_UINT64_C(0);
270 template<typename TInput, typename LiteralWrapper>
271 inline bool qt_convertToBool(const QVariant::Private *const d)
273 TInput str = v_cast<TInput>(d)->toLower();
274 return !(str == LiteralWrapper("0") || str == LiteralWrapper("false") || str.isEmpty());
280 Converts \a d to type \a t, which is placed in \a result.
282 static bool convert(const QVariant::Private *d, QVariant::Type t, void *result, bool *ok)
284 Q_ASSERT(d->type != uint(t));
294 case QVariant::String:
295 *static_cast<QUrl *>(result) = QUrl(*v_cast<QString>(d));
301 case QVariant::String: {
302 QString *str = static_cast<QString *>(result);
305 *str = QString(*v_cast<QChar>(d));
307 case QMetaType::Char:
308 case QMetaType::UChar:
309 *str = QChar::fromAscii(d->data.c);
311 case QMetaType::Short:
312 case QMetaType::Long:
314 case QVariant::LongLong:
315 *str = QString::number(qMetaTypeNumber(d));
318 case QVariant::ULongLong:
319 case QMetaType::UShort:
320 case QMetaType::ULong:
321 *str = QString::number(qMetaTypeUNumber(d));
323 case QMetaType::Float:
324 *str = QString::number(d->data.f, 'g', FLT_DIG);
326 case QVariant::Double:
327 *str = QString::number(d->data.d, 'g', DBL_DIG);
329 #if !defined(QT_NO_DATESTRING)
331 *str = v_cast<QDate>(d)->toString(Qt::ISODate);
334 *str = v_cast<QTime>(d)->toString(Qt::ISODate);
336 case QVariant::DateTime:
337 *str = v_cast<QDateTime>(d)->toString(Qt::ISODate);
341 *str = QLatin1String(d->data.b ? "true" : "false");
343 case QVariant::ByteArray:
344 *str = QString::fromAscii(v_cast<QByteArray>(d)->constData());
346 case QVariant::StringList:
347 if (v_cast<QStringList>(d)->count() == 1)
348 *str = v_cast<QStringList>(d)->at(0);
351 *str = v_cast<QUrl>(d)->toString();
354 *str = v_cast<QUuid>(d)->toString();
361 case QVariant::Char: {
362 QChar *c = static_cast<QChar *>(result);
365 case QVariant::LongLong:
366 case QMetaType::Char:
367 case QMetaType::Short:
368 case QMetaType::Long:
369 case QMetaType::Float:
370 *c = QChar(ushort(qMetaTypeNumber(d)));
373 case QVariant::ULongLong:
374 case QMetaType::UChar:
375 case QMetaType::UShort:
376 case QMetaType::ULong:
377 *c = QChar(ushort(qMetaTypeUNumber(d)));
384 #ifndef QT_NO_GEOM_VARIANT
385 case QVariant::Size: {
386 QSize *s = static_cast<QSize *>(result);
388 case QVariant::SizeF:
389 *s = v_cast<QSizeF>(d)->toSize();
397 case QVariant::SizeF: {
398 QSizeF *s = static_cast<QSizeF *>(result);
401 *s = QSizeF(*(v_cast<QSize>(d)));
409 case QVariant::Line: {
410 QLine *s = static_cast<QLine *>(result);
412 case QVariant::LineF:
413 *s = v_cast<QLineF>(d)->toLine();
421 case QVariant::LineF: {
422 QLineF *s = static_cast<QLineF *>(result);
425 *s = QLineF(*(v_cast<QLine>(d)));
433 case QVariant::StringList:
434 if (d->type == QVariant::List) {
435 QStringList *slst = static_cast<QStringList *>(result);
436 const QVariantList *list = v_cast<QVariantList >(d);
437 for (int i = 0; i < list->size(); ++i)
438 slst->append(list->at(i).toString());
439 } else if (d->type == QVariant::String) {
440 QStringList *slst = static_cast<QStringList *>(result);
441 *slst = QStringList(*v_cast<QString>(d));
446 case QVariant::Date: {
447 QDate *dt = static_cast<QDate *>(result);
448 if (d->type == QVariant::DateTime)
449 *dt = v_cast<QDateTime>(d)->date();
450 #ifndef QT_NO_DATESTRING
451 else if (d->type == QVariant::String)
452 *dt = QDate::fromString(*v_cast<QString>(d), Qt::ISODate);
457 return dt->isValid();
459 case QVariant::Time: {
460 QTime *t = static_cast<QTime *>(result);
462 case QVariant::DateTime:
463 *t = v_cast<QDateTime>(d)->time();
465 #ifndef QT_NO_DATESTRING
466 case QVariant::String:
467 *t = QTime::fromString(*v_cast<QString>(d), Qt::ISODate);
475 case QVariant::DateTime: {
476 QDateTime *dt = static_cast<QDateTime *>(result);
478 #ifndef QT_NO_DATESTRING
479 case QVariant::String:
480 *dt = QDateTime::fromString(*v_cast<QString>(d), Qt::ISODate);
484 *dt = QDateTime(*v_cast<QDate>(d));
489 return dt->isValid();
491 case QVariant::ByteArray: {
492 QByteArray *ba = static_cast<QByteArray *>(result);
494 case QVariant::String:
495 *ba = v_cast<QString>(d)->toAscii();
497 case QVariant::Double:
498 *ba = QByteArray::number(d->data.d, 'g', DBL_DIG);
500 case QMetaType::Float:
501 *ba = QByteArray::number(d->data.f, 'g', FLT_DIG);
503 case QMetaType::Char:
504 case QMetaType::UChar:
505 *ba = QByteArray(1, d->data.c);
508 case QVariant::LongLong:
509 case QMetaType::Short:
510 case QMetaType::Long:
511 *ba = QByteArray::number(qMetaTypeNumber(d));
514 case QVariant::ULongLong:
515 case QMetaType::UShort:
516 case QMetaType::ULong:
517 *ba = QByteArray::number(qMetaTypeUNumber(d));
520 *ba = QByteArray(d->data.b ? "true" : "false");
527 case QMetaType::Short:
528 *static_cast<short *>(result) = short(qConvertToNumber(d, ok));
530 case QMetaType::Long:
531 *static_cast<long *>(result) = long(qConvertToNumber(d, ok));
533 case QMetaType::UShort:
534 *static_cast<ushort *>(result) = ushort(qConvertToUnsignedNumber(d, ok));
536 case QMetaType::ULong:
537 *static_cast<ulong *>(result) = ulong(qConvertToUnsignedNumber(d, ok));
540 *static_cast<int *>(result) = int(qConvertToNumber(d, ok));
543 *static_cast<uint *>(result) = uint(qConvertToUnsignedNumber(d, ok));
545 case QVariant::LongLong:
546 *static_cast<qlonglong *>(result) = qConvertToNumber(d, ok);
548 case QVariant::ULongLong: {
549 *static_cast<qulonglong *>(result) = qConvertToUnsignedNumber(d, ok);
552 case QMetaType::UChar: {
553 *static_cast<uchar *>(result) = qConvertToUnsignedNumber(d, ok);
556 case QVariant::Bool: {
557 bool *b = static_cast<bool *>(result);
559 case QVariant::ByteArray:
560 *b = qt_convertToBool<QByteArray, QByteArray>(d);
562 case QVariant::String:
563 *b = qt_convertToBool<QString, QLatin1String>(d);
566 *b = !v_cast<QChar>(d)->isNull();
568 case QVariant::Double:
570 case QVariant::LongLong:
571 case QMetaType::Char:
572 case QMetaType::Short:
573 case QMetaType::Long:
574 case QMetaType::Float:
575 *b = qMetaTypeNumber(d) != Q_INT64_C(0);
578 case QVariant::ULongLong:
579 case QMetaType::UChar:
580 case QMetaType::UShort:
581 case QMetaType::ULong:
582 *b = qMetaTypeUNumber(d) != Q_UINT64_C(0);
590 case QVariant::Double: {
591 double *f = static_cast<double *>(result);
593 case QVariant::String:
594 *f = v_cast<QString>(d)->toDouble(ok);
596 case QVariant::ByteArray:
597 *f = v_cast<QByteArray>(d)->toDouble(ok);
600 *f = double(d->data.b);
602 case QMetaType::Float:
603 *f = double(d->data.f);
605 case QVariant::LongLong:
607 case QMetaType::Char:
608 case QMetaType::Short:
609 case QMetaType::Long:
610 *f = double(qMetaTypeNumber(d));
613 case QVariant::ULongLong:
614 case QMetaType::UChar:
615 case QMetaType::UShort:
616 case QMetaType::ULong:
617 *f = double(qMetaTypeUNumber(d));
625 case QMetaType::Float: {
626 float *f = static_cast<float *>(result);
628 case QVariant::String:
629 *f = v_cast<QString>(d)->toFloat(ok);
631 case QVariant::ByteArray:
632 *f = v_cast<QByteArray>(d)->toFloat(ok);
635 *f = float(d->data.b);
637 case QVariant::Double:
638 *f = float(d->data.d);
640 case QVariant::LongLong:
642 case QMetaType::Char:
643 case QMetaType::Short:
644 case QMetaType::Long:
645 *f = float(qMetaTypeNumber(d));
648 case QVariant::ULongLong:
649 case QMetaType::UChar:
650 case QMetaType::UShort:
651 case QMetaType::ULong:
652 *f = float(qMetaTypeUNumber(d));
661 if (d->type == QVariant::StringList) {
662 QVariantList *lst = static_cast<QVariantList *>(result);
663 const QStringList *slist = v_cast<QStringList>(d);
664 for (int i = 0; i < slist->size(); ++i)
665 lst->append(QVariant(slist->at(i)));
666 } else if (qstrcmp(QMetaType::typeName(d->type), "QList<QVariant>") == 0) {
667 *static_cast<QVariantList *>(result) =
668 *static_cast<QList<QVariant> *>(d->data.shared->ptr);
674 if (qstrcmp(QMetaType::typeName(d->type), "QMap<QString, QVariant>") == 0) {
675 *static_cast<QVariantMap *>(result) =
676 *static_cast<QMap<QString, QVariant> *>(d->data.shared->ptr);
682 if (qstrcmp(QMetaType::typeName(d->type), "QHash<QString, QVariant>") == 0) {
683 *static_cast<QVariantHash *>(result) =
684 *static_cast<QHash<QString, QVariant> *>(d->data.shared->ptr);
689 #ifndef QT_NO_GEOM_VARIANT
691 if (d->type == QVariant::RectF)
692 *static_cast<QRect *>(result) = (v_cast<QRectF>(d))->toRect();
696 case QVariant::RectF:
697 if (d->type == QVariant::Rect)
698 *static_cast<QRectF *>(result) = *v_cast<QRect>(d);
702 case QVariant::PointF:
703 if (d->type == QVariant::Point)
704 *static_cast<QPointF *>(result) = *v_cast<QPoint>(d);
708 case QVariant::Point:
709 if (d->type == QVariant::PointF)
710 *static_cast<QPoint *>(result) = (v_cast<QPointF>(d))->toPoint();
714 case QMetaType::Char:
716 *static_cast<qint8 *>(result) = qint8(qConvertToNumber(d, ok));
722 case QVariant::String:
723 *static_cast<QUuid *>(result) = QUuid(*v_cast<QString>(d));
735 #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
736 static void streamDebug(QDebug dbg, const QVariant &v)
738 QVariant::Private *d = const_cast<QVariant::Private *>(&v.data_ptr());
739 QVariantDebugStream<CoreTypesFilter> stream(dbg, d);
740 QMetaTypeSwitcher::switcher<void>(stream, d->type, 0);
744 const QVariant::Handler qt_kernel_variant_handler = {
748 #ifndef QT_NO_DATASTREAM
755 #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
762 static void dummyConstruct(QVariant::Private *, const void *) { Q_ASSERT_X(false, "QVariant", "Trying to construct an unknown type"); }
763 static void dummyClear(QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to clear an unknown type"); }
764 static bool dummyIsNull(const QVariant::Private *d) { Q_ASSERT_X(false, "QVariant::isNull", "Trying to call isNull on an unknown type"); return d->is_null; }
765 static bool dummyCompare(const QVariant::Private *, const QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to compare an unknown types"); return false; }
766 static bool dummyConvert(const QVariant::Private *, QVariant::Type , void *, bool *) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); return false; }
767 #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
768 static void dummyStreamDebug(QDebug, const QVariant &) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); }
770 const QVariant::Handler qt_dummy_variant_handler = {
774 #ifndef QT_NO_DATASTREAM
781 #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
788 static void customConstruct(QVariant::Private *d, const void *copy)
790 const uint size = QMetaType::sizeOf(d->type);
792 d->type = QVariant::Invalid;
796 // this logic should match with QVariantIntegrator::CanUseInternalSpace
797 if (size <= sizeof(QVariant::Private::Data)
798 && (QMetaType::typeFlags(d->type) & QMetaType::MovableType)) {
799 QMetaType::construct(d->type, &d->data.ptr, copy);
800 d->is_shared = false;
802 void *ptr = QMetaType::create(d->type, copy);
804 d->data.shared = new QVariant::PrivateShared(ptr);
808 static void customClear(QVariant::Private *d)
811 QMetaType::destruct(d->type, &d->data.ptr);
813 QMetaType::destroy(d->type, d->data.shared->ptr);
814 delete d->data.shared;
818 static bool customIsNull(const QVariant::Private *d)
823 static bool customCompare(const QVariant::Private *a, const QVariant::Private *b)
825 const char *const typeName = QMetaType::typeName(a->type);
826 if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(a->type)))
827 qFatal("QVariant::compare: type %d unknown to QVariant.", a->type);
829 const void *a_ptr = a->is_shared ? a->data.shared->ptr : &(a->data.ptr);
830 const void *b_ptr = b->is_shared ? b->data.shared->ptr : &(b->data.ptr);
832 uint typeNameLen = qstrlen(typeName);
833 if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*')
834 return *static_cast<void *const *>(a_ptr) == *static_cast<void *const *>(b_ptr);
836 if (a->is_null && b->is_null)
839 return !memcmp(a_ptr, b_ptr, QMetaType::sizeOf(a->type));
842 static bool customConvert(const QVariant::Private *, QVariant::Type, void *, bool *ok)
849 #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
850 static void customStreamDebug(QDebug, const QVariant &) {}
853 const QVariant::Handler qt_custom_variant_handler = {
857 #ifndef QT_NO_DATASTREAM
864 #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
871 } // annonymous used to hide QVariant handlers
873 static HandlersManager handlerManager;
874 Q_STATIC_ASSERT_X(!QModulesPrivate::Core, "Initialization assumes that ModulesNames::Core is 0");
875 const QVariant::Handler *HandlersManager::Handlers[QModulesPrivate::ModulesCount]
876 = { &qt_kernel_variant_handler, &qt_dummy_variant_handler,
877 &qt_dummy_variant_handler, &qt_custom_variant_handler };
879 Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler()
881 return &qt_kernel_variant_handler;
884 inline void HandlersManager::unregisterHandler(const QModulesPrivate::Names name)
886 Handlers[name] = &qt_dummy_variant_handler;
889 Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names */name, const QVariant::Handler *handler)
891 handlerManager.registerHandler(static_cast<QModulesPrivate::Names>(name), handler);
894 Q_CORE_EXPORT void QVariantPrivate::unregisterHandler(const int /* Modules::Names */ name)
896 handlerManager.unregisterHandler(static_cast<QModulesPrivate::Names>(name));
901 \brief The QVariant class acts like a union for the most common Qt data types.
907 Because C++ forbids unions from including types that have
908 non-default constructors or destructors, most interesting Qt
909 classes cannot be used in unions. Without QVariant, this would be
910 a problem for QObject::property() and for database work, etc.
912 A QVariant object holds a single value of a single type() at a
913 time. (Some type()s are multi-valued, for example a string list.)
914 You can find out what type, T, the variant holds, convert it to a
915 different type using convert(), get its value using one of the
916 toT() functions (e.g., toSize()) and check whether the type can
917 be converted to a particular type using canConvert().
919 The methods named toT() (e.g., toInt(), toString()) are const. If
920 you ask for the stored type, they return a copy of the stored
921 object. If you ask for a type that can be generated from the
922 stored type, toT() copies and converts and leaves the object
923 itself unchanged. If you ask for a type that cannot be generated
924 from the stored type, the result depends on the type; see the
925 function documentation for details.
927 Here is some example code to demonstrate the use of QVariant:
929 \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 0
931 You can even store QList<QVariant> and QMap<QString, QVariant>
932 values in a variant, so you can easily construct arbitrarily
933 complex data structures of arbitrary types. This is very powerful
934 and versatile, but may prove less memory and speed efficient than
935 storing specific types in standard data structures.
937 QVariant also supports the notion of null values, where you can
938 have a defined type with no value set. However, note that QVariant
939 types can only be cast when they have had a value set.
941 \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 1
943 QVariant can be extended to support other types than those
944 mentioned in the \l Type enum. See the \l QMetaType documentation
947 \section1 A Note on GUI Types
949 Because QVariant is part of the QtCore library, it cannot provide
950 conversion functions to data types defined in QtGui, such as
951 QColor, QImage, and QPixmap. In other words, there is no \c
952 toColor() function. Instead, you can use the QVariant::value() or
953 the qvariant_cast() template function. For example:
955 \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 2
957 The inverse conversion (e.g., from QColor to QVariant) is
958 automatic for all data types supported by QVariant, including
961 \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 3
963 \section1 Using canConvert() and convert() Consecutively
965 When using canConvert() and convert() consecutively, it is possible for
966 canConvert() to return true, but convert() to return false. This
967 is typically because canConvert() only reports the general ability of
968 QVariant to convert between types given suitable data; it is still
969 possible to supply data which cannot actually be converted.
971 For example, canConvert() would return true when called on a variant
972 containing a string because, in principle, QVariant is able to convert
973 strings of numbers to integers.
974 However, if the string contains non-numeric characters, it cannot be
975 converted to an integer, and any attempt to convert it will fail.
976 Hence, it is important to have both functions return true for a
977 successful conversion.
983 \obsolete Use QMetaType::Type instead
986 This enum type defines the types of variable that a QVariant can
989 \value Invalid no type
990 \value BitArray a QBitArray
991 \value Bitmap a QBitmap
993 \value Brush a QBrush
994 \value ByteArray a QByteArray
996 \value Color a QColor
997 \value Cursor a QCursor
999 \value DateTime a QDateTime
1000 \value Double a double
1001 \value EasingCurve a QEasingCurve
1003 \value ModelIndex a QModelIndex
1005 \value Hash a QVariantHash
1007 \value Image a QImage
1009 \value KeySequence a QKeySequence
1011 \value LineF a QLineF
1012 \value List a QVariantList
1013 \value Locale a QLocale
1014 \value LongLong a \l qlonglong
1015 \value Map a QVariantMap
1016 \value Matrix a QMatrix
1017 \value Transform a QTransform
1018 \value Matrix4x4 a QMatrix4x4
1019 \value Palette a QPalette
1021 \value Pixmap a QPixmap
1022 \value Point a QPoint
1023 \value PointF a QPointF
1024 \value Polygon a QPolygon
1025 \value PolygonF a QPolygonF
1026 \value Quaternion a QQuaternion
1028 \value RectF a QRectF
1029 \value RegExp a QRegExp
1030 \value Region a QRegion
1032 \value SizeF a QSizeF
1033 \value SizePolicy a QSizePolicy
1034 \value String a QString
1035 \value StringList a QStringList
1036 \value TextFormat a QTextFormat
1037 \value TextLength a QTextLength
1039 \value UInt a \l uint
1040 \value ULongLong a \l qulonglong
1042 \value Vector2D a QVector2D
1043 \value Vector3D a QVector3D
1044 \value Vector4D a QVector4D
1046 \value UserType Base value for user-defined types.
1049 \omitvalue ColorGroup
1051 \omitvalue LastGuiType
1052 \omitvalue LastCoreType
1057 \fn QVariant::QVariant()
1059 Constructs an invalid variant.
1064 \fn QVariant::QVariant(int typeOrUserType, const void *copy)
1066 Constructs variant of type \a typeOrUserType, and initializes with
1067 \a copy if \a copy is not 0.
1069 Note that you have to pass the address of the variable you want stored.
1071 Usually, you never have to use this constructor, use QVariant::fromValue()
1072 instead to construct variants from the pointer types represented by
1073 \c QMetaType::VoidStar, \c QMetaType::QObjectStar and
1074 \c QMetaType::QWidgetStar.
1076 \sa QVariant::fromValue(), Type
1080 \fn QVariant::QVariant(Type type)
1082 Constructs a null variant of type \a type.
1088 \fn QVariant::create(int type, const void *copy)
1092 Constructs a variant private of type \a type, and initializes with \a copy if
1096 void QVariant::create(int type, const void *copy)
1099 handlerManager[type]->construct(&d, copy);
1103 \fn QVariant::~QVariant()
1105 Destroys the QVariant and the contained object.
1107 Note that subclasses that reimplement clear() should reimplement
1108 the destructor to call clear(). This destructor calls clear(), but
1109 because it is the destructor, QVariant::clear() is called rather
1110 than a subclass's clear().
1113 QVariant::~QVariant()
1115 if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
1116 handlerManager[d.type]->clear(&d);
1120 \fn QVariant::QVariant(const QVariant &p)
1122 Constructs a copy of the variant, \a p, passed as the argument to
1126 QVariant::QVariant(const QVariant &p)
1130 d.data.shared->ref.ref();
1131 } else if (p.d.type > Char) {
1132 handlerManager[d.type]->construct(&d, p.constData());
1133 d.is_null = p.d.is_null;
1137 #ifndef QT_NO_DATASTREAM
1139 Reads the variant from the data stream, \a s.
1141 QVariant::QVariant(QDataStream &s)
1146 #endif //QT_NO_DATASTREAM
1149 \fn QVariant::QVariant(const QString &val)
1151 Constructs a new variant with a string value, \a val.
1155 \fn QVariant::QVariant(const QLatin1String &val)
1157 Constructs a new variant with a string value, \a val.
1161 \fn QVariant::QVariant(const char *val)
1163 Constructs a new variant with a string value of \a val.
1164 The variant creates a deep copy of \a val, using the encoding
1165 set by QTextCodec::setCodecForCStrings().
1167 Note that \a val is converted to a QString for storing in the
1168 variant and QVariant::type() will return QMetaType::QString for
1171 You can disable this operator by defining \c
1172 QT_NO_CAST_FROM_ASCII when you compile your applications.
1174 \sa QTextCodec::setCodecForCStrings()
1177 #ifndef QT_NO_CAST_FROM_ASCII
1178 QVariant::QVariant(const char *val)
1180 QString s = QString::fromAscii(val);
1186 \fn QVariant::QVariant(const QStringList &val)
1188 Constructs a new variant with a string list value, \a val.
1192 \fn QVariant::QVariant(const QMap<QString, QVariant> &val)
1194 Constructs a new variant with a map of QVariants, \a val.
1198 \fn QVariant::QVariant(const QHash<QString, QVariant> &val)
1200 Constructs a new variant with a hash of QVariants, \a val.
1204 \fn QVariant::QVariant(const QDate &val)
1206 Constructs a new variant with a date value, \a val.
1210 \fn QVariant::QVariant(const QTime &val)
1212 Constructs a new variant with a time value, \a val.
1216 \fn QVariant::QVariant(const QDateTime &val)
1218 Constructs a new variant with a date/time value, \a val.
1223 \fn QVariant::QVariant(const QEasingCurve &val)
1225 Constructs a new variant with an easing curve value, \a val.
1229 \fn QVariant::QVariant(const QByteArray &val)
1231 Constructs a new variant with a bytearray value, \a val.
1235 \fn QVariant::QVariant(const QBitArray &val)
1237 Constructs a new variant with a bitarray value, \a val.
1241 \fn QVariant::QVariant(const QPoint &val)
1243 Constructs a new variant with a point value of \a val.
1247 \fn QVariant::QVariant(const QPointF &val)
1249 Constructs a new variant with a point value of \a val.
1253 \fn QVariant::QVariant(const QRectF &val)
1255 Constructs a new variant with a rect value of \a val.
1259 \fn QVariant::QVariant(const QLineF &val)
1261 Constructs a new variant with a line value of \a val.
1265 \fn QVariant::QVariant(const QLine &val)
1267 Constructs a new variant with a line value of \a val.
1271 \fn QVariant::QVariant(const QRect &val)
1273 Constructs a new variant with a rect value of \a val.
1277 \fn QVariant::QVariant(const QSize &val)
1279 Constructs a new variant with a size value of \a val.
1283 \fn QVariant::QVariant(const QSizeF &val)
1285 Constructs a new variant with a size value of \a val.
1289 \fn QVariant::QVariant(const QUrl &val)
1291 Constructs a new variant with a url value of \a val.
1295 \fn QVariant::QVariant(int val)
1297 Constructs a new variant with an integer value, \a val.
1301 \fn QVariant::QVariant(uint val)
1303 Constructs a new variant with an unsigned integer value, \a val.
1307 \fn QVariant::QVariant(qlonglong val)
1309 Constructs a new variant with a long long integer value, \a val.
1313 \fn QVariant::QVariant(qulonglong val)
1315 Constructs a new variant with an unsigned long long integer value, \a val.
1320 \fn QVariant::QVariant(bool val)
1322 Constructs a new variant with a boolean value, \a val.
1326 \fn QVariant::QVariant(double val)
1328 Constructs a new variant with a floating point value, \a val.
1332 \fn QVariant::QVariant(float val)
1334 Constructs a new variant with a floating point value, \a val.
1339 \fn QVariant::QVariant(const QList<QVariant> &val)
1341 Constructs a new variant with a list value, \a val.
1345 \fn QVariant::QVariant(const QChar &c)
1347 Constructs a new variant with a char value, \a c.
1351 \fn QVariant::QVariant(const QLocale &l)
1353 Constructs a new variant with a locale value, \a l.
1357 \fn QVariant::QVariant(const QRegExp ®Exp)
1359 Constructs a new variant with the regexp value \a regExp.
1363 \fn QVariant::QVariant(Qt::GlobalColor color)
1365 Constructs a new variant of type QVariant::Color and initializes
1368 This is a convenience constructor that allows \c{QVariant(Qt::blue);}
1369 to create a valid QVariant storing a QColor.
1371 Note: This constructor will assert if the application does not link
1372 to the Qt GUI library.
1375 QVariant::QVariant(Type type)
1376 { create(type, 0); }
1377 QVariant::QVariant(int typeOrUserType, const void *copy)
1378 { create(typeOrUserType, copy); d.is_null = false; }
1381 flags is true if it is a pointer type
1383 QVariant::QVariant(int typeOrUserType, const void *copy, uint flags)
1385 if (flags) { //type is a pointer type
1386 d.type = typeOrUserType;
1387 d.data.ptr = *reinterpret_cast<void *const*>(copy);
1389 create(typeOrUserType, copy);
1394 QVariant::QVariant(int val)
1395 { d.is_null = false; d.type = Int; d.data.i = val; }
1396 QVariant::QVariant(uint val)
1397 { d.is_null = false; d.type = UInt; d.data.u = val; }
1398 QVariant::QVariant(qlonglong val)
1399 { d.is_null = false; d.type = LongLong; d.data.ll = val; }
1400 QVariant::QVariant(qulonglong val)
1401 { d.is_null = false; d.type = ULongLong; d.data.ull = val; }
1402 QVariant::QVariant(bool val)
1403 { d.is_null = false; d.type = Bool; d.data.b = val; }
1404 QVariant::QVariant(double val)
1405 { d.is_null = false; d.type = Double; d.data.d = val; }
1407 QVariant::QVariant(const QByteArray &val)
1408 { d.is_null = false; d.type = ByteArray; v_construct<QByteArray>(&d, val); }
1409 QVariant::QVariant(const QBitArray &val)
1410 { d.is_null = false; d.type = BitArray; v_construct<QBitArray>(&d, val); }
1411 QVariant::QVariant(const QString &val)
1412 { d.is_null = false; d.type = String; v_construct<QString>(&d, val); }
1413 QVariant::QVariant(const QChar &val)
1414 { d.is_null = false; d.type = Char; v_construct<QChar>(&d, val); }
1415 QVariant::QVariant(const QLatin1String &val)
1416 { QString str(val); d.is_null = false; d.type = String; v_construct<QString>(&d, str); }
1417 QVariant::QVariant(const QStringList &val)
1418 { d.is_null = false; d.type = StringList; v_construct<QStringList>(&d, val); }
1420 QVariant::QVariant(const QDate &val)
1421 { d.is_null = false; d.type = Date; v_construct<QDate>(&d, val); }
1422 QVariant::QVariant(const QTime &val)
1423 { d.is_null = false; d.type = Time; v_construct<QTime>(&d, val); }
1424 QVariant::QVariant(const QDateTime &val)
1425 { d.is_null = false; d.type = DateTime; v_construct<QDateTime>(&d, val); }
1426 #ifndef QT_BOOTSTRAPPED
1427 QVariant::QVariant(const QEasingCurve &val)
1428 { d.is_null = false; d.type = EasingCurve; v_construct<QEasingCurve>(&d, val); }
1430 QVariant::QVariant(const QList<QVariant> &list)
1431 { d.is_null = false; d.type = List; v_construct<QVariantList>(&d, list); }
1432 QVariant::QVariant(const QMap<QString, QVariant> &map)
1433 { d.is_null = false; d.type = Map; v_construct<QVariantMap>(&d, map); }
1434 QVariant::QVariant(const QHash<QString, QVariant> &hash)
1435 { d.is_null = false; d.type = Hash; v_construct<QVariantHash>(&d, hash); }
1436 #ifndef QT_NO_GEOM_VARIANT
1437 QVariant::QVariant(const QPoint &pt) { d.is_null = false; d.type = Point; v_construct<QPoint>(&d, pt); }
1438 QVariant::QVariant(const QPointF &pt) { d.is_null = false; d.type = PointF; v_construct<QPointF>(&d, pt); }
1439 QVariant::QVariant(const QRectF &r) { d.is_null = false; d.type = RectF; v_construct<QRectF>(&d, r); }
1440 QVariant::QVariant(const QLineF &l) { d.is_null = false; d.type = LineF; v_construct<QLineF>(&d, l); }
1441 QVariant::QVariant(const QLine &l) { d.is_null = false; d.type = Line; v_construct<QLine>(&d, l); }
1442 QVariant::QVariant(const QRect &r) { d.is_null = false; d.type = Rect; v_construct<QRect>(&d, r); }
1443 QVariant::QVariant(const QSize &s) { d.is_null = false; d.type = Size; v_construct<QSize>(&d, s); }
1444 QVariant::QVariant(const QSizeF &s) { d.is_null = false; d.type = SizeF; v_construct<QSizeF>(&d, s); }
1446 QVariant::QVariant(const QUrl &u) { d.is_null = false; d.type = Url; v_construct<QUrl>(&d, u); }
1447 QVariant::QVariant(const QLocale &l) { d.is_null = false; d.type = Locale; v_construct<QLocale>(&d, l); }
1448 #ifndef QT_NO_REGEXP
1449 QVariant::QVariant(const QRegExp ®Exp) { d.is_null = false; d.type = RegExp; v_construct<QRegExp>(&d, regExp); }
1451 QVariant::QVariant(Qt::GlobalColor color) { create(62, &color); }
1454 Returns the storage type of the value stored in the variant.
1455 Although this function is declared as returning QVariant::Type,
1456 the return value should be interpreted as QMetaType::Type. In
1457 particular, QVariant::UserType is returned here only if the value
1458 is equal or greater than QMetaType::User.
1460 Note that return values in the ranges QVariant::Char through
1461 QVariant::RegExp and QVariant::Font through QVariant::Transform
1462 correspond to the values in the ranges QMetaType::QChar through
1463 QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion.
1465 Pay particular attention when working with char and QChar
1466 variants. Note that there is no QVariant constructor specifically
1467 for type char, but there is one for QChar. For a variant of type
1468 QChar, this function returns QVariant::Char, which is the same as
1469 QMetaType::QChar, but for a variant of type \c char, this function
1470 returns QMetaType::Char, which is \e not the same as
1473 Also note that the types \c void*, \c long, \c short, \c unsigned
1474 \c long, \c unsigned \c short, \c unsigned \c char, \c float, \c
1475 QObject*, and \c QWidget* are represented in QMetaType::Type but
1476 not in QVariant::Type, and they can be returned by this function.
1477 However, they are considered to be user defined types when tested
1478 against QVariant::Type.
1480 To test whether an instance of QVariant contains a data type that
1481 is compatible with the data type you are interested in, use
1485 QVariant::Type QVariant::type() const
1487 return d.type >= QMetaType::User ? UserType : static_cast<Type>(d.type);
1491 Returns the storage type of the value stored in the variant. For
1492 non-user types, this is the same as type().
1497 int QVariant::userType() const
1503 Assigns the value of the variant \a variant to this variant.
1505 QVariant& QVariant::operator=(const QVariant &variant)
1507 if (this == &variant)
1511 if (variant.d.is_shared) {
1512 variant.d.data.shared->ref.ref();
1514 } else if (variant.d.type > Char) {
1515 d.type = variant.d.type;
1516 handlerManager[d.type]->construct(&d, variant.constData());
1517 d.is_null = variant.d.is_null;
1526 \fn void QVariant::swap(QVariant &other)
1529 Swaps variant \a other with this variant. This operation is very
1530 fast and never fails.
1534 \fn void QVariant::detach()
1539 void QVariant::detach()
1541 if (!d.is_shared || d.data.shared->ref.load() == 1)
1546 handlerManager[d.type]->construct(&dd, constData());
1547 if (!d.data.shared->ref.deref())
1548 handlerManager[d.type]->clear(&d);
1549 d.data.shared = dd.data.shared;
1553 \fn bool QVariant::isDetached() const
1558 // ### Qt 5: change typeName()(and froends= to return a QString. Suggestion from Harald.
1560 Returns the name of the type stored in the variant. The returned
1561 strings describe the C++ datatype used to store the data: for
1562 example, "QFont", "QString", or "QVariantList". An Invalid
1565 const char *QVariant::typeName() const
1567 return typeToName(Type(d.type));
1571 Convert this variant to type Invalid and free up any resources
1574 void QVariant::clear()
1576 if ((d.is_shared && !d.data.shared->ref.deref()) || (!d.is_shared && d.type > Char))
1577 handlerManager[d.type]->clear(&d);
1580 d.is_shared = false;
1584 Converts the enum representation of the storage type, \a typ, to
1585 its string representation.
1587 Returns a null pointer if the type is QVariant::Invalid or doesn't exist.
1589 const char *QVariant::typeToName(Type typ)
1593 if (typ == UserType)
1596 return QMetaType::typeName(typ);
1601 Converts the string representation of the storage type given in \a
1602 name, to its enum representation.
1604 If the string representation cannot be converted to any enum
1605 representation, the variant is set to \c Invalid.
1607 QVariant::Type QVariant::nameToType(const char *name)
1609 if (!name || !*name)
1611 if (strcmp(name, "Q3CString") == 0)
1613 if (strcmp(name, "Q_LLONG") == 0)
1615 if (strcmp(name, "Q_ULLONG") == 0)
1617 if (strcmp(name, "QIconSet") == 0)
1619 if (strcmp(name, "UserType") == 0)
1622 int metaType = QMetaType::type(name);
1623 return metaType <= int(LastGuiType) ? QVariant::Type(metaType) : UserType;
1626 #ifndef QT_NO_DATASTREAM
1627 enum { MapFromThreeCount = 36 };
1628 static const ushort map_from_three[MapFromThreeCount] =
1634 QVariant::StringList,
1650 QVariant::ByteArray,
1655 QVariant::SizePolicy,
1659 QVariant::ByteArray,
1661 QVariant::KeySequence,
1664 QVariant::ULongLong,
1665 QVariant::EasingCurve
1669 Internal function for loading a variant from stream \a s. Use the
1670 stream operators instead.
1674 void QVariant::load(QDataStream &s)
1680 if (s.version() < QDataStream::Qt_4_0) {
1681 if (u >= MapFromThreeCount)
1683 u = map_from_three[u];
1685 qint8 is_null = false;
1686 if (s.version() >= QDataStream::Qt_4_2)
1688 if (u == QVariant::UserType) {
1691 u = QMetaType::type(name);
1693 s.setStatus(QDataStream::ReadCorruptData);
1697 create(static_cast<int>(u), 0);
1698 d.is_null = is_null;
1701 // Since we wrote something, we should read something
1708 // const cast is safe since we operate on a newly constructed variant
1709 if (!QMetaType::load(s, d.type, const_cast<void *>(constData()))) {
1710 s.setStatus(QDataStream::ReadCorruptData);
1711 qWarning("QVariant::load: unable to load type %d.", d.type);
1716 Internal function for saving a variant to the stream \a s. Use the
1717 stream operators instead.
1721 void QVariant::save(QDataStream &s) const
1723 quint32 tp = type();
1724 if (s.version() < QDataStream::Qt_4_0) {
1726 for (i = MapFromThreeCount - 1; i >= 0; i--) {
1727 if (map_from_three[i] == tp) {
1738 if (s.version() >= QDataStream::Qt_4_2)
1739 s << qint8(d.is_null);
1740 if (tp == QVariant::UserType) {
1741 s << QMetaType::typeName(userType());
1749 if (!QMetaType::save(s, d.type, constData())) {
1750 Q_ASSERT_X(false, "QVariant::save", "Invalid type to save");
1751 qWarning("QVariant::save: unable to save type %d.", d.type);
1758 Reads a variant \a p from the stream \a s.
1760 \sa \link datastreamformat.html Format of the QDataStream
1763 QDataStream& operator>>(QDataStream &s, QVariant &p)
1770 Writes a variant \a p to the stream \a s.
1772 \sa \link datastreamformat.html Format of the QDataStream
1775 QDataStream& operator<<(QDataStream &s, const QVariant &p)
1782 Reads a variant type \a p in enum representation from the stream \a s.
1784 QDataStream& operator>>(QDataStream &s, QVariant::Type &p)
1788 p = (QVariant::Type)u;
1794 Writes a variant type \a p to the stream \a s.
1796 QDataStream& operator<<(QDataStream &s, const QVariant::Type p)
1798 s << static_cast<quint32>(p);
1803 #endif //QT_NO_DATASTREAM
1806 \fn bool QVariant::isValid() const
1808 Returns true if the storage type of this variant is not
1809 QVariant::Invalid; otherwise returns false.
1812 template <typename T>
1813 inline T qVariantToHelper(const QVariant::Private &d, const HandlersManager &handlerManager)
1815 const QVariant::Type targetType = static_cast<const QVariant::Type>(qMetaTypeId<T>());
1816 if (d.type == targetType)
1817 return *v_cast<T>(&d);
1820 handlerManager[d.type]->convert(&d, targetType, &ret, 0);
1825 \fn QStringList QVariant::toStringList() const
1827 Returns the variant as a QStringList if the variant has type()
1828 StringList, \l String, or \l List of a type that can be converted
1829 to QString; otherwise returns an empty list.
1831 \sa canConvert(), convert()
1833 QStringList QVariant::toStringList() const
1835 return qVariantToHelper<QStringList>(d, handlerManager);
1839 Returns the variant as a QString if the variant has type() \l
1840 String, \l Bool, \l ByteArray, \l Char, \l Date, \l DateTime, \l
1841 Double, \l Int, \l LongLong, \l StringList, \l Time, \l UInt, or
1842 \l ULongLong; otherwise returns an empty string.
1844 \sa canConvert(), convert()
1846 QString QVariant::toString() const
1848 return qVariantToHelper<QString>(d, handlerManager);
1852 Returns the variant as a QMap<QString, QVariant> if the variant
1853 has type() \l Map; otherwise returns an empty map.
1855 \sa canConvert(), convert()
1857 QVariantMap QVariant::toMap() const
1859 return qVariantToHelper<QVariantMap>(d, handlerManager);
1863 Returns the variant as a QHash<QString, QVariant> if the variant
1864 has type() \l Hash; otherwise returns an empty map.
1866 \sa canConvert(), convert()
1868 QVariantHash QVariant::toHash() const
1870 return qVariantToHelper<QVariantHash>(d, handlerManager);
1874 \fn QDate QVariant::toDate() const
1876 Returns the variant as a QDate if the variant has type() \l Date,
1877 \l DateTime, or \l String; otherwise returns an invalid date.
1879 If the type() is \l String, an invalid date will be returned if the
1880 string cannot be parsed as a Qt::ISODate format date.
1882 \sa canConvert(), convert()
1884 QDate QVariant::toDate() const
1886 return qVariantToHelper<QDate>(d, handlerManager);
1890 \fn QTime QVariant::toTime() const
1892 Returns the variant as a QTime if the variant has type() \l Time,
1893 \l DateTime, or \l String; otherwise returns an invalid time.
1895 If the type() is \l String, an invalid time will be returned if
1896 the string cannot be parsed as a Qt::ISODate format time.
1898 \sa canConvert(), convert()
1900 QTime QVariant::toTime() const
1902 return qVariantToHelper<QTime>(d, handlerManager);
1906 \fn QDateTime QVariant::toDateTime() const
1908 Returns the variant as a QDateTime if the variant has type() \l
1909 DateTime, \l Date, or \l String; otherwise returns an invalid
1912 If the type() is \l String, an invalid date/time will be returned
1913 if the string cannot be parsed as a Qt::ISODate format date/time.
1915 \sa canConvert(), convert()
1917 QDateTime QVariant::toDateTime() const
1919 return qVariantToHelper<QDateTime>(d, handlerManager);
1924 \fn QEasingCurve QVariant::toEasingCurve() const
1926 Returns the variant as a QEasingCurve if the variant has type() \l
1927 EasingCurve; otherwise returns a default easing curve.
1929 \sa canConvert(), convert()
1931 #ifndef QT_BOOTSTRAPPED
1932 QEasingCurve QVariant::toEasingCurve() const
1934 return qVariantToHelper<QEasingCurve>(d, handlerManager);
1939 \fn QByteArray QVariant::toByteArray() const
1941 Returns the variant as a QByteArray if the variant has type() \l
1942 ByteArray or \l String (converted using QString::fromAscii());
1943 otherwise returns an empty byte array.
1945 \sa canConvert(), convert()
1947 QByteArray QVariant::toByteArray() const
1949 return qVariantToHelper<QByteArray>(d, handlerManager);
1952 #ifndef QT_NO_GEOM_VARIANT
1954 \fn QPoint QVariant::toPoint() const
1956 Returns the variant as a QPoint if the variant has type()
1957 \l Point or \l PointF; otherwise returns a null QPoint.
1959 \sa canConvert(), convert()
1961 QPoint QVariant::toPoint() const
1963 return qVariantToHelper<QPoint>(d, handlerManager);
1967 \fn QRect QVariant::toRect() const
1969 Returns the variant as a QRect if the variant has type() \l Rect;
1970 otherwise returns an invalid QRect.
1972 \sa canConvert(), convert()
1974 QRect QVariant::toRect() const
1976 return qVariantToHelper<QRect>(d, handlerManager);
1980 \fn QSize QVariant::toSize() const
1982 Returns the variant as a QSize if the variant has type() \l Size;
1983 otherwise returns an invalid QSize.
1985 \sa canConvert(), convert()
1987 QSize QVariant::toSize() const
1989 return qVariantToHelper<QSize>(d, handlerManager);
1993 \fn QSizeF QVariant::toSizeF() const
1995 Returns the variant as a QSizeF if the variant has type() \l
1996 SizeF; otherwise returns an invalid QSizeF.
1998 \sa canConvert(), convert()
2000 QSizeF QVariant::toSizeF() const
2002 return qVariantToHelper<QSizeF>(d, handlerManager);
2006 \fn QRectF QVariant::toRectF() const
2008 Returns the variant as a QRectF if the variant has type() \l Rect
2009 or \l RectF; otherwise returns an invalid QRectF.
2011 \sa canConvert(), convert()
2013 QRectF QVariant::toRectF() const
2015 return qVariantToHelper<QRectF>(d, handlerManager);
2019 \fn QLineF QVariant::toLineF() const
2021 Returns the variant as a QLineF if the variant has type() \l
2022 LineF; otherwise returns an invalid QLineF.
2024 \sa canConvert(), convert()
2026 QLineF QVariant::toLineF() const
2028 return qVariantToHelper<QLineF>(d, handlerManager);
2032 \fn QLine QVariant::toLine() const
2034 Returns the variant as a QLine if the variant has type() \l Line;
2035 otherwise returns an invalid QLine.
2037 \sa canConvert(), convert()
2039 QLine QVariant::toLine() const
2041 return qVariantToHelper<QLine>(d, handlerManager);
2045 \fn QPointF QVariant::toPointF() const
2047 Returns the variant as a QPointF if the variant has type() \l
2048 Point or \l PointF; otherwise returns a null QPointF.
2050 \sa canConvert(), convert()
2052 QPointF QVariant::toPointF() const
2054 return qVariantToHelper<QPointF>(d, handlerManager);
2057 #endif // QT_NO_GEOM_VARIANT
2060 \fn QUrl QVariant::toUrl() const
2062 Returns the variant as a QUrl if the variant has type()
2063 \l Url; otherwise returns an invalid QUrl.
2065 \sa canConvert(), convert()
2067 QUrl QVariant::toUrl() const
2069 return qVariantToHelper<QUrl>(d, handlerManager);
2073 \fn QLocale QVariant::toLocale() const
2075 Returns the variant as a QLocale if the variant has type()
2076 \l Locale; otherwise returns an invalid QLocale.
2078 \sa canConvert(), convert()
2080 QLocale QVariant::toLocale() const
2082 return qVariantToHelper<QLocale>(d, handlerManager);
2086 \fn QRegExp QVariant::toRegExp() const
2089 Returns the variant as a QRegExp if the variant has type() \l
2090 RegExp; otherwise returns an empty QRegExp.
2092 \sa canConvert(), convert()
2094 #ifndef QT_NO_REGEXP
2095 QRegExp QVariant::toRegExp() const
2097 return qVariantToHelper<QRegExp>(d, handlerManager);
2102 \fn QChar QVariant::toChar() const
2104 Returns the variant as a QChar if the variant has type() \l Char,
2105 \l Int, or \l UInt; otherwise returns an invalid QChar.
2107 \sa canConvert(), convert()
2109 QChar QVariant::toChar() const
2111 return qVariantToHelper<QChar>(d, handlerManager);
2115 Returns the variant as a QBitArray if the variant has type()
2116 \l BitArray; otherwise returns an empty bit array.
2118 \sa canConvert(), convert()
2120 QBitArray QVariant::toBitArray() const
2122 return qVariantToHelper<QBitArray>(d, handlerManager);
2125 template <typename T>
2126 inline T qNumVariantToHelper(const QVariant::Private &d,
2127 const HandlersManager &handlerManager, bool *ok, const T& val)
2129 uint t = qMetaTypeId<T>();
2136 if (!handlerManager[d.type]->convert(&d, QVariant::Type(t), &ret, ok) && ok)
2142 Returns the variant as an int if the variant has type() \l Int,
2143 \l Bool, \l ByteArray, \l Char, \l Double, \l LongLong, \l
2144 String, \l UInt, or \l ULongLong; otherwise returns 0.
2146 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2147 converted to an int; otherwise \c{*}\a{ok} is set to false.
2149 \bold{Warning:} If the value is convertible to a \l LongLong but is too
2150 large to be represented in an int, the resulting arithmetic overflow will
2151 not be reflected in \a ok. A simple workaround is to use QString::toInt().
2152 Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
2154 \sa canConvert(), convert()
2156 int QVariant::toInt(bool *ok) const
2158 return qNumVariantToHelper<int>(d, handlerManager, ok, d.data.i);
2162 Returns the variant as an unsigned int if the variant has type()
2163 \l UInt, \l Bool, \l ByteArray, \l Char, \l Double, \l Int, \l
2164 LongLong, \l String, or \l ULongLong; otherwise returns 0.
2166 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2167 converted to an unsigned int; otherwise \c{*}\a{ok} is set to false.
2169 \bold{Warning:} If the value is convertible to a \l ULongLong but is too
2170 large to be represented in an unsigned int, the resulting arithmetic overflow will
2171 not be reflected in \a ok. A simple workaround is to use QString::toUInt().
2172 Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
2174 \sa canConvert(), convert()
2176 uint QVariant::toUInt(bool *ok) const
2178 return qNumVariantToHelper<uint>(d, handlerManager, ok, d.data.u);
2182 Returns the variant as a long long int if the variant has type()
2183 \l LongLong, \l Bool, \l ByteArray, \l Char, \l Double, \l Int,
2184 \l String, \l UInt, or \l ULongLong; otherwise returns 0.
2186 If \a ok is non-null: \c{*}\c{ok} is set to true if the value could be
2187 converted to an int; otherwise \c{*}\c{ok} is set to false.
2189 \sa canConvert(), convert()
2191 qlonglong QVariant::toLongLong(bool *ok) const
2193 return qNumVariantToHelper<qlonglong>(d, handlerManager, ok, d.data.ll);
2197 Returns the variant as as an unsigned long long int if the
2198 variant has type() \l ULongLong, \l Bool, \l ByteArray, \l Char,
2199 \l Double, \l Int, \l LongLong, \l String, or \l UInt; otherwise
2202 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2203 converted to an int; otherwise \c{*}\a{ok} is set to false.
2205 \sa canConvert(), convert()
2207 qulonglong QVariant::toULongLong(bool *ok) const
2209 return qNumVariantToHelper<qulonglong>(d, handlerManager, ok, d.data.ull);
2213 Returns the variant as a bool if the variant has type() Bool.
2215 Returns true if the variant has type() \l Bool, \l Char, \l Double,
2216 \l Int, \l LongLong, \l UInt, or \l ULongLong and the value is
2217 non-zero, or if the variant has type \l String or \l ByteArray and
2218 its lower-case content is not empty, "0" or "false"; otherwise
2221 \sa canConvert(), convert()
2223 bool QVariant::toBool() const
2229 handlerManager[d.type]->convert(&d, Bool, &res, 0);
2235 Returns the variant as a double if the variant has type() \l
2236 Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
2237 UInt, or \l ULongLong; otherwise returns 0.0.
2239 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2240 converted to a double; otherwise \c{*}\a{ok} is set to false.
2242 \sa canConvert(), convert()
2244 double QVariant::toDouble(bool *ok) const
2246 return qNumVariantToHelper<double>(d, handlerManager, ok, d.data.d);
2250 Returns the variant as a float if the variant has type() \l
2251 Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
2252 UInt, or \l ULongLong; otherwise returns 0.0.
2256 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2257 converted to a double; otherwise \c{*}\a{ok} is set to false.
2259 \sa canConvert(), convert()
2261 float QVariant::toFloat(bool *ok) const
2263 return qNumVariantToHelper<float>(d, handlerManager, ok, d.data.f);
2267 Returns the variant as a qreal if the variant has type() \l
2268 Double, \l QMetaType::Float, \l Bool, \l ByteArray, \l Int, \l LongLong, \l String, \l
2269 UInt, or \l ULongLong; otherwise returns 0.0.
2273 If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
2274 converted to a double; otherwise \c{*}\a{ok} is set to false.
2276 \sa canConvert(), convert()
2278 qreal QVariant::toReal(bool *ok) const
2280 return qNumVariantToHelper<qreal>(d, handlerManager, ok, d.data.real);
2284 Returns the variant as a QVariantList if the variant has type()
2285 \l List or \l StringList; otherwise returns an empty list.
2287 \sa canConvert(), convert()
2289 QVariantList QVariant::toList() const
2291 return qVariantToHelper<QVariantList>(d, handlerManager);
2295 static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
2299 /*Bool*/ 1 << QVariant::Double | 1 << QVariant::Int | 1 << QVariant::UInt
2300 | 1 << QVariant::LongLong | 1 << QVariant::ULongLong | 1 << QVariant::ByteArray
2301 | 1 << QVariant::String | 1 << QVariant::Char,
2303 /*Int*/ 1 << QVariant::UInt | 1 << QVariant::String | 1 << QVariant::Double
2304 | 1 << QVariant::Bool | 1 << QVariant::LongLong | 1 << QVariant::ULongLong
2305 | 1 << QVariant::Char | 1 << QVariant::ByteArray,
2307 /*UInt*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::Double
2308 | 1 << QVariant::Bool | 1 << QVariant::LongLong | 1 << QVariant::ULongLong
2309 | 1 << QVariant::Char | 1 << QVariant::ByteArray,
2311 /*LLong*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::Double
2312 | 1 << QVariant::Bool | 1 << QVariant::UInt | 1 << QVariant::ULongLong
2313 | 1 << QVariant::Char | 1 << QVariant::ByteArray,
2315 /*ULlong*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::Double
2316 | 1 << QVariant::Bool | 1 << QVariant::UInt | 1 << QVariant::LongLong
2317 | 1 << QVariant::Char | 1 << QVariant::ByteArray,
2319 /*double*/ 1 << QVariant::Int | 1 << QVariant::String | 1 << QVariant::ULongLong
2320 | 1 << QVariant::Bool | 1 << QVariant::UInt | 1 << QVariant::LongLong
2321 | 1 << QVariant::ByteArray,
2323 /*QChar*/ 1 << QVariant::Int | 1 << QVariant::UInt | 1 << QVariant::LongLong
2324 | 1 << QVariant::ULongLong,
2328 /*QList*/ 1 << QVariant::StringList,
2330 /*QString*/ 1 << QVariant::StringList | 1 << QVariant::ByteArray | 1 << QVariant::Int
2331 | 1 << QVariant::UInt | 1 << QVariant::Bool | 1 << QVariant::Double
2332 | 1 << QVariant::Date | 1 << QVariant::Time | 1 << QVariant::DateTime
2333 | 1 << QVariant::LongLong | 1 << QVariant::ULongLong | 1 << QVariant::Char
2334 | 1 << QVariant::Url | 1 << QVariant::Uuid,
2336 /*QStringList*/ 1 << QVariant::List | 1 << QVariant::String,
2338 /*QByteArray*/ 1 << QVariant::String | 1 << QVariant::Int | 1 << QVariant::UInt | 1 << QVariant::Bool
2339 | 1 << QVariant::Double | 1 << QVariant::LongLong | 1 << QVariant::ULongLong,
2343 /*QDate*/ 1 << QVariant::String | 1 << QVariant::DateTime,
2345 /*QTime*/ 1 << QVariant::String | 1 << QVariant::DateTime,
2347 /*QDateTime*/ 1 << QVariant::String | 1 << QVariant::Date,
2349 /*QUrl*/ 1 << QVariant::String,
2353 /*QRect*/ 1 << QVariant::RectF,
2355 /*QRectF*/ 1 << QVariant::Rect,
2357 /*QSize*/ 1 << QVariant::SizeF,
2359 /*QSizeF*/ 1 << QVariant::Size,
2361 /*QLine*/ 1 << QVariant::LineF,
2363 /*QLineF*/ 1 << QVariant::Line,
2365 /*QPoint*/ 1 << QVariant::PointF,
2367 /*QPointF*/ 1 << QVariant::Point,
2375 /*QUuid*/ 1 << QVariant::String
2379 Returns true if the variant's type can be cast to the requested
2380 type, \a t. Such casting is done automatically when calling the
2381 toInt(), toBool(), ... methods.
2383 The following casts are done automatically:
2386 \header \o Type \o Automatically Cast To
2387 \row \o \l Bool \o \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
2388 \row \o \l ByteArray \o \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
2389 \row \o \l Char \o \l Bool, \l Int, \l UInt, \l LongLong, \l ULongLong
2390 \row \o \l Color \o \l String
2391 \row \o \l Date \o \l DateTime, \l String
2392 \row \o \l DateTime \o \l Date, \l String, \l Time
2393 \row \o \l Double \o \l Bool, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
2394 \row \o \l Font \o \l String
2395 \row \o \l Int \o \l Bool, \l Char, \l Double, \l LongLong, \l String, \l UInt, \l ULongLong
2396 \row \o \l KeySequence \o \l Int, \l String
2397 \row \o \l List \o \l StringList (if the list's items can be converted to strings)
2398 \row \o \l LongLong \o \l Bool, \l ByteArray, \l Char, \l Double, \l Int, \l String, \l UInt, \l ULongLong
2399 \row \o \l Point \o PointF
2400 \row \o \l Rect \o RectF
2401 \row \o \l String \o \l Bool, \l ByteArray, \l Char, \l Color, \l Date, \l DateTime, \l Double,
2402 \l Font, \l Int, \l KeySequence, \l LongLong, \l StringList, \l Time, \l UInt,
2404 \row \o \l StringList \o \l List, \l String (if the list contains exactly one item)
2405 \row \o \l Time \o \l String
2406 \row \o \l UInt \o \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l ULongLong
2407 \row \o \l ULongLong \o \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt
2412 bool QVariant::canConvert(Type t) const
2414 //we can treat floats as double
2415 //the reason for not doing it the "proper" way is that QMetaType::Float's value is 135,
2416 //which can't be handled by qCanConvertMatrix
2417 //In addition QVariant::Type doesn't have a Float value, so we're using QMetaType::Float
2418 const uint currentType = ((d.type == QMetaType::Float) ? QVariant::Double : d.type);
2419 if (uint(t) == uint(QMetaType::Float)) t = QVariant::Double;
2421 if (currentType == uint(t))
2424 if (currentType > QVariant::LastCoreType || t > QVariant::LastCoreType) {
2427 return currentType == QVariant::KeySequence
2428 || currentType == QMetaType::ULong
2429 || currentType == QMetaType::Long
2430 || currentType == QMetaType::UShort
2431 || currentType == QMetaType::UChar
2432 || currentType == QMetaType::Char
2433 || currentType == QMetaType::Short;
2434 case QVariant::Image:
2435 return currentType == QVariant::Pixmap || currentType == QVariant::Bitmap;
2436 case QVariant::Pixmap:
2437 return currentType == QVariant::Image || currentType == QVariant::Bitmap
2438 || currentType == QVariant::Brush;
2439 case QVariant::Bitmap:
2440 return currentType == QVariant::Pixmap || currentType == QVariant::Image;
2441 case QVariant::ByteArray:
2442 return currentType == QVariant::Color;
2443 case QVariant::String:
2444 return currentType == QVariant::KeySequence || currentType == QVariant::Font
2445 || currentType == QVariant::Color;
2446 case QVariant::KeySequence:
2447 return currentType == QVariant::String || currentType == QVariant::Int;
2448 case QVariant::Font:
2449 return currentType == QVariant::String;
2450 case QVariant::Color:
2451 return currentType == QVariant::String || currentType == QVariant::ByteArray
2452 || currentType == QVariant::Brush;
2453 case QVariant::Brush:
2454 return currentType == QVariant::Color || currentType == QVariant::Pixmap;
2455 case QMetaType::Long:
2456 case QMetaType::Char:
2457 case QMetaType::UChar:
2458 case QMetaType::ULong:
2459 case QMetaType::Short:
2460 case QMetaType::UShort:
2461 return qCanConvertMatrix[QVariant::Int] & (1 << currentType) || currentType == QVariant::Int;
2467 if(t == String && currentType == StringList)
2468 return v_cast<QStringList>(&d)->count() == 1;
2470 return qCanConvertMatrix[t] & (1 << currentType);
2474 Casts the variant to the requested type, \a t. If the cast cannot be
2475 done, the variant is cleared. Returns true if the current type of
2476 the variant was successfully cast; otherwise returns false.
2478 \warning For historical reasons, converting a null QVariant results
2479 in a null value of the desired type (e.g., an empty string for
2480 QString) and a result of false.
2482 \sa canConvert(), clear()
2485 bool QVariant::convert(Type t)
2487 if (d.type == uint(t))
2490 QVariant oldValue = *this;
2493 if (!oldValue.canConvert(t))
2497 if (oldValue.isNull())
2501 if (!handlerManager[d.type]->convert(&oldValue.d, t, data(), &isOk))
2508 \fn convert(const int type, void *ptr) const
2510 Created for qvariant_cast() usage
2512 bool QVariant::convert(const int type, void *ptr) const
2514 Q_ASSERT(type < int(QMetaType::User));
2515 return handlerManager[type]->convert(&d, QVariant::Type(type), ptr, 0);
2520 \fn bool operator==(const QVariant &v1, const QVariant &v2)
2524 Returns true if \a v1 and \a v2 are equal; otherwise returns false.
2526 \warning This function doesn't support custom types registered
2527 with qRegisterMetaType().
2530 \fn bool operator!=(const QVariant &v1, const QVariant &v2)
2534 Returns false if \a v1 and \a v2 are equal; otherwise returns true.
2536 \warning This function doesn't support custom types registered
2537 with qRegisterMetaType().
2540 /*! \fn bool QVariant::operator==(const QVariant &v) const
2542 Compares this QVariant with \a v and returns true if they are
2543 equal; otherwise returns false.
2545 In the case of custom types, their equalness operators are not called.
2546 Instead the values' addresses are compared.
2550 \fn bool QVariant::operator!=(const QVariant &v) const
2552 Compares this QVariant with \a v and returns true if they are not
2553 equal; otherwise returns false.
2555 \warning This function doesn't support custom types registered
2556 with qRegisterMetaType().
2559 static bool qIsNumericType(uint tp)
2561 return (tp >= QVariant::Bool && tp <= QVariant::Double)
2562 || (tp >= QMetaType::Long && tp <= QMetaType::Float);
2565 static bool qIsFloatingPoint(uint tp)
2567 return tp == QVariant::Double || tp == QMetaType::Float;
2572 bool QVariant::cmp(const QVariant &v) const
2575 if (d.type != v2.d.type) {
2576 if (qIsNumericType(d.type) && qIsNumericType(v.d.type)) {
2577 if (qIsFloatingPoint(d.type) || qIsFloatingPoint(v.d.type))
2578 return qFuzzyCompare(toReal(), v.toReal());
2580 return toLongLong() == v.toLongLong();
2582 if (!v2.canConvert(Type(d.type)) || !v2.convert(Type(d.type)))
2585 return handlerManager[d.type]->compare(&d, &v2.d);
2591 const void *QVariant::constData() const
2593 return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr);
2597 \fn const void* QVariant::data() const
2603 void* QVariant::data()
2606 return const_cast<void *>(constData());
2611 Returns true if this is a NULL variant, false otherwise.
2613 bool QVariant::isNull() const
2615 return handlerManager[d.type]->isNull(&d);
2618 #ifndef QT_NO_DEBUG_STREAM
2619 QDebug operator<<(QDebug dbg, const QVariant &v)
2621 #ifndef Q_BROKEN_DEBUG_STREAM
2622 dbg.nospace() << "QVariant(" << QMetaType::typeName(v.userType()) << ", ";
2623 handlerManager[v.d.type]->debugStream(dbg, v);
2624 dbg.nospace() << ')';
2627 qWarning("This compiler doesn't support streaming QVariant to QDebug");
2633 QDebug operator<<(QDebug dbg, const QVariant::Type p)
2635 #ifndef Q_BROKEN_DEBUG_STREAM
2636 dbg.nospace() << "QVariant::" << QMetaType::typeName(p);
2639 qWarning("This compiler doesn't support streaming QVariant::Type to QDebug");
2647 /*! \fn void QVariant::setValue(const T &value)
2649 Stores a copy of \a value. If \c{T} is a type that QVariant
2650 doesn't support, QMetaType is used to store the value. A compile
2651 error will occur if QMetaType doesn't handle the type.
2655 \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 4
2657 \sa value(), fromValue(), canConvert()
2660 /*! \fn T QVariant::value() const
2662 Returns the stored value converted to the template type \c{T}.
2663 Call canConvert() to find out whether a type can be converted.
2664 If the value cannot be converted, \l{default-constructed value}
2667 If the type \c{T} is supported by QVariant, this function behaves
2668 exactly as toString(), toInt() etc.
2672 \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 5
2674 \sa setValue(), fromValue(), canConvert()
2677 /*! \fn bool QVariant::canConvert() const
2679 Returns true if the variant can be converted to the template type \c{T},
2684 \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 6
2689 /*! \fn static QVariant QVariant::fromValue(const T &value)
2691 Returns a QVariant containing a copy of \a value. Behaves
2692 exactly like setValue() otherwise.
2696 \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 7
2698 \note If you are working with custom types, you should use
2699 the Q_DECLARE_METATYPE() macro to register your custom type.
2701 \sa setValue(), value()
2705 \fn QVariant qVariantFromValue(const T &value)
2709 Returns a variant containing a copy of the given \a value
2710 with template type \c{T}.
2712 This function is equivalent to QVariant::fromValue(\a value).
2714 \note This function was provided as a workaround for MSVC 6
2715 which did not support member template functions. It is advised
2716 to use the other form in new code.
2718 For example, a QObject pointer can be stored in a variant with the
2721 \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 8
2723 \sa QVariant::fromValue()
2726 /*! \fn void qVariantSetValue(QVariant &variant, const T &value)
2730 Sets the contents of the given \a variant to a copy of the
2731 \a value with the specified template type \c{T}.
2733 This function is equivalent to QVariant::setValue(\a value).
2735 \note This function was provided as a workaround for MSVC 6
2736 which did not support member template functions. It is advised
2737 to use the other form in new code.
2739 \sa QVariant::setValue()
2743 \fn T qvariant_cast(const QVariant &value)
2746 Returns the given \a value converted to the template type \c{T}.
2748 This function is equivalent to QVariant::value().
2750 \sa QVariant::value()
2753 /*! \fn T qVariantValue(const QVariant &value)
2757 Returns the given \a value converted to the template type \c{T}.
2759 This function is equivalent to
2760 \l{QVariant::value()}{QVariant::value}<T>(\a value).
2762 \note This function was provided as a workaround for MSVC 6
2763 which did not support member template functions. It is advised
2764 to use the other form in new code.
2766 \sa QVariant::value(), qvariant_cast()
2769 /*! \fn bool qVariantCanConvert(const QVariant &value)
2773 Returns true if the given \a value can be converted to the
2774 template type specified; otherwise returns false.
2776 This function is equivalent to QVariant::canConvert(\a value).
2778 \note This function was provided as a workaround for MSVC 6
2779 which did not support member template functions. It is advised
2780 to use the other form in new code.
2782 \sa QVariant::canConvert()
2786 \typedef QVariantList
2789 Synonym for QList<QVariant>.
2793 \typedef QVariantMap
2796 Synonym for QMap<QString, QVariant>.
2800 \typedef QVariantHash
2804 Synonym for QHash<QString, QVariant>.
2808 \typedef QVariant::DataPtr
2813 \fn DataPtr &QVariant::data_ptr()