QVariant相当于一个包含大多数Qt数据类型的联合体
将数据存储为一个Private结构体类型的成员变量d:
<qvariant.cpp>
QVariant::QVariant(Type type)
{ 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;
}
QVariant::QVariant(int val)
{ 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支持的数据类型:
enum Type {
Invalid = 0,
Bool = 1,
Int = 2,
UInt = 3,
LongLong = 4,
ULongLong = 5,
Double = 6,
Char = 7,
Map = 8,
List = 9,
String = 10,
StringList = 11,
ByteArray = 12,
BitArray = 13,
Date = 14,
Time = 15,
DateTime = 16,
Url = 17,
Locale = 18,
Rect = 19,
RectF = 20,
Size = 21,
SizeF = 22,
Line = 23,
LineF = 24,
Point = 25,
PointF = 26,
RegExp = 27,
Hash = 28,
EasingCurve = 29,
LastCoreType = EasingCurve,
// value 62 is internally reserved
#ifdef QT3_SUPPORT
ColorGroup = 63,
#endif
Font = 64,
Pixmap = 65,
Brush = 66,
Color = 67,
Palette = 68,
Icon = 69,
Image = 70,
Polygon = 71,
Region = 72,
Bitmap = 73,
Cursor = 74,
SizePolicy = 75,
KeySequence = 76,
Pen = 77,
TextLength = 78,
TextFormat = 79,
Matrix = 80,
Transform = 81,
Matrix4x4 = 82,
Vector2D = 83,
Vector3D = 84,
Vector4D = 85,
Quaternion = 86,
LastGuiType = Quaternion,
UserType = 127,
#ifdef QT3_SUPPORT
IconSet = Icon,
CString = ByteArray,
PointArray = Polygon,
#endif
LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
};
数据类型转换:
以下数据类型可以自动转换
可通过成员函数bool QVariant::canConvert ( Type t ) const确定是否可执行指定数据类型的转换
自定义QVariant可存储的数据类型:
class Q_CORE_EXPORT QVariant
{
......
template<typename T>
bool canConvert() const
{ return canConvert(Type(qMetaTypeId<T>())); }
......
}
static inline QVariant fromValue(const T &value)
{ 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>
#define Q_DECLARE_METATYPE(TYPE) \
QT_BEGIN_NAMESPACE \
template <> \
struct QMetaTypeId< TYPE > \
{ \
enum { Defined = 1 }; \
static int qt_metatype_id() \
{ \
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
if (!metatype_id) \
metatype_id = qRegisterMetaType< TYPE >(#TYPE, \
reinterpret_cast< TYPE *>(quintptr(-1))); \
return metatype_id; \
} \
}; \
QT_END_NAMESPACE
示例:
namespace MyNamespace
{
struct MyStruct
{
int i;
...
};
}
Q_DECLARE_METATYPE(MyNamespace::MyStruct)
MyStruct s;
QVariant var;
var.setValue(s);
......
QVariant var2 = QVariant::fromValue(s);
if (var2.canConvert<MyStruct>())
{
MyStruct s2 = var2.value<MyStruct>();
}
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