首页 > 代码库 > QVariant相当于一个包含大多数Qt数据类型的联合体(源码解读)
QVariant相当于一个包含大多数Qt数据类型的联合体(源码解读)
将数据存储为一个Private结构体类型的成员变量d:
<qvariant.cpp>
1 QVariant::QVariant(Type type)2 { create(type, 0); }
1 void QVariant::create(int type, const void *copy)2 {3 d.type = type;4 handler->construct(&d, copy);5 }
static void construct(QVariant::Private *x, const void *copy){ x->is_shared = false; switch (x->type) { case QVariant::String: v_construct<QString>(x, copy); break; ...... default: void *ptr = QMetaType::construct(x->type, copy); if (!ptr) { x->type = QVariant::Invalid; } else { x->is_shared = true; x->data.shared = new QVariant::PrivateShared(ptr); } break; } x->is_null = !copy;}
1 QVariant::QVariant(int val)2 { d.is_null = false; d.type = Int; d.data.i = val; }
<qvariant.h>
class Q_CORE_EXPORT QVariant{ ...... struct Private { inline Private(): type(Invalid), is_shared(false), is_null(true) { data.ptr = 0; } inline Private(const Private &other) : data(other.data), type(other.type), is_shared(other.is_shared), is_null(other.is_null) {} union Data { char c; int i; uint u; bool b; double d; float f; qreal real; qlonglong ll; qulonglong ull; QObject *o; void *ptr; PrivateShared *shared; } data; uint type : 30; uint is_shared : 1; uint is_null : 1; }; ...... Private d; ......}
QVariant支持的数据类型:
1 enum Type { 2 Invalid = 0, 3 4 Bool = 1, 5 Int = 2, 6 UInt = 3, 7 LongLong = 4, 8 ULongLong = 5, 9 Double = 6,10 Char = 7,11 Map = 8,12 List = 9,13 String = 10,14 StringList = 11,15 ByteArray = 12,16 BitArray = 13,17 Date = 14,18 Time = 15,19 DateTime = 16,20 Url = 17,21 Locale = 18,22 Rect = 19,23 RectF = 20,24 Size = 21,25 SizeF = 22,26 Line = 23,27 LineF = 24,28 Point = 25,29 PointF = 26,30 RegExp = 27,31 Hash = 28,32 EasingCurve = 29,33 LastCoreType = EasingCurve,34 35 // value 62 is internally reserved36 #ifdef QT3_SUPPORT37 ColorGroup = 63,38 #endif39 Font = 64,40 Pixmap = 65,41 Brush = 66,42 Color = 67,43 Palette = 68,44 Icon = 69,45 Image = 70,46 Polygon = 71,47 Region = 72,48 Bitmap = 73,49 Cursor = 74,50 SizePolicy = 75,51 KeySequence = 76,52 Pen = 77,53 TextLength = 78,54 TextFormat = 79,55 Matrix = 80,56 Transform = 81,57 Matrix4x4 = 82,58 Vector2D = 83,59 Vector3D = 84,60 Vector4D = 85,61 Quaternion = 86,62 LastGuiType = Quaternion,63 64 UserType = 127,65 #ifdef QT3_SUPPORT66 IconSet = Icon,67 CString = ByteArray,68 PointArray = Polygon,69 #endif70 LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type71 };
数据类型转换:
以下数据类型可以自动转换
可通过成员函数bool QVariant::canConvert ( Type t ) const确定是否可执行指定数据类型的转换
自定义QVariant可存储的数据类型:
class Q_CORE_EXPORT QVariant{ ...... template<typename T> bool canConvert() const { return canConvert(Type(qMetaTypeId<T>())); } ......}
1 static inline QVariant fromValue(const T &value)2 { return qVariantFromValue(value); }
template <typename T>inline QVariant qVariantFromValue(const T &t){ return QVariant(qMetaTypeId<T>(reinterpret_cast<T *>(0)), &t, QTypeInfo<T>::isPointer);}
从类的声明中可以看出,要成为QVariant可存储的数据类型,必须将该自定义数据类型通过宏Q_DECLARE_METATYPE (Type)注册到MetaType系统中
<qmetatype.h>
1 #define Q_DECLARE_METATYPE(TYPE) 2 QT_BEGIN_NAMESPACE 3 template <> 4 struct QMetaTypeId< TYPE > 5 { 6 enum { Defined = 1 }; 7 static int qt_metatype_id() 8 { 9 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); 10 if (!metatype_id) 11 metatype_id = qRegisterMetaType< TYPE >(#TYPE, 12 reinterpret_cast< TYPE *>(quintptr(-1))); 13 return metatype_id; 14 } 15 }; 16 QT_END_NAMESPACE
示例:
namespace MyNamespace{ struct MyStruct { int i; ... };} Q_DECLARE_METATYPE(MyNamespace::MyStruct)
1 MyStruct s; 2 QVariant var; 3 var.setValue(s); 4 5 ...... 6 7 QVariant var2 = QVariant::fromValue(s); 8 if (var2.canConvert<MyStruct>()) 9 {10 MyStruct s2 = var2.value<MyStruct>();11 }
http://www.cnblogs.com/paullam/p/3706371.html
QVariant相当于一个包含大多数Qt数据类型的联合体(源码解读)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。