QVariant

 

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是否为空。

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值