【QT】枚举常用宏(Q

您所在的位置:网站首页 标志位flag用法 【QT】枚举常用宏(Q

【QT】枚举常用宏(Q

2024-01-29 14:30| 来源: 网络整理| 查看: 265

目录 1. Q_ENUM宏 与 QMetaEnum类1.1 Q_ENUM宏的作用1.2 使用Q_ENUM注意的问题1.3 在写有关枚举的代码时,我们可能遇到这种情况:需要用到枚举的字符串,该怎么办?1.4 下面通过一段简单的代码来说明Q_ENUM的作用 2. Q_FLAG宏2.1 Q_FLAG宏的作用2.2 Q_DECLARE_FLAGS()宏的作用2.3 Q_DECLARE_OPERATORS_FOR_FLAGS()宏的作用2.4 演示代码

1. Q_ENUM宏 与 QMetaEnum类 1.1 Q_ENUM宏的作用 宏Q_ENUM会向元对象系统注册一个枚举类型 1.2 使用Q_ENUM注意的问题 使用Q_ENUM之前,必须在类中先声明Q_OBJECT或Q_GADGET宏。Q_ENUM(枚举类型)必须放在枚举声明之后,放在前面编译器会报错。Q_ENUM宏引入自Qt5.5版本,之前版本的Qt请使用Q_ENUMS宏,但Q_ENUMS宏不支持QMetaEnum::fromType()函数(这也是Q_ENUMS被弃用的原因) 1.3 在写有关枚举的代码时,我们可能遇到这种情况:需要用到枚举的字符串,该怎么办?

这时就需要用到 Q_ENUM宏 和 QMetaEnum类。 用Q_ENUM声明的枚举,其QMetaEnum注册在外部的QMetaObject中。在5.5版本之前可以使用QMetaObject获取QMetaEnum。

//before Qt5.5 QMetaObject object = MyEnum::staticMetaObject; //MyEnum是当前类,staticMetaObject返回类的元对象 int index = object.indexOfEnumerator("Orientation"); //Orientation是枚举的类型 QMetaEnum metaEnum = object.enumerator(index);

也可以使用静态函数QMetaEnum::fromType()来获取QMetaEnum。

QMetaEnum metaEnum = QMetaEnum::fromType(); //MyEnum是当前类,Orientation是枚举的类型

通过QMetaEnum对象就可以获得枚举的一些信息以及枚举类型与字符串类型的转换。

1.4 下面通过一段简单的代码来说明Q_ENUM的作用 #include #include #include class MyEnum : public QDialog { Q_OBJECT public: enum Orientation { Up = 1, Down = 2, Left = 3, Right = 4 }; Q_ENUM(Orientation) //向元对象系统注册枚举类型 MyEnum(QWidget* parent = 0); ~MyEnum(); }; #include "myenum.h" MyEnum::MyEnum(QWidget* parent) : QDialog(parent) { //获取QMetaEnum对象的方法1: //QMetaObject object = MyEnum::staticMetaObject; //before Qt5.5 //int index = object.indexOfEnumerator("Orientation"); //Orientation是枚举的类型 //QMetaEnum metaEnum = object.enumerator(index); //获取QMetaEnum对象的方法2: QMetaEnum metaEnum = QMetaEnum::fromType(); //通过静态函数fromType获取QMetaEnum对象 //QMetaEnum会对所有的枚举进行下标编号,从0开始 QString name = metaEnum.name(); //枚举名称 int count = metaEnum.keyCount(); //枚举数量 QString keyIndex = metaEnum.key(0); //下标为0的key int valueIndex = metaEnum.value(0); //下标为0的value QString Key = metaEnum.valueToKey(MyEnum::Left); //通过value得到key int value = metaEnum.keyToValue("Left"); //通过key得到value qDebug() Up = 0x01, //即0000...0001 Down = 0x02, //即0000...0010 Left = 0x04, //即0000...0100 Right = 0x08 //即0000...1000 }; 2.2 Q_DECLARE_FLAGS()宏的作用

Q_DECLARE_FLAGS(Flags, Enum)宏展开为:

typedef QFlags Flags;

QFlags是一个模板类,其中Enum是枚举类型,QFlags用于存储枚举值的组合。

传统的 C++ 编程中,通常使用整数来保存 enum 的逻辑运算结果 (与、或、非、异或等),在进行逻辑运算的时候没有进行类型检查,一个枚举类型可以和其他的枚举类型进行逻辑运算,运算的结果可以直接传递给接收参数为整数的函数。

下面看一个例子:

enum Orientation { Up = 1, //即0000...0001 Down = 2, //即0000...0010 Left = 4, //即0000...0100 Right = 8 //即0000...1000 }; enum Direction { horizontal = 1, vertical = 2 };

这种操作编译器不会报错:

Orientation::Up | Direction::horizontal; //两个不相关的枚举值做逻辑运算没有意义

对于上面的问题,应该怎么解决? Qt 中,模板类 QFlags 提供了类型安全的方式保存 enum 的逻辑运算结果,来解决上面的问题。

这种方式在 Qt 里很常见,例如设置 QLabel 对齐方式的函数是 QLabel::setAlignment(Qt::Alignment) (typedef QFlagsQt::AlignmentFlag Qt::Alignment),这就意味着传给 setAlignment 的参数只能是枚举 Qt::AlignmentFlag 的变量、它们的逻辑运算结果或者 0,如果传入其他的枚举类型或者非 0 值,编译时就会报错,例如:

label->setAlignment(0); // OK label->setAlignment(Qt::AlignLeft | Qt::AlignTop); // OK label->setAlignment(Qt::WA_Hover); // Error: 编译时报错

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

2.3 Q_DECLARE_OPERATORS_FOR_FLAGS()宏的作用 Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)赋予了Flags一个全局操作符“|”,没有这个宏语句,Flags量之间进行与操作后的结果将是一个int值,而不是Flags值。这点特别重要。Q_DECLARE_OPERATORS_FOR_FLAGS必须定义在类外。Q_DECLARE_OPERATORS_FOR_FLAGS只提供了“或”操作,没有提供“与”“非”操作。Q_DECLARE_FLAGS和Q_DECLARE_OPERATORS_FOR_FLAGS都是和元对象系统无关的,可以脱离Q_FLAG单独使用,事实上这两个宏在Qt4就已经存在(不确定更早是否存在),而Q_FLAG是在Qt5.5版本才加入的。 2.4 演示代码 #include #include #include #include class MyEnum : public QDialog { Q_OBJECT public: enum Orientation { Up = 0x01, //即0000...0001 Down = 0x02, //即0000...0010 Left = 0x04, //即0000...0100 Right = 0x08 //即0000...1000 }; Q_ENUM(Orientation) Q_DECLARE_FLAGS(Orientations, Orientation) Q_FLAG(Orientations) MyEnum(QWidget* parent = 0); ~MyEnum(); }; Q_DECLARE_OPERATORS_FOR_FLAGS(MyEnum::Orientations) #include "myenum.h" MyEnum::MyEnum(QWidget* parent) : QDialog(parent) { QMetaEnum metaEnum = QMetaEnum::fromType(); //通过静态函数fromType获取QMetaEnum对象 QString name = metaEnum.name(); //枚举名称 int count = metaEnum.keyCount(); //枚举数量 QString keyIndex = metaEnum.key(0); //下标为0的key int valueIndex = metaEnum.value(0); //下标为0的value QString Key = metaEnum.valueToKeys(MyEnum::Left | MyEnum::Right); //通过value得到key int value = metaEnum.keysToValue("Up | Down"); //通过key得到value qDebug()


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3