ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-08-07 15:32:52  阅读:142  来源: 互联网

标签:QVariant 自定义 UserType 数据类型 qDebug 类型 include


 

  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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有