其他分享
首页 > 其他分享> > QVariant::UserType QVariant自定义数据类型的深入认识

QVariant::UserType QVariant自定义数据类型的深入认识

作者:互联网

 

  1 /*************************************************
  2 Copyright: zhm_xxbs@2022
  3 Author: 张洪铭
  4 Date: 2022年08月07日
  5 Description:主要围绕QVariant类型,编写代码深入认识 QVariant::UserType。
  6 总结:
  7 1. 自定义枚举类型。
  8    1)QVariant::type() 不能识别到 QVariant::UserType类型;
  9    2)使用 Q_ENUM() 注册到元对象系统内的枚举类型,可以用QDebug()打印出值的名字;
 10 
 11 2. 自定义类类型
 12    1)紧邻类型声明后,使用 Q_DECLARE_METATYPE() 宏;
 13    2)存入QVariant时,使用 QVariant::fromValue() 静态函数;
 14    3)QVariant::type() 的结果不准确,函数返回 QVariant::QWidget*, 而非 QVariant::UserType。但是可以识别到 QVariant::UserType类型;
 15    4)可以组合使用 QVariant::typeName() 和 value<T>(),进而得到自定义类类型的值;
 16 
 17 3. 自定义容器类型::与自定义类类型行为一致
 18 
 19 4. Qt提供的非QVariant默认支持的类类型
 20     1)不需要使用 Q_DECLARE_METATYPE();
 21     2)前提条件:"it provides a public default constructor, a public copy constructor and a public destructor"。
 22     3)如果满足条件“2)",可直接作为自定义类型数据使用;
 23     4)如果不满足条件“2)",就是不满足 QMetaType 要求;只能使用类型的指针;
 24 
 25 注意项:
 26 1. QVariant::canConvert() 返回true,仅仅表示有转换为类型T能力,并不代表 QVariant::convert()就是true,要根据数据内容来决定。
 27 2. QVariant 在类型转换时,原数据不动,新拷贝出一个临时对象进行转换。
 28    因此,自定义的类类型,使用 QVariant 存储,一定要具备共有的默认构造函数,共有的拷贝构造函数,公有的析构函数。
 29 
 30 问:
 31 1. 怎样可以做到,自定义类型存入 QVariant 时,不需要使用 QVariant::fromValue() 静态函数,有可能吗?
 32 2. 自定义类型 QVariant::type()函数返回 QVariant::QWidget*, 而非 QVariant::UserType,是哪里弄错了吗?
 33 **************************************************/
 34 
 35 #ifndef STUDYQVARIANT_H
 36 #define STUDYQVARIANT_H
 37 
 38 #include <string>
 39 #include <map>
 40 
 41 #include <QObject>
 42 #include <QVariant>
 43 #include <QDebug>   //可以打印注册到 “Qt meta type system” 的自定义类型
 44 #include <QWidget>  //提供GUI模块里的Qt类型 (代表:widgets模块)
 45 #include <QLabel>   //提供GUI模块里的Qt类型 (代表:widgets模块)
 46 #include <QSharedMemory>  //提供QObject子类Qt类型 (代表:core模块)
 47 #include <QEvent>  //提供非QObject子类的Qt类型 (代表:core模块)
 48 #include <QPixmap> //提供非QObject子类的Qt类型 (代表:gui模块)
 49 
 50 /*
 51  * 自定义枚举类型如何用 QVariant 来存放 ("未注册元对象系统")
 52  * Enum-Type:UserType_CountryEnum
 53 */
 54 enum UserType_CountryEnum{China, Russia};
 55 //Q_ENUM(UserType_CountryEnum) "Q_ENUM must be placed in a class that has the Q_OBJECT or the Q_GADGET macro"
 56 Q_DECLARE_METATYPE(UserType_CountryEnum) //makes the type known to QMetaType
 57 
 58 
 59 /*
 60  * 自定义类类型如何使用 QVariant 类存放("未注册元对象系统")
 61  * Class_Type::UserType_SocialMan
 62 */
 63 struct UserType_SocialMan{
 64     QString name = "zhm_xxbs";
 65     int age = 26;
 66 };
 67 
 68 /*
 69  * 自定义类类型如何使用 QVariant 类存放 ("注册元对象系统")
 70  * Class_Type::UserType_Student
 71 */
 72 struct UserType_Student{
 73     QString name = "zhm";
 74     int age = 21;
 75 };
 76 Q_DECLARE_METATYPE(UserType_Student) //makes the type known to QMetaType
 77 
 78 /*
 79  * 自定义非Qt容器类型如何使用 QVariant 类存放("注册元对象系统")
 80  * STL_Type:UserType_IDCard
 81 */
 82 typedef std::map<std::string, std::string> UserType_IDCard;
 83 Q_DECLARE_METATYPE(UserType_IDCard)
 84 
 85 
 86 class StudyQVariant : public QObject
 87 {
 88     Q_OBJECT
 89 public:
 90     explicit StudyQVariant(QObject *parent = nullptr);
 91 
 92     /*
 93      * 自定义枚举类型如何用 QVariant 来存放("注册元对象系统")
 94      * Enum-Type:UserType_SexEnum
 95      *
 96     */
 97     enum UserType_SexEnum{male, female};
 98     Q_ENUM(UserType_SexEnum)  //"registers an enum type with the meta-object system"
 99     Q_DECLARE_FLAGS(UserType_SexEnums, UserType_SexEnum)
100 
101 private:
102     void storeUserTypeData(); //把各种用户自定义类型的值存放在 QVariant 里面
103     void printAllDatas(); //把存放在 QVariant 里面的各种用户自定义类型的值打印出来
104 
105 private:
106     QVariantList userType_datas; //存放各种用户自定义数据
107 };
108 Q_DECLARE_METATYPE(StudyQVariant::UserType_SexEnum) //makes the type known to QMetaType
109 
110 #endif // STUDYQVARIANT_H

 

 

