QVariant类

QVariant类 

转载自https://wenku.baidu.com/view/adfdf20e02768e9950e73868.html



这个类型相当于是Java里面的Object,它把绝大多数Qt提供的数据类型都封装起来,起到一个数据类型“擦除”的作用。比如我们的 table单元格可以是string,也可以是int,也可以是一个颜色值,那么这么多类型怎么返回呢?于是,Qt提供了这个QVariant类型,你可 以把这很多类型都存放进去,到需要使用的时候使用一系列的to函数取出来即可。比如你把int包装成一个QVariant,使用的时候要用 QVariant::toInt()重新取出来。这里需要注意的是,QVariant类型的放入和取出必须是相对应的,你放入一个int就必须按int取出,不能用toString(), Qt不会帮你自动转换。 
数据核心无非就是一个 union,和一个标记类型的type:传递的是整数 123,那么它union存储整数123,同时type标志Int;如果传递字符串,union存储字符串的指针,同时type标志QString。 
QVariant 属于 Qt 的Core模块,属于Qt的底层核心之一,ActiveQt、QtScript、QtDeclarative等都严重依赖于QVariant。 
QVariant类作为一个最为普遍的Qt数据类型的联合。 
因为c++禁止没有构造函数和析构函数的联合体,许多继承的Qt类不能够在联合体当中使用。(联合体当中的变量共用一个存储区),没有了联合变量,我们在物体属性以及数据库的工作等方面受到很多的困扰。 
一个QVariant对象在一个时间内只保留一种类型的值。我们可以使用
canConvert来查询是否能够转换当前的类型。转换类型一般以toT()命名。 QVariant 可以保存很多Qt的数据类型,包括QBrush、QColor、QCursor、QDateTime、QFont、QKeySequence、 QPalette、QPen、QPixmap、QPoint、QRect、QRegion、QSize和QString,并且还有C++基本类型,如 int、float等。QVariant还能保存很多集合类型,如QMap<QSTRING, QVariant>, 
QStringList和QList。item view classes,数据库模块和QSettings都大量使用了QVariant类,,以方便我们读写数据。  摘录了一个example来说明QVariant的使用方法:   
QDataStream out(...); 
 QVariant v(123);                // The variant now contains an int  int x = v.toInt();              // x = 123 
 out << v;                       // Writes a type tag and an int to out 
 v = QVariant("hello");          // The variant now contains a QByteArray 
 v = QVariant(tr("hello"));      // The variant now contains a QString  int y = v.toInt();              // y = 0 since v cannot be converted to an int 
 QString s = v.toString();       // s = tr("hello")  (see QObject::tr())  out << v;                       // Writes a type tag and a QString to out  ... 
 QDataStream in(...);            // (opening the previously written stream) 
 in >> v;                        // Reads an Int variant  int z = v.toInt();              // z = 123 
 qDebug("Type is %s",            // prints "Type is int"          v.typeName()); 
 v = v.toInt() + 100;            // The variant now hold the value 223  v = QVariant(QStringList());你甚至可以存储QList<QVariant>和QMap<QString ,QVariant>.所以你可以构造任意复杂的任意的数据类型。这个是非常强大而且又有用的。QVariant也支持null值,你可以定义一个 没有任何值的类型,然而,也要注意QVariant类型只能在他们有值的时候被强制转换。QVariant x, y(QString()), z(QString(""));  x.convert(QVariant::Int);  // x.isNull() == true 
 // y.isNull() == true, z.isNull() == false 
因 为QVariant是QtCore库的一部分,它不能够提供定义在QtGui当中的类型的转换,如QColor,QImage,he QPixmap等。换句话说,没有toColor()这样的函数。取代的,你可以使用QVariant::value()或者 qVariantValue()这两个模板函数。 QVariant variant;  ... 
 QColor color = variant.value<QColor>(); 
反向转换(如把QColor转成QVariant)是自动完成的。也包含了GUI相关的那些数据类型。 


 var cpro_psid ="u2572954"; var cpro_pswidth =966; var cpro_psheight =120;



QColor color=palette().background().color(); QVariant variant=color; QVariant也可以进行嵌套存储,例如 
QMap<QString, QVariant> pearMap;    pearMap["Standard"] = 1.95;    pearMap["Organic"] = 2.25;      
QMap<QString, QVariant> fruitMap;    fruitMap["Orange"] = 2.10;    fruitMap["Pineapple"] = 3.85;    fruitMap["Pear"] = pearMap; 
QVariant被用于构建Qt Meta-Object,因此是QtCore的一部分。当然,我们也可以在GUI模块中使用,例如 
QIcon icon("open.png");    QVariant variant = icon;    // other function    
QIcon icon = variant.value<QIcon>(); 
我们使用了value()模版函数,获取存储在QVariant中的数据。这种函数在非GUI数据中同样适用,但是,在非GUI模块中,我们通常使用toInt()这样的一系列to...()函数,如toString()等。 
如果你觉得QVariant提供的存储数据类型太少,也可以自定义QVariant的存储类型。被QVariant存储的数据类型需要有一个默认的构造函数和一个拷贝构造函数。为了实现这个功能,首先必须使用Q_DECLARE_METATYPE()宏。通常会将这个宏放在类的声明所在头文件的下面: Q_DECLARE_METATYPE(BusinessCard) 然后我们就可以使用: 
BusinessCard businessCard;    
QVariant variant = QVariant::fromValue(businessCard);    // ...    
if (variant.canConvert<BusinessCard>()) {    
     BusinessCard card = variant.value<BusinessCard>();         // ...    } 
由于VC 6的编译器限制,这些模板函数不能使用,如果你使用这个编译器,需要使用qVariantFromValue(), qVariantValue()和qVariantCanConvert()这三个宏。 如果自定义数据类型重写了<<和>>运算符,那么就可以直接在QDataStream中使用。不过首先需要使用qRegisterMetaTypeStreamOperators().宏进行注册。这就能够让QSettings使用操作符对数据进行操作 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值