zoukankan      html  css  js  c++  java
  • QVariant相当于一个包含大多数Qt数据类型的联合体(源码解读)

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

    <qvariant.cpp>

    1 QVariant::QVariant(Type type)
    2 { 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;
    }
    复制代码
    1 QVariant::QVariant(int val)
    2 { 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支持的数据类型:

    复制代码
     1 enum Type {
     2         Invalid = 0,
     3 
     4         Bool = 1,
     5         Int = 2,
     6         UInt = 3,
     7         LongLong = 4,
     8         ULongLong = 5,
     9         Double = 6,
    10         Char = 7,
    11         Map = 8,
    12         List = 9,
    13         String = 10,
    14         StringList = 11,
    15         ByteArray = 12,
    16         BitArray = 13,
    17         Date = 14,
    18         Time = 15,
    19         DateTime = 16,
    20         Url = 17,
    21         Locale = 18,
    22         Rect = 19,
    23         RectF = 20,
    24         Size = 21,
    25         SizeF = 22,
    26         Line = 23,
    27         LineF = 24,
    28         Point = 25,
    29         PointF = 26,
    30         RegExp = 27,
    31         Hash = 28,
    32         EasingCurve = 29,
    33         LastCoreType = EasingCurve,
    34 
    35         // value 62 is internally reserved
    36 #ifdef QT3_SUPPORT
    37         ColorGroup = 63,
    38 #endif
    39         Font = 64,
    40         Pixmap = 65,
    41         Brush = 66,
    42         Color = 67,
    43         Palette = 68,
    44         Icon = 69,
    45         Image = 70,
    46         Polygon = 71,
    47         Region = 72,
    48         Bitmap = 73,
    49         Cursor = 74,
    50         SizePolicy = 75,
    51         KeySequence = 76,
    52         Pen = 77,
    53         TextLength = 78,
    54         TextFormat = 79,
    55         Matrix = 80,
    56         Transform = 81,
    57         Matrix4x4 = 82,
    58         Vector2D = 83,
    59         Vector3D = 84,
    60         Vector4D = 85,
    61         Quaternion = 86,
    62         LastGuiType = Quaternion,
    63 
    64         UserType = 127,
    65 #ifdef QT3_SUPPORT
    66         IconSet = Icon,
    67         CString = ByteArray,
    68         PointArray = Polygon,
    69 #endif
    70         LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
    71     };
    复制代码

    数据类型转换:

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

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

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

    复制代码
    class Q_CORE_EXPORT QVariant
    {
        ......
       template<typename T>
        bool canConvert() const
        { return canConvert(Type(qMetaTypeId<T>())); }
        ......
    }
    复制代码
     
    1 static inline QVariant fromValue(const T &value)
    2     { 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>

    复制代码
     1 #define Q_DECLARE_METATYPE(TYPE)                                        
     2     QT_BEGIN_NAMESPACE                                                  
     3     template <>                                                         
     4     struct QMetaTypeId< TYPE >                                          
     5     {                                                                   
     6         enum { Defined = 1 };                                           
     7         static int qt_metatype_id()                                     
     8             {                                                           
     9                 static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); 
    10                 if (!metatype_id)                                       
    11                     metatype_id = qRegisterMetaType< TYPE >(#TYPE,      
    12                                reinterpret_cast< TYPE *>(quintptr(-1))); 
    13                 return metatype_id;                                     
    14             }                                                           
    15     };                                                                  
    16     QT_END_NAMESPACE
    复制代码

    示例:

    复制代码
    namespace MyNamespace
    {
        struct MyStruct
         {
             int i;
             ...
         };
    }
    
     Q_DECLARE_METATYPE(MyNamespace::MyStruct)
    复制代码
    复制代码
     1 MyStruct s;
     2 QVariant var;
     3 var.setValue(s);
     4 
     5 ......
     6 
     7 QVariant var2 = QVariant::fromValue(s);
     8 if (var2.canConvert<MyStruct>()) 
     9 {
    10     MyStruct s2 = var2.value<MyStruct>();
    11 }
    复制代码

    http://www.cnblogs.com/paullam/p/3706371.html

  • 相关阅读:
    期望DP入门(p1850换教室)
    P2858 [USACO06FEB]奶牛零食Treats for the Cows
    2019 CCF夏令营 day 2
    2019 CCF夏令营 day 1
    双向存图解题
    P3952 时间复杂度
    P1347 排序(拓扑排序)
    清理Docker垃圾
    k8s中command、args和dockerfile中entrypoint、cmd之间的作用
    kubectl命令自动补全
  • 原文地址:https://www.cnblogs.com/findumars/p/6040249.html
Copyright © 2011-2022 走看看