#include "StudyQVariant.h"

StudyQVariant::StudyQVariant(QObject *parent) : QObject(parent)
{
    storeUserTypeData();
    printAllDatas();
}

void StudyQVariant::storeUserTypeData()
{
    int index = 0;
    qDebug()<<"把自定义类型数据逐个存入 QVariant 中||||||||||||||||||||||||||||||||||||||||||||";

    qDebug()<<"第"<<++index<<"个:"<<"自定义枚举类型(\"未注册 Qt-meta-type-system\")";
    userType_datas.push_back(UserType_CountryEnum::China);

    qDebug()<<"第"<<++index<<"个:"<<"自定义枚举类型(\"已注册 Qt-meta-type-system\")";
    userType_datas.push_back(UserType_SexEnum::male);

#if 0 //错误写法
    qDebug()<<"自定义类类型(\"未注册 Qt-meta-type-system\")";
    userType_datas.push_back(UserType_SocialMan());

    qDebug()<<"自定义类类型(\"已注册 Qt-meta-type-system\")";
    userType_datas.push_back(UserType_Student());
#else
    qDebug()<<"自定义类类型(\"未注册 Qt-meta-type-system\"), 不可以存入 QVariant";
    //userType_datas.push_back(QVariant::fromValue(UserType_SocialMan()));

    qDebug()<<"第"<<++index<<"个:"<<"自定义类类型(\"已注册 Qt-meta-type-system\")";
    userType_datas.push_back(QVariant::fromValue(UserType_Student()));
#endif

    qDebug()<<"第"<<++index<<"个:"<<"自定义非Qt容器类型(\"已注册 Qt-meta-type-system\")";
    userType_datas.push_back(QVariant::fromValue(UserType_IDCard{{"zhm", "0001"}}));

    qDebug()<<"第"<<++index<<"个:"<<"GUI模块里的类型 QColor (\"不用注册 Qt-meta-type-system\")";
    userType_datas.push_back(QColor(110, 112, 119));

    qDebug()<<"第"<<++index<<"个:"<<"Qt提供GUI模块里的类型 QPoint (\"不用注册 Qt-meta-type-system\")";
    userType_datas.push_back(QVariant::fromValue(QPoint(0, 0)));

    qDebug()<<"Qt提供GUI模块里的类型 QLabel,没有 public-copy 不可以存入QVariant";
    //userType_datas.push_back(QVariant::fromValue(QLabel("I'am a label gui")));

    qDebug()<<"第"<<++index<<"个:"<<"Qt提供GUI模块里的类型 QLabel* (\"不用注册 Qt-meta-type-system\")";
    userType_datas.push_back(QVariant::fromValue(new QLabel("I'am a label gui-pointer")));

    qDebug()<<"Qt提供Qbject非控件子类类型 QSharedMemory,没有 public-copy 不可以存入QVariant";
    //userType_datas.push_back(QVariant::fromValue(QSharedMemory("I'am a sharedMemory object")));

    qDebug()<<"第"<<++index<<"个:"<<"Qt提供Qbject非控件子类类型 QSharedMemory*  (\"不用注册 Qt-meta-type-system\")";
    userType_datas.push_back(QVariant::fromValue(new QSharedMemory("I'am a sharedMemory object-pointer")));

    qDebug("");
}

