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 ...
随机推荐
- com.jcraft.jsch.JSchException: java.io.FileNotFoundException: file:\D:\development\ideaProjects\salary-card\target\salary-card-0.0.1-SNAPSHOT.jar!\BOOT-INF\classes!\keystore\login_id_rsa 资源未找到
com.jcraft.jsch.JSchException: java.io.FileNotFoundException: file:\D:\development\ideaProjects\sala ...
- P4774 [NOI2018]屠龙勇士
P4774 [NOI2018]屠龙勇士 先平衡树跑出打每条龙的atk t[] 然后每条龙有\(xt \equiv a[i](\text{mod }p[i])\) 就是\(xt+kp[i]=a[i]\) ...
- jzoj5377 开拓
哇好火的dp啊. 开始根本想不出 这里如果顺着dp肯定是不行的,没办法记录钻头能力值 显然能力值的变化会影响后面收入 而具体影响就是:全部乘了1-0.01k或1+0.01c. 可以倒着dp(orz) ...
- JS ,substr、 substring、charAt方法的区别
JS 截取字符串substr 和 substring方法的区别,需要的朋友可以参考下,根据需要自行选择. substr 方法 返回一个从指定位置开始的指定长度的子字符串. stringvar.subs ...
- sqlite3 数据库命令操作
SQLite 数据库,是一个非常轻量级自包含(lightweight and self-contained)的DBMS,它可移植性好,很容易使用,很小,高效而且可靠. SQLite嵌入到使用它的应用程 ...
- iframe的简单使用方法
1.父页面调用子页面的元素(a代表iframe的id或者class,b代表子页面) $('a').contents().find("b") 2.子页面调用父页面的元素(c代表父页面 ...
- ffmpeg 踩坑实录 添加实时水印(二)
一.背景介绍 最近领导要求做一个视频录制的相关项目.其中,需要对视频文件进行添加 实时时间水印.于是,我想到了使用之前的ffmpeg来做. 二.ffmpeg实际操作 首先把需要添加水印的视频文件,上传 ...
- 使用request+Beautiful爬取妹子图
一.request安装 pip install requests request使用示例 import requests response = requests.get('https://www.mz ...
- 用Unity的UGUI实现简单摇杆
1.在Canvas下新建一个空对象作为我们的摇杆,命名为Joystick. 摇杆由背景和杆两部分组成,所以在Joystick下新建一个Image作为摇杆的背景,命名为BG. 在BG下新建一个Image ...
- HPCMS V9使用ajax方式提交表单
一.前台模板(注:需要引入jquery文件) <form id="myform" class="subscribe-form subscription" ...