Qt之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()<&().value();
#if 0
().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()<&().value().type();
}
//⼆.⾃定义数据类型
因为⾃定义数据类型是系统中不存在的,即使创建,也需要注册⼀下,⽅便编译器识别
struct myStruct //⾃定义的数据类型
{
int age;
char name[10];
};
Q_DECLARE_METATYPE(myStruct)//注册,必不可少
//上⾯这部分代码⼀般在头⽂件中完成
//    myStruct stu=  //结构体初始化
//    {
//        100,
//        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是否为空。
那么看看type可以指⽰的类型有哪些:
enum Type {
Invalid = QMetaType::UnknownType,
Bool = QMetaType::Bool,
Int = QMetaType::Int,
Int = QMetaType::Int,
UInt = QMetaType::UInt,
LongLong = QMetaType::LongLong,
ULongLong = QMetaType::ULongLong,
Double = QMetaType::Double,
Char = QMetaType::QChar,
Map = QMetaType::QVariantMap,
List = QMetaType::QVariantList,
String = QMetaType::QString,
StringList = QMetaType::QStringList,
ByteArray = QMetaType::QByteArray,
BitArray = QMetaType::QBitArray,
Date = QMetaType::QDate,
Time = QMetaType::QTime,
DateTime = QMetaType::QDateTime,
Url = QMetaType::QUrl,
Locale = QMetaType::QLocale,
Rect = QMetaType::QRect,
RectF = QMetaType::QRectF,
Size = QMetaType::QSize,
SizeF = QMetaType::QSizeF,
Line = QMetaType::QLine,
LineF = QMetaType::QLineF,
Point = QMetaType::QPoint,
PointF = QMetaType::QPointF,
RegExp = QMetaType::QRegExp,
RegularExpression = QMetaType::QRegularExpression,
Hash = QMetaType::QVariantHash,
EasingCurve = QMetaType::QEasingCurve,
Uuid = QMetaType::QUuid,
ModelIndex = QMetaType::QModelIndex,
PersistentModelIndex = QMetaType::QPersistentModelIndex,
LastCoreType = QMetaType::LastCoreType,
Font = QMetaType::QFont,
Pixmap = QMetaType::QPixmap,
Brush = QMetaType::QBrush,
Color = QMetaType::QColor,
Palette = QMetaType::QPalette,
Image = QMetaType::QImage,
Polygon = QMetaType::QPolygon,
Region = QMetaType::QRegion,
bootstrapped
Bitmap = QMetaType::QBitmap,
Cursor = QMetaType::QCursor,
KeySequence = QMetaType::QKeySequence,
Pen = QMetaType::QPen,
TextLength = QMetaType::QTextLength,
TextFormat = QMetaType::QTextFormat,
Matrix = QMetaType::QMatrix,
Transform = QMetaType::QTransform,
Matrix4x4 = QMetaType::QMatrix4x4,
Vector2D = QMetaType::QVector2D,
Vector3D = QMetaType::QVector3D,
Vector4D = QMetaType::QVector4D,
Quaternion = QMetaType::QQuaternion,
PolygonF = QMetaType::QPolygonF,
Icon = QMetaType::QIcon,
LastGuiType = QMetaType::LastGuiType,
SizePolicy = QMetaType::QSizePolicy,
UserType = QMetaType::User,
LastType =0xffffffff// need this so that gcc >= 3.4 allocates 32 bits for Type };
不仅包含了基本数据类型Bool、Int、Double等,还包含了core中的数据类型QChar、QPoint、QSize、QRect、QDateTime、QString,容器类型QMap、QList、QHash,gui中的数据类型QColor、QFont、QPalette、QImage、QVector、QMatrix等,还可以添加⾃定义类型QMetaType::User
构造函数
可以存储Type中的数据类型,构造函数重载⾃然很多,随便列举些:
QVariant(bool b);
QVariant(double d);
QVariant(const QString &string);
QVariant(const QList<QVariant>&list);
QVariant(const QMap<QString,QVariant>&map);
QVariant(const QHash<QString,QVariant>&hash);
QVariant(const QVariant &other);
也可以通过setValue赋值
template<typename T>
inline void setValue(const T &value);
取值
在已知存储类型的情况下,可以直接使⽤如下函数:
int toInt(bool *ok = Q_NULLPTR)const;
uint toUInt(bool *ok = Q_NULLPTR)const;
qlonglong toLongLong(bool *ok = Q_NULLPTR)const;
qulonglong toULongLong(bool *ok = Q_NULLPTR)const;
bool toBool()const;
double toDouble(bool *ok = Q_NULLPTR)const;
float toFloat(bool *ok = Q_NULLPTR)const;
qreal toReal(bool *ok = Q_NULLPTR)const;
QByteArray toByteArray()const;
QBitArray toBitArray()const;
QString toString()const;
QStringList toStringList()const;
QChar toChar()const;
QDate toDate()const;
QTime toTime()const;
QDateTime toDateTime()const;
QList<QVariant>toList()const;
QMap<QString, QVariant>toMap()const;
QHash<QString, QVariant>toHash()const;
#ifndef QT_NO_GEOM_VARIANT
QPoint toPoint()const;
QPointF toPointF()const;
QRect toRect()const;
QSize toSize()const;
QSizeF toSizeF()const;
QLine toLine()const;
QLineF toLineF()const;
QRectF toRectF()const;
#endif
QLocale toLocale()const;
#ifndef QT_NO_REGEXP
QRegExp toRegExp()const;
#endif // QT_NO_REGEXP
#ifndef QT_BOOTSTRAPPED
#ifndef QT_NO_REGULAREXPRESSION
QRegularExpression toRegularExpression()const;
#endif // QT_NO_REGULAREXPRESSION
QUrl toUrl()const;
QEasingCurve toEasingCurve()const;
QUuid toUuid()const;
QModelIndex toModelIndex()const;
QPersistentModelIndex toPersistentModelIndex()const;
QJsonValue toJsonValue()const;
QJsonObject toJsonObject()const;
QJsonArray toJsonArray()const;
QJsonDocument toJsonDocument()const;
#endif // QT_BOOTSTRAPPED
未知情况下,可以先使⽤canConvert进⾏查询是否可以转化,然后调⽤对应toXXX。
bool canConvert(int targetTypeId)const;
template<typename T>
bool canConvert()const;
⾃定义数据类型可使⽤value取值
template<typename T>
inline T value()const
{return qvariant_cast<T>(*this);}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。