void StudyQVariant::printAllDatas()
{
    qDebug()<<"循环的打印用户自定义类型的数据类型、类型名称、转换为 QString值和数据值||||||||||||||||||||||||||||||||||||||||||||";
    foreach (QVariant var, userType_datas) {
        static int index = 0;
        qDebug()<<"第"<<++index<<"个:";

        qDebug()<<"type():"<<var.type();            ///[枚举类型-失败] [类类型-不准确]
        qDebug()<<"typeName():"<<var.typeName();    ///[枚举类型-失败] [类类型-成功]

        //注册到元对象系统的自定义类型,可以转换为对应的名称
        qDebug()<<"toString():"<<var.toString();    ///[枚举类型-成功] [类类型-失败]

        switch (var.type()) {
        case QVariant::UserType:                    ///[枚举类型-失败] [类类型-不准确][类类型-能匹配上]
            qDebug()<<"用户自定义类型";

            if (!strcmp(var.typeName(), "UserType_Student")) ///[类类型-成功]
            {
                auto _st = var.value<UserType_Student>();
                qDebug()<<_st.name<<"; "<<_st.age;
            }
            if (!strcmp(var.typeName(), "UserType_IDCard"))
            {
                auto _idCard = var.value<UserType_IDCard>();
                qDebug()<<QString::fromStdString(_idCard.begin()->first)<<"; "<<QString::fromStdString(_idCard.begin()->second);
            }
            if (!strcmp(var.typeName(), "QLabel*"))
            {
                qDebug()<<"第"<<index<<"个:"<<var.value<QLabel*>()->text();
            }
            if (!strcmp(var.typeName(), "QSharedMemory*"))
            {
                qDebug()<<"第"<<index<<"个:"<<var.value<QSharedMemory*>()->key();
            }
            break;
        default:
            qDebug()<<"非用户自定义类型";
            break;
        }
    }
    qDebug("");

    qDebug()<<"挨个针对性的打印用户自定义类型的值||||||||||||||||||||||||||||||||||||||||||||";
    int index = 0;
    qDebug()<<"第"<<index<<"个:"<<userType_datas.at(index++).value<UserType_CountryEnum>();   ///[枚举类型-失败 (非Q_ENUM)]
    qDebug()<<"第"<<index<<"个:"<<userType_datas.at(index++).value<UserType_SexEnum>();       ///[枚举类型-成功 (Q_ENUM)]

    UserType_Student _st = userType_datas.at(index++).value<UserType_Student>();
    UserType_Student _sstt = qvariant_cast<UserType_Student>(userType_datas.at(3));
    qDebug()<<"第"<<index<<"个:"<<_st.name<<"; "<<_sstt.age;

    UserType_IDCard _idCard = userType_datas.at(index++).value<UserType_IDCard>();
    qDebug()<<"第"<<index<<"个:"<<QString::fromStdString(_idCard.begin()->first)<<"; "<<QString::fromStdString(_idCard.begin()->second);

    qDebug()<<"第"<<index<<"个:"<<userType_datas.at(index++).value<QColor>();

    QPoint _pt = userType_datas.at(index++).toPoint();
    qDebug()<<"第"<<index<<"个:"<<_pt;

    QLabel* _label = userType_datas.at(index++).value<QLabel*>();
    qDebug()<<"第"<<index<<"个:"<<_label->text();
    delete _label; _label = nullptr;

    QSharedMemory *_shMe = userType_datas.at(index++).value<QSharedMemory*>();
    qDebug()<<"第"<<index<<"个:"<<_shMe->key();
    delete _shMe; _shMe = nullptr;

    qDebug("");
}

 

标签:QVariant,自定义,UserType,数据类型,qDebug,类型,include
来源: https://www.cnblogs.com/azbane/p/16559135.html