• 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

  • 相关阅读:
    利用DTrace实时检测MySQl
    改进MySQL Order By Rand()的低效率
    RDS for MySQL查询缓存 (Query Cache) 的设置和使用
    RDS For MySQL 字符集相关说明
    RDS for MySQL 通过 mysqlbinlog 查看 binlog 乱码
    RDS for MySQL Mysqldump 常见问题和处理
    RDS for MySQL Online DDL 使用
    RDS MySQL 表上 Metadata lock 的产生和处理
    RDS for MySQL 如何使用 Percona Toolkit
    北京已成为投融资诈骗重灾区:存好骗子公司黑名单,谨防上当!
  • 原文地址:https://www.cnblogs.com/findumars/p/6040249.html
Copyright © 2020-2023  润新知