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 reserved
36 #ifdef QT3_SUPPORT
37 ColorGroup = 63,
38 #endif
39 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_SUPPORT
66 IconSet = Icon,
67 CString = ByteArray,
68 PointArray = Polygon,
69 #endif
70 LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
71 };

数据类型转换:
以下数据类型可以自动转换
可通过成员函数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数据类型的联合体(源码解读)的更多相关文章
- 如何判断一个Http Message的结束——python源码解读
HTTP/1.1 默认的连接方式是长连接,不能通过简单的TCP连接关闭判断HttpMessage的结束. 以下是几种判断HttpMessage结束的方式: 1. HTTP协议约定status ...
- Qt update刷新之源码分析(一)
在做GUI开发时,要让控件刷新,会调用update函数:那么在调用了update函数后,Qt究竟基于什么原理.执行了什么代码使得屏幕上有变化?本文就带大家来探究探究其内部源码. Qt手册中关于QWid ...
- 分享一个与ABP配套使用的代码生成器源码
点这里进入ABP系列文章总目录 分享一个与ABP配套使用的代码生成器源码 真对不起关注我博客的朋友, 因最近工作很忙, 很久没有更新博客了.以前答应把自用的代码生成器源码共享出来, 也一直没有时间整理 ...
- 整合了一个功能强大完善的OA系统源码,php全开源 界面漂亮美观
整合了一个功能强大完善的OA系统源码,php全开源界面漂亮美观.需要的同学联系Q:930948049
- IM即时通讯设计 高并发聊天服务:服务器 + qt客户端(附源码)
来源:微信公众号「编程学习基地」 目录 IM即时通信程序设计 IM即时通讯 设计一款高并发聊天服务需要注意什么 如何设计可靠的消息处理服务 什么是粘包 什么是半包 解决粘包和半包 IM通信协议 应用层 ...
- Qt事件分发机制源码分析之QApplication对象构建过程
我们在新建一个Qt GUI项目时,main函数里会生成类似下面的代码: int main(int argc, char *argv[]) { QApplication application(argc ...
- koa2源码解读及实现一个简单的koa2框架
阅读目录 一:封装node http server. 创建koa类构造函数. 二:构造request.response.及 context 对象. 三:中间件机制的实现. 四:错误捕获和错误处理. k ...
- 分享一个基于web的满意度调查问卷源码系统
问卷调查系统应用于各行各业,对于企业的数据回收统计分析战略决策起到至关作用.而现有的问卷调查系统大都是在线使用并将数据保存在第三方服务器上.这种模式每年都要缴纳费用并且数据安全性得不到保证.所以说每个 ...
- Android Studio 一个完整的APP实例(附源码和数据库)
前言: 这是我独立做的第一个APP,是一个记账本APP. This is the first APP, I've ever done on my own. It's a accountbook APP ...
随机推荐
- 26-[Boostrap]-全局css样式,组件,控件
1.全局CSS样式 https://v3.bootcss.com/css/ <!DOCTYPE html> <html lang="zh-CN"> < ...
- centos中如何添加环境变量
在Linux CentOS系统上安装完php和MySQL后,为了使用方便,需要将php和mysql命令加到系统命令中,如果在没有添加到环境变量之前,执行“php -v”命令查看当前php版本信息时时, ...
- 解决公司的垃圾wifi dhcp获取不到ip 以及配上ip也不能联网的原因
用手机连公司的wifi时,发现dhcp自动获取不到ip,然后配置了静态ip,但是还是无法联网, 然后发现鸡巴垃圾公司傻逼操她妈的逼原来是google的dns导致不能用??? 换成114.114.11 ...
- [环境配置]Ubuntu 16.04+CUDA 9.0+OpenCV 3.2.0下编译基于Caffe的MobileNet-SSD踩过的一些坑
SSD是Caffe的一个分支,源码在github上:https://github.com/weiliu89/caffe/tree/ssd $ git clone https://github.com/ ...
- 执行sh脚本报“/usr/bin/env: "sh\r": 没有那个文件或目录”错误
出现这个错误的原因是出错的语句后面多了“\r”这个字符,换言之,脚本文件格式的问题,我们只需要把格式改成unix即可: vi xx.sh :set ff :set ff=unix :wq!
- SVN For Mac: Cornerstone.app破解版免费下载
Cornerstone.app下载地址 链接:https://pan.baidu.com/s/1kwQ65SBgfWXQur8Zdzkyyw 密码:rqe7 Cornerstone303 MAS.a ...
- centos7.6 安装 openvpn--2.4.7
openvpn-server端 搭建 1,软件版本 Centos - 7.x easy-rsa - 3.0.3 OpenVPN - 2.4.7 2,安装 建议安装启用epel源,采用yum的方式安装o ...
- awk之close函数
echo "21 2 " | awk '{ first[NR]=$ second[NR]=$ }END{ print "======打印第1列并排序:========== ...
- linux后台启动程序脚本实例
启动安装的zookeeper和kafka #!/bin/bash # start zookeeper and kafka service echo "========== Start the ...
- 机器学习基础 --- numpy的基本使用
一.numpy的简介 numpy是Python的一种开源的数值计算扩展库.这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该 ...