欢迎光临
我们一起努力

QVariant的用法

前言
QVariant这个类很神奇,或者说方便。很多时候,需要几种不同的数据类型需要传递,如果用结构体,又不大方便,容器保存的也只是一种数据类型,而QVariant则可以统统搞定。

 

介绍
帮助文档上说:The QVariant class acts like a union for the most common Qt data types.。

QVariant 这个类型充当着最常见的数据类型的联合。QVariant 可以保存很多Qt的数据类型,包括QBrush、QColor、QCursor、QDateTime、QFont、QKeySequence、 QPalette、QPen、QPixmap、QPoint、QRect、QRegion、QSize和QString,并且还有C++基本类型,如 int、float等。

当然,如果支持的类型没有想要的,没关系,QVariant也可以支持自定义的数据类型。被QVariant存储的数据类型需要有一个默认的构造函数和一个拷贝构造函数。为了实现这个功能,首先必须使用Q_DECLARE_METATYPE()宏。通常会将这个宏放在类的声明所在头文件的下面:

Q_DECLARE_METATYPE(MyClass)

 

示例
(1)支持的类型。对于QVariant支持的类型,可直接赋值,但是取值时,对于存入的是什么类型,取出也要为这个类型。如存入为int类型,输出为toString()

    QVariant var;
    var.setValue(12);
    int data=var.toInt();

或

    QVariant var=12;
    int data=var.toInt();

 

(2)对于不支持的类型,如自己定义的结构体。由于Qt都是基于元对象系统,故要在头文件里面要注册此类属于元类型。存储用到了QVariant QVariant::fromValue(const T &value) 或 void QVariant::setValue(const T &value)。获取用到了

T QVariant::value() const,在这之前一般要bool QVariant::canConvert(int targetTypeId) const先用进行判断,是否可以转换。例子如下:

.h文件声明

struct MyClass{
    int id;
    QString name;
};
Q_DECLARE_METATYPE(MyClass)

.cpp文件定义

//存储数据
    MyClass myClass;
    myClass.id=0;
    myClass.name=QString("LiMing");
 
    data[0]=QString("ddd");
    data[1]=123;
    data[3]=QVariant::fromValue(myClass);
 
 
//获取数据
    QString str=data.value(0).toString();
    int val=data.value(1).toInt();
 
    if(data[3].canConvert<MyClass>())
    {
        MyClass myClass=data[3].value<MyClass>();
        int id=myClass.id;
        QString name=myClass.name;
    }

 

(3)保存指针,感觉这个比较强大,也比较容易用到。如

//保存
QVariant var=QVariant::fromValue((void*)event);

//获取
QPaintEvent* e=(QPaintEvent*)var.value<void*>();

(4)还有种写法,用QVariant的构造函数QVariant(int typeId, const void *copy)。虽然不常用,特别是指针类型,即 QMetaType::VoidStar,和 QMetaType::QObjectStar,一般还是用fromValue。但是还是以存取QObject*为例补充下吧,

起码知道写法。

QObject* obj=new QObject;
obj->setObjectName("myObj");
 
//保存
QVariant var=QVariant(QMetaType::QObjectStar,&obj);
 
//提取
QObject* myobj=qvariant_cast<QObject*>(var);
if(myobj!=NULL)
    qDebug()<<myobj->objectName();
 
obj->deleteLater();

再看第二篇文章

QVariant为一个万能的数据类型–可以作为许多类型互相之间进行自动转换。将C++变为弱数据类型成为可能–也是许多控件中用户定义数据的类型–因为无法预先知道用户附加到控件的数据是什么类型。
而QT的Variant类型默认识别的类型都非常强制–只支持已注册的类型–如何将一个自己定义的结构或类赋予QVariant对象呢?

myStructor c;
QVariant v;
v.setValue (c); //将会错误--Qvariant还不认识myStructor呢。

首先必须先注册myStructor–使用Q_DECLARE_METATYPE(myStructor)。
这是一个Macro–只能在全局中使用–否则出现错误。
然后就可以按一般的方法来赋值了–取值代码为 v.value < myStructor >();
例子:
将一个指针赋予QVariant–可能有需要将一个指针赋予树型列表控件(QTreeWidget)中一个条目–点击此条目获取指针对数据进行处理–而无须通过查找来取得数据–缩短处理时间。

用int指针作为例子–QVariant不支持此类型必须先注册。

ifndef __XXX__
define __XXX__

Q_DECLARE_METATYPE(int*);
...

endif

附带记下如何在QTreeWidget控件中附加数据

增加Item

QTreeWidgetItem* newItem = new QTreeWidgetItem;

...增加newItem到treeWidget中...

int* itemVal = new int (123);
QVariant Var;
Var.setValue (testVal); // 已注册了int*--正确编译
newItem->setData (0, 0, Var); //newItem的第一列附加了Var--即指向itemVal的指针
//第二个参数为role角色的意思--我也不懂啥意思

点击某个条目获取对应的数据

on_treeWidget_click ()
{
...取得选择的条目-curItem...
//Data()的参数和当时设置数据的参数一样,value()是取得var的数据
int* ptr = curItem->Data (0, 0).value < int* >();

...对ptr进行处理...
}

 

赞(0) 打赏
未经允许不得转载:Libero's Blog » QVariant的用法

评论 抢沙发

评论前必须登录!