Qt 枚举

Qt中的枚举变量,Q_ENUM,Q_FLAG,Q_NAMESPACE,Q_ENUM_NS,Q_FLAG_NS以及其他
Qt QMetaEnum Class
Qt Q_ENUM(…)
Qt Q_FLAG(…)

Q_ENUM 宏注册枚举类型

1

QMetaEnum

QMetaEnum功能方法(QT5.12)
Qt中的枚举变量,Q_ENUM,Q_FLAG,Q_NAMESPACE,Q_ENUM_NS,Q_FLAG_NS以及其他

Qt 帮助文档说明:

2


注意:如果要用或结合,isFlag() 必须时true

头文件:

#include <QWidget>
#include <QDebug>
#include <QMetaEnum>

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    enum Priority {High = 1, Low = 2, VeryHigh = 4, VeryLow = 8};
    Q_ENUM(Priority)

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

源文件:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowModality(Qt::ApplicationModal);
    
    qDebug() << Priority::High << Priority::Low;
    QMetaEnum metaEnum  = QMetaEnum::fromType<Widget::Priority>();
    int count = metaEnum.keyCount(); //4

    for (int i = 0; i < count; ++i)
    {
        qDebug() << i << ") key: " << metaEnum.key(i) << "; value: " << metaEnum.value(i);
    }

    //Returns the name of the type (without the scope).
    qDebug()<< "name: " << metaEnum.name();
    //Returns the enum name of the flag (without the scope).
    qDebug()<< "enumName: " << metaEnum.enumName();

    //如果此枚举用作标志,则返回true;否则返回false; 当用作标志时,可以使用OR运算符组合枚举数
    qDebug()<< "isFlag: " << metaEnum.isFlag();

    //如果此枚举数声明为C++11枚举类,则返回true;否则返回false
    qDebug()<< "isScoped: " << metaEnum.isScoped();
    
    //如果此枚举有效(有名称),则返回true;否则返回false
    qDebug()<< "isValid: " << metaEnum.isValid(); 
    qDebug()<< "keyCount: " << metaEnum.keyCount(); //返回键个数

    //返回具有给定索引的键,如果不存在这样的键,则返回0。 "VeryHigh"
    qDebug()<< "key(2): " << metaEnum.key(2);
    //返回给定枚举键的整数值,如果未定义键,则返回-1
    qDebug()<< "keyToValue(\"High\"): " << metaEnum.keyToValue("High");

    //返回使用OR运算符组合键的值,如果未定义键,则返回-1
    //请注意,键中的字符串必须以“|”分隔; 需要 isFlag 为 true
    qDebug()<< "keysToValue(\"High|VeryHigh\"): " << metaEnum.keysToValue("High|VeryHigh");

    //返回此枚举数在其中声明的范围。即所属类/namespace的名字  MainWindow
    qDebug()<< "scope: " << metaEnum.scope();
    qDebug()<< "value(0): " << metaEnum.value(0); //参数为索引值,返回索引对应的 value
    qDebug()<< "value(1): " << metaEnum.value(1);
    qDebug()<< "value(2): " << metaEnum.value(2);
    qDebug()<< "value(3): " << metaEnum.value(3);
    qDebug()<< "value(4): " << metaEnum.value(4); //索引超范围,返回-1。
    //参数为 value,返回对应的 key Low
    qDebug()<< "valueToKey(2): " << metaEnum.valueToKey(Priority::Low); 

    //用 | 结合,isFlag() 必须是 true,返回表示给定值的由“|”分隔键组成的字节数组。"Low|VeryHigh"
    qDebug()<< "valueToKeys(1|2): " << metaEnum.valueToKeys(Priority::High|Priority::Low);
}

输出为:

3

  1. 尽管定义的枚举值分别为 1, 2, 4, 8,可以用或运算组合,但仍不是 flag,isFlagfalse
  2. const char *QMetaEnum::key(int index) const,中的参数为索引,索引不是键值,根据枚举声明时的顺序,第一个为 0,依次递增,因此 key(2)VeryHigh;返回的为枚举的名字,而不是枚举的整数值。
  3. int QMetaEnum::keyToValue(const char *key, bool *ok = nullptr) const,参数为枚举名字,如 High,返回的是该键的整型数值。
  4. int QMetaEnum::value(int index) const 函数参数为索引,返回整型键值。
  5. keysToValuevalueToKeys 需要 isFalgtrue

让枚举能作为 flag 使用

头文件做如下改变:

```cpp
#include <QWidget>
#include <QDebug>
#include <QMetaEnum>

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    enum Priority {High = 1, Low = 2, VeryHigh = 4, VeryLow = 8};
    Q_DECLARE_FLAGS(Priorities, Priority)
    Q_FLAG(Priority)

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

Q_DECLARE_OPERATORS_FOR_FLAGS(Widget::Priorities)

其中 Q_DECLARE_FLAGS(Flags, Enum) 宏定义为 typedef QFlags<Enum> Flags;

源文件不变,但输出结果改变:

4


这是 isFlag 才为 true
注意这里不用 Q_ENUM() 宏。
metaEnum.valueToKeys(1|2) 也可以写为 metaEnum.valueToKeys(Priority::High|Priority::Low)

作为标志位使用,利用运算检查是否存在某个标志位:

Widget::Priorities flag;
flag.setFlag(Priority::Low);
qDebug() << "flag: " << flag;

auto testFlag = [](Widget::Priorities flag){
   if (flag.testFlag(Priority::Low))
       qDebug() << "flag Priority::Low is set";
   if (flag.testFlag(Priority::High))
       qDebug() << "flag Priority::High is set";
   if (flag.testFlag(Priority::VeryLow))
       qDebug() << "flag Priority::VeryLow is set";
   if (flag.testFlag(Priority::VeryHigh))
       qDebug() << "flag Priority::VeryHigh is set";
};

testFlag(Priority::Low | Priority::VeryLow);

输出:

flag:  QFlags<Widget::Priority>(Low)
flag Priority::Low is set  
flag Priority::VeryLow is set
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值