前言
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)
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就是如此。