Qt进阶之Q_ENUM、Q_FLAG、Q_DECLARE_FLAGS、Q_DECLARE_OPERATORS_FOR_FLAGS相关宏的深度探秘与点亮高效编程之路

目录

  • 1.Q_ENUM
    • 1.1.概述及用法
    • 1.2.为什么要使用Q_ENUM?
    • 1.3.QMetaEnum类:字符串与枚举相互转换
    • 1.4.QMetaEnum类中的`const char *key(int index) const`和`int value(int index) const`方法
    • 1.5.Q_ENUM和QMetaEnum用法完整示例
  • 2.Q_FLAG相关宏
    • 2.1.Q_FLAG宏概述及用法
    • 2.2.Q_FLAG宏使用注意
    • 2.3.Q_DECLARE_FLAGS宏
    • 2.4.Q_DECLARE_FLAGS宏作用
    • 2.5.Q_DECLARE_FLAGS宏使用
    • 2.6.Q_DECLARE_OPERATORS_FOR_FLAGS宏作用
    • 2.7.Q_FLAG宏、Q_DECLARE_FLAGS宏和Q_DECLARE_OPERATORS_FOR_FLAGS宏组合用法
  • 3.使用函数模板实现字符串和枚举值相互转换
    • 3.1.将单枚举值转换为字符串
    • 3.2.将字符串转换为单枚举值
    • 3.3.将带 | 操作位的枚举值转换为字符串
    • 3.4.将字符串转换为带 | 操作位的枚举值(假设输入字符串格式符合要求,如 "Value1 | Value2")
    • 3.5.调用实例
  • 4.使用类模板实现字符串和枚举值相互转换
    • 4.1.实例

Qt的广袤编程世界里,隐藏着如魔法般强大的元素,那便是Q_ENUMQ_FLAG以及与之紧密相连的Q_DECLARE_FLAGSQ_DECLARE_OPERATORS_FOR_FLAGS。它们犹如神秘的咒语与符文,一旦掌握,便能点亮高效编程之路。无论是构建复杂的图形界面,还是处理底层的数据逻辑,这些Qt进阶魔法都将赋予开发者全新的力量,让代码更加简洁、灵活且美观,接下来就开启一段奇妙的Qt编程升级之旅。

1.Q_ENUM

1.1.概述及用法

这个宏向元对象系统注册一个枚举类型。但是它必须放在具有Q_OBJECT或Q_GADGET宏的类的枚举声明之后。
用法,建议就在枚举后使用,一目了然:

class MainWindow : public QMainWindow
{
   
    Q_OBJECT
public:
    enum _eType{
   
        None = 1 << 0,
        Up = 1 << 1,
        Right = 1 << 2,
        Bottom = 1 << 3,
        Left = 1 << 4
    };
    Q_ENUM(_eType)
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
};

1.2.为什么要使用Q_ENUM?

该方法在Qt 5.5中引入。
使用Q_ENUM声明的枚举会将其QMetaEnum注册到QMetaObject中。
注册后,就可以使用QMetaEnum::fromType()来获取 QMetaEnum
已注册的枚举也会自动注册到Qt元类型系统中,这使得它们能被QMetaType知晓,而无需使用 Q_DECLARE_METATYPE()。这将启用一些有用的功能;例如,如果在QVariant中使用,可以将它们转换为字符串。同样,将它们传递给QDebug会打印出它们的名称。
***Tips***:
注意,在元对象系统中,枚举值存储为有符号整数。注册超出int有效取值范围的枚举值,在通过元对象系统访问它们时会导致溢出,并可能产生未定义行为。例如,QML就是通过元对象系统访问已注册的枚举。
Qt5.5之前的版本要使用Q_ENUMS宏,但Q_ENUMS宏不支持QMetaEnum::fromType()函数来进行字符串和枚举值转换(估计这可能是Q_ENUMS被弃用的原因)。

1.3.QMetaEnum类:字符串与枚举相互转换

在编程过程中,有时会有这样的需求:需要将枚举输出为字符串,或者将字符串转换为枚举值。
可能常见用法是为每一个枚举实现两个接口:1. 枚举转字符串;2. 字符串转枚举。
Qt中,可以通过QMetaEnum类实现。
Qt5.5之前版本实现:

    QMetaObject metaObj = this->staticMetaObject;
    int nEnumIndex = metaObj.indexOfEnumerator("_eType");
    QMetaEnum me = metaObj.enumerator(nEnumIndex);
    qDebug() << QString::fromLocal8Bit("枚举名称 :") << me.name();
    qDebug() << QString::fromLocal8Bit("枚举的key数目 :") << me.keyCount();
    qDebug() << QString::fromLocal8Bit("枚举转字符串 :") << me.valueToKey(Up);
    qDebug() << QString::fromLocal8Bit("字符串转枚举 :") << (_eType)me.keyToValue("Up");

输出:

"枚举名称 :" _eType
"枚举的key数目 :" 5
"枚举转字符串 :" Up
"字符串转枚举 :" MainWindow::Up

Qt5.5及之后版本实现:
可以使用其提供的静态方法QMetaEnum::fromType<MainWindow::_eType>()

    QMetaEnum metaEnum = QMetaEnum::fromType<MainWindow::_eType>();
    qDebug() << QString::fromLocal8Bit("枚举名称 :") << metaEnum.name();
    qDebug() << QString::fromLocal8Bit("枚举的key数目 :") << metaEnum.keyCount();
    qDebug() << QString::fromLocal8Bit("枚举转字符串 :") << metaEnum.valueToKey(Up);
    qDebug() << QString::fromLocal8Bit("字符串转枚举 :") << (_eType)metaEnum.keyToValue("Up");

输出:

"枚举名称 :" _eType
"枚举的key数目 :" 5
"枚举转字符串 :" Up
"字符串转枚举 :" MainWindow::Up

1.4.QMetaEnum类中的const char *key(int index) constint value(int index) const方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FreeLikeTheWind.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值