Qt入门 - QVariant

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 }

Qt入门 - QVariant,布布扣,bubuko.com

时间: 2024-10-10 01:09:12

Qt入门 - QVariant的相关文章

Qt入门之基础篇 ( 二 ) :Qt项目建立、编译、运行和发布过程解析

转载请注明出处:CN_Simo. 题解: 本篇内容主讲Qt应用从创建到发布的整个过程,旨在帮助读者能够快速走进Qt的世界. 本来计划是讲解Qt源码静态编译,如此的话读者可能并不能清楚地知道为何要静态编译,所以借此篇内容说明一下原由并为之后文章的学习做准备. 即使本片内容只是在围绕一个小小的HelloWorld程序开展,但还是希望朋友们不要急于求成,"欲速则不达". 文章整体思路: 我们循序渐进地来看,一个Qt应用的完成有以下一个重要的步骤: 项目创建->源码编译->程序运行

Qt入门之基础篇 ( 一 ) :Qt4及Qt5的下载与安装

转载请注明出处:CN_Simo. 导语: Qt是一个跨平台的C++图形界面应用程序框架.它提供给开发者建立图形用户界面所需的功能,广泛用于开发GUI程序,也可用于开发非GUI程序.Qt很容易扩展,并且允许真正地组件编程.基本上,Qt同X Window上的Motif,Openwin,GTK等图形界面库以及Windows平台上的MFC.OWL.VCL.ATL是同类型的东西. 本系列教程以Qt5.6为基础展开精讲. 参考书目: [1]霍亚飞.Qt Creator快速入门(第3版).2017年 [2]蔡

[QT入门篇]3 QObject的拷贝构造函数与赋值运算符

本文主要是针对QObject的拷贝构造函数和赋值运算符进行说明.先来看一下拷贝构造函数定义:拷贝构造函数,又称复制构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化.其唯一的形参必须是引用,但并不限制为const,一般普遍的会加上const限制.此函数经常用在函数调用时用户定义类型的值传递及返回.拷贝构造函数要调用基类的拷贝构造函数和成员函数.如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用. 还记得<[QT入门篇]1 QT中的对象模型>中

Qt入门之小心read()给你设下的陷阱

最近帮学长写了个Qt Tcpsocket客户端的应用程序,被一个问题困扰了许久.因为以前没有用Qt 写过socket的客户端程序 加上时间比较紧,都没能好好的查看些资料就急忙的写代码,看了一些别人的代码,差不多都是相同的,但是我就出现了收数据 不全的问题.. 最后查出原因是我在接受服务器端的数据时使用了read()这个函数,接收的是个结构体,这里顺便说下怎么在Qt 下收发结构体 发: clientsocket->write((char *)&CardInfo, sizeof(CardInfo

[Qt入门篇]5 Qt的属性系统——声明属性

[Qt入门篇]5 Qt的属性系统--声明属性 Qt提供了灵活的属性系统,它基于Qt的元对象系统,不依赖于编译器,这保证了Qt独立于编译其和平台的特点.这篇文章主要看看如何声明属性. 属性系统比较复杂,先看一个简单的例子.在QWidget中,有很多属性的声明,找一个简单学习: Q_PROPERTY(boolmodalREADisModal) 这里出现了5个元素:Q_PROPERTY.bool.modal.READ.isModal.这五个元素都是啥作用呢? Q_PROPERTY:用于声明属性的宏:

第一章 Qt入门

现在自己开始学习Qt了,参考资料是C++ GUI Qt4编程 准备做一系列的学习笔记,也算帮助自己学习吧,希望自己能坚持下去. 1.先来一段程序代码,当然是鼎鼎大名的Hello Qt 1 #include <QApplication> 2 #include <QLabel> 3 4 int main(int argc, char** argv) 5 { 6 QApplication app(argc, argv); 7 //QLabel *label = new QLabel(&q

Qt入门 - 全局数据类型

<QtGlobal> 1 typedef signed char qint8; /* 8 bit signed */ 2 typedef unsigned char quint8; /* 8 bit unsigned */ 3 typedef short qint16; /* 16 bit signed */ 4 typedef unsigned short quint16; /* 16 bit unsigned */ 5 typedef int qint32; /* 32 bit signe

Qt入门 - QTextEdit

QTextEdit *textedit = new QTextEdit(); 获取文本框内容:QString qstring = textedit->toPlainText(); 设置文本框内容:textedit->setPlainText(qstring); 自动跳到最后一行: QTextCursor tc = textEdit->textCursor(); tc.movePosition(QTextCursor::End); textEdit->setTextCursor(tc

Qt入门学习——Qt 5 帮助文档的使用

Qt入门学习——Qt 5 帮助文档的使用 学习图形界面开发,肯定离不开帮助文档的使用,因为它不像 C 语言那样就那么几个函数接口,图形接口的接口可以用海量来形容,常用的我们可能能记住,其它的真的没有必要去记,用到什么就去帮助文档查看用法. 我们使用 Qt 帮助文档,主要分为这么几步: 1)类使用的相关介绍 2)查看所用部件(类)的相应成员函数(功能,参数,返回值) 3)查看部件的信号 4)查看部件的事件(所对应的虚函数如何编写) 1)类使用的相关介绍 光标移动到类名字的地方,接着按“F1”即可跳