• QT笔记——QMetaEnum类


    我们常常想 知道 枚举类型 如何输出对应的英文 而不是数字呢?
    QT为我们提供了QMetaEnum类 解决了 这样的需求

    在这里插入图片描述

    返回定义的枚举的名称: enumName()
    是否作为标志: isFlag()
    是否作为c++11枚举 isScoped()
    枚举是否有效 isValid()
    返回枚举数量:keyCount()
    返回index序号对应的key key()
    根据index序号返回枚举整型值value value()
    枚举变量名 name()
    返回枚举定义所在类名 scope()
    返回整型枚举值value keyToValue
    返回value对应枚举名key valueToKey

    什么是c++11的枚举,和普通枚举有什么不一样,怎么写的呢

    c++11写法:
    enum class Day
    {
    	ONE,
    	TWO,
    	THREE,
    	FOUR,
    	FIVE
    };
    c++普通写法:
    enum Day
    {
    	ONE,
    	TWO,
    	THREE,
    	FOUR,
    	FIVE
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    普通枚举与c++11枚举的区别

    使用QMetaEnum 必须要有Q_OBJECT宏 还有Q_ENUM()或者Q_FLAG()

    #pragma once
    
    #include 
    #include "ui_QMetaEnumTest.h"
    #include 
    #include 
    class QMetaEnumTest : public QWidget
    {
        Q_OBJECT
    public:
    	enum class NUMBER
    	{
    		ONE,
    		TWO,
    		THREE,
    		FOUR,
    		FIVE
    	};
    	Q_ENUM(NUMBER) //注册枚举
    
    	enum Orientation
    	{
    		Up = 1,
    		Down = 2,
    		Left = 4,
    		Right = 8,
    	};
    	Q_DECLARE_FLAGS(OrientationFlags, Orientation) // 相当于 QFlags OrientationFlags;
    	Q_FLAG(OrientationFlags)                       //将OrientationFlags 注册为元对象
    
    public:
        QMetaEnumTest(QWidget *parent = Q_NULLPTR);
    
    	void enumTest();
    	void flagTest();
    private:
        Ui::QMetaEnumTestClass ui;
    };
    Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaEnumTest::OrientationFlags)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    #include "QMetaEnumTest.h"
    
    QMetaEnumTest::QMetaEnumTest(QWidget* parent)
    	: QWidget(parent)
    {
    	ui.setupUi(this);
    
    	enumTest();
    	flagTest();
    }
    
    void QMetaEnumTest::enumTest()
    {
    	QMetaEnum metaEnum = QMetaEnum::fromType<NUMBER>();
    
    	qDebug() << "[" << "file:" << __FILE__ << "line:" << __LINE__ << "]" << "enumName() :" << metaEnum.enumName();
    	qDebug() << "[" << "file:" << __FILE__ << "line:" << __LINE__ << "]" << "isFlag() :" << metaEnum.isFlag();
    	qDebug() << "[" << "file:" << __FILE__ << "line:" << __LINE__ << "]" << "isScoped():" << metaEnum.isScoped();
    	qDebug() << "[" << "file:" << __FILE__ << "line:" << __LINE__ << "]" << "isValid() :" << metaEnum.isValid();
    	qDebug() << "[" << "file:" << __FILE__ << "line:" << __LINE__ << "]" << "key(0) :" << metaEnum.key(0);
    	qDebug() << "[" << "file:" << __FILE__ << "line:" << __LINE__ << "]" << "keyCount() :" << metaEnum.keyCount();
    	qDebug() << "[" << "file:" << __FILE__ << "line:" << __LINE__ << "]" << "keyToValue() :" << metaEnum.keyToValue("THREE");
    	qDebug() << "[" << "file:" << __FILE__ << "line:" << __LINE__ << "]" << "name() :" << metaEnum.name();
    	qDebug() << "[" << "file:" << __FILE__ << "line:" << __LINE__ << "]" << "scope() :" << metaEnum.scope();
    	qDebug() << "[" << "file:" << __FILE__ << "line:" << __LINE__ << "]" << "value() :" << metaEnum.value(1);
    	qDebug() << "[" << "file:" << __FILE__ << "line:" << __LINE__ << "]" << "valueToKey() :" << metaEnum.valueToKey(0);
    
    }
    
    void QMetaEnumTest::flagTest()
    {
    	qDebug() << (Up |Down);
    	//注意这里不是  Orientation,因为 我们没有用Q_ENUM来注册枚举  我们需要写包装后的枚举类型
    	QMetaEnum metaEnum = QMetaEnum::fromType<OrientationFlags>();
    	
    	//我们使用keyToValue 和 valueToKey  不生效  因为这是复合类型  这个是没有经过重载的
    	qDebug() << "keyToValue:" << metaEnum.keyToValue("Up|Down");
    	qDebug() << "valueToKey:" << metaEnum.valueToKey(Up | Down);
    	//我们需要使用keysToValue  和 valueToKeys 才生效 
    	//经过Q_FLAG包装之后,QMetaEnum具有了操作复合枚举量的能力,所以
    	qDebug() << "keysToValue:" << metaEnum.keysToValue("Up|Down");
    	qDebug() << "valueToKeys:" << metaEnum.valueToKeys(Up | Down);
    
    	qDebug() << "isFlag:" << metaEnum.isFlag();
    	//包装后的类型
    	qDebug() << "name:" << metaEnum.name();
    	//包装前的类型
    	qDebug() << "enumName:" << metaEnum.enumName();               
    	qDebug() << "scope:" << metaEnum.scope() << endl;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    运行结果:
    Q_ENUM()下:
    在这里插入图片描述
    在这里插入图片描述
    Q_DECLARE_FLAGS(Flags, Enum) 实际上被展开成typedef QFlags< Enum > Flags
    在这里插入图片描述
    Q_DECLARE_FLAGS实际上是QFlags的定义式,之后才能使用Q_FLAG(Flags)把定义的Flags注册到元对象系统

    Q_DECLARE_FLAGS(Flags, Enum)宏将普通结构体Enum重新定义成了一个可以自由进行与或非操作的安全的结构体Flags。

    当我们在类的结尾写上Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaEnumTest::OrientationFlags)
    在这里插入图片描述
    如果不加该宏:
    在这里插入图片描述
    我们发现 打印的第一个,不一样,此时我们就可以看出这个宏的作用:
    Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)赋予了Flags一个全局操作符“|”,没有这个宏语句,Flags之间进行与操作后的结果将是一个int值,而不是Flags值。Q_DECLARE_OPERATORS_FOR_FLAGS应当定义在类外;

    参考博客:
    Q_ENUM,Q_FLAG,Q_NAMESPACE,Q_ENUM_NS,Q_FLAG_NS介绍
    QT QMetaEnum类

  • 相关阅读:
    一文解读 SmartX 超融合虚拟化下的网络 I/O 虚拟化技术
    React如何优化减少组件间的重新Render
    docker mysql 5.7
    【夜读】影响一生的五个自律法则
    MySQL数据库面试题总结(2022最新版)
    标准算法的征集及启示
    FFmpeg 命令:从入门到精通 | ffmpeg 命令直播
    【JVM笔记】堆的核心概述与堆空间大小的设置与查看
    工作和生活中,如何用项目管理思维解决复杂的事情?
    DX::ThrowIfFailed使用
  • 原文地址:https://blog.csdn.net/lion_cxq/article/details/125900562