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是否为空。
那么看看type可以指示的类型有哪些:
enum Type {
Invalid = QMetaType::UnknownType, Bool = QMetaType::Bool, 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, 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); }
今天的文章Qt之QVariant用法分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/5245.html