Qt QVariant

QVariant相当于一个包含大多数Qt数据类型的联合体

将数据存储为一个Private结构体类型的成员变量d:

<qvariant.cpp>

QVariant::QVariant(Type type)
{ create(type, 0); }
1 void QVariant::create(int type, const void *copy)
2 {
3     d.type = type;
4     handler->construct(&d, copy);
5 }
static void construct(QVariant::Private *x, const void *copy)
{
    x->is_shared = false;

    switch (x->type) {
    case QVariant::String:
        v_construct<QString>(x, copy);
        break;
    ......
    default:
        void *ptr = QMetaType::construct(x->type, copy);
        if (!ptr) {
            x->type = QVariant::Invalid;
        } else {
            x->is_shared = true;
            x->data.shared = new QVariant::PrivateShared(ptr);
        }
        break;
    }
    x->is_null = !copy;
}
QVariant::QVariant(int val)
{ d.is_null = false; d.type = Int; d.data.i = val; }

<qvariant.h>

class Q_CORE_EXPORT QVariant
{
    ......
   struct Private
    {
        inline Private(): type(Invalid), is_shared(false), is_null(true) { data.ptr = 0; }
        inline Private(const Private &other)
            : data(other.data), type(other.type),
              is_shared(other.is_shared), is_null(other.is_null)
        {}
        union Data
        {
            char c;
            int i;
            uint u;
            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 d;
    ......
}

QVariant支持的数据类型:

enum Type {
        Invalid = 0,

        Bool = 1,
        Int = 2,
        UInt = 3,
        LongLong = 4,
        ULongLong = 5,
        Double = 6,
        Char = 7,
        Map = 8,
        List = 9,
        String = 10,
        StringList = 11,
        ByteArray = 12,
        BitArray = 13,
        Date = 14,
        Time = 15,
        DateTime = 16,
        Url = 17,
        Locale = 18,
        Rect = 19,
        RectF = 20,
        Size = 21,
        SizeF = 22,
        Line = 23,
        LineF = 24,
        Point = 25,
        PointF = 26,
        RegExp = 27,
        Hash = 28,
        EasingCurve = 29,
        LastCoreType = EasingCurve,

        // value 62 is internally reserved
#ifdef QT3_SUPPORT
        ColorGroup = 63,
#endif
        Font = 64,
        Pixmap = 65,
        Brush = 66,
        Color = 67,
        Palette = 68,
        Icon = 69,
        Image = 70,
        Polygon = 71,
        Region = 72,
        Bitmap = 73,
        Cursor = 74,
        SizePolicy = 75,
        KeySequence = 76,
        Pen = 77,
        TextLength = 78,
        TextFormat = 79,
        Matrix = 80,
        Transform = 81,
        Matrix4x4 = 82,
        Vector2D = 83,
        Vector3D = 84,
        Vector4D = 85,
        Quaternion = 86,
        LastGuiType = Quaternion,

        UserType = 127,
#ifdef QT3_SUPPORT
        IconSet = Icon,
        CString = ByteArray,
        PointArray = Polygon,
#endif
        LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
    };

数据类型转换:

以下数据类型可以自动转换

 

可通过成员函数bool QVariant::canConvert ( Type t ) const确定是否可执行指定数据类型的转换

自定义QVariant可存储的数据类型:

class Q_CORE_EXPORT QVariant
{
    ......
   template<typename T>
    bool canConvert() const
    { return canConvert(Type(qMetaTypeId<T>())); }
    ......
}
static inline QVariant fromValue(const T &value)
   { return qVariantFromValue(value); }
template <typename T>
inline QVariant qVariantFromValue(const T &t)
{
    return QVariant(qMetaTypeId<T>(reinterpret_cast<T *>(0)), &t, QTypeInfo<T>::isPointer);
}

从类的声明中可以看出,要成为QVariant可存储的数据类型,必须将该自定义数据类型通过宏Q_DECLARE_METATYPE (Type)注册到MetaType系统中

<qmetatype.h>

#define Q_DECLARE_METATYPE(TYPE)                                        \
    QT_BEGIN_NAMESPACE                                                  \
    template <>                                                         \
    struct QMetaTypeId< TYPE >                                          \
    {                                                                   \
        enum { Defined = 1 };                                           \
        static int qt_metatype_id()                                     \
            {                                                           \
                static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
                if (!metatype_id)                                       \
                    metatype_id = qRegisterMetaType< TYPE >(#TYPE,      \
                               reinterpret_cast< TYPE *>(quintptr(-1))); \
                return metatype_id;                                     \
            }                                                           \
    };                                                                  \
    QT_END_NAMESPACE

示例:

namespace MyNamespace
{
    struct MyStruct
     {
         int i;
         ...
     };
}

 Q_DECLARE_METATYPE(MyNamespace::MyStruct)
MyStruct s;
QVariant var;
var.setValue(s);

......

QVariant var2 = QVariant::fromValue(s);
if (var2.canConvert<MyStruct>())
{
    MyStruct s2 = var2.value<MyStruct>();
}

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值