1. 简介
QVariant可以存储各种数据类型,QVariant行为类似于C/C++的union, 但在Qt中比union强大很多, QVariant内置支持所有QMetaType::Type里声明的类型如:int,QString,QFont,QColor等,甚至QList,QMap<QString, QVariant>等组成的任意复杂类型。简单的说QVariant可以存储任意数据类型,表现的类似弱语言,如JS中的var如,包括容器类型的值,如QStringlist。Qt的很多功能都是建立在QVariant类的基础之上的,如Qt对象属性及数据库功能等,在代码片段中主要分两种情况讨论QVariant的应用:
2.代码片段
//一.基本数据类型
QVariant number(27); //定义一个名为number的QVariant变量,并初始值为27,那么在这里相当于int型
qDebug()<<number;//打印结果:QVariant(int, 27)
qDebug()<<number;
QStringList strList;
strList.append("who");
strList.append("are");
strList.append("you");
QMap<QString,QVariant> myMap;
myMap.insert("one",45); //int
myMap.insert("two","hello"); //qstring
myMap.insert("three",QColor(0,0,0)); //qcolor
myMap.insert("four",strList); //QStringList 类型,就是所谓的容器类型值
// myMap.insert("five",map); //尝试了一下,结果这里无法转化,可能是不支持这种数据类型吧,map为QMap类型
QMapIterator<QString,QVariant> x(myMap);
for(;x.hasNext();)
{
qDebug()<<x.key()<<x.next().value();
#if 0
if(x.next().value().type() == QVariant::StringList) //判断QVariant类型,这里是判断是否为QStringList,更多的可以找手册查询一下
{
// qDebug()<<x.key();
QString str=QString("%1").arg(x.key()); //找到数据类型为QStringList的值对应的键,再通过键找到值,这里不能直接用x.next().value(),因为next会跳到下一个键值对
qDebug()<<str;
QStringList myList=myMap[str].toStringList(); //必要的转化
for(int m=0;m<myList.size();m++) //遍历QStringList
{
qDebug()<<myList[m];
}
}
#endif
// qDebug()<<x.next().value().type();
}
//二.自定义数据类型
因为自定义数据类型是系统中不存在的,即使创建,也需要注册一下,方便编译器识别
struct myStruct //自定义的数据类型
{
int age;
char name[10];
};
Q_DECLARE_METATYPE(myStruct) //注册,必不可少
//上面这部分代码一般在头文件中完成
// myStruct stu= //结构体初始化
// {
// 100,
// "wangLei"
// };
myStruct stu;
stu.age = 100;//也可以先定义变量后这样赋值
strcpy(stu.name,"Hello./n");
QVariant v;
v.setValue(stu); //设置QVariant的值
qDebug()<<"v:"<<v;
myStruct s; //这部分代码主要是将QVariant类再转化为myStruct类,其他QVariant类转化成其他类也可用这种方法
s=v.value<myStruct>();
qDebug()<<"s:"<<s.age<<s.name;
如果要使自定义类型或其他非QMetaType内置类型在QVariant中使用,必须使用该宏Q_DECLARE_METATYPE
如果非QMetaType内置类型要在信号与槽中使用,必须使用qRegisterMetaType。
3.源码赏析
数据成员
QVariant的数据成员很简单,只有一句:
Private d;
Private 定义:
struct Private
{
union Data
{
char c;
uchar uc;
short s;
signed char sc;
ushort us;
int i;
uint u;
long l;
ulong ul;
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是一个结构体,核心数据成员是data,是一个union数据类型,可以存储各种整型,浮点型,QObject类指针,任意指针,共享数据指针。type指示了data中存储的数据类型,is_shared代表数据是否是共享的,is_null代表data是否为空。