关于Q_ENUMS和Q_ENUM的区别和用法

1.使用Q_ENUM

1).枚举定义和Q_ENUM都在Q_OBJECT下面并且在public上面

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
    enum Action { Open, Save, New, Copy, Cut, Paste, Undo, Redo, Delete };
    Q_ENUM(Action)
public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

    void printEnums(Action a);
private:
    Ui::Widget *ui;

};

#endif // WIDGET_H

编译的时候提示错误:

debug\moc_widget.cpp:70:24: error: 'Widget::Action Open' is private within this context
        2, uint(Widget::Open),

此时把枚举ACtion当成私有的了,于是改变写法如下:

2).Q_ENUM在public上面Q_OBJECT下面,枚举定义在public下面:

此时编译又发现:E:\QtPro\test\test_qobject_moc\widget.h:14: error: unknown type name 'Action' 

3).把枚举的定义和Q_EUNM宏都写在public下面

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT


public:

    enum Action { Open, Save, New, Copy, Cut, Paste, Undo, Redo, Delete };
    Q_ENUM(Action)
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

    void printEnums(Action a);
private:
    Ui::Widget *ui;

};

#endif // WIDGET_H



调用方式:
    printEnums(Action::Undo);
    printEnums(Widget::Save);

此时编译运行,输出如下:

打印出来的是枚举的名字,不是值。

此时,改成Q_ENUMS:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT


public:
    enum Action { Open, Save, New, Copy, Cut, Paste, Undo, Redo, Delete };
    Q_ENUMS(Action)
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

    void printEnums(Action a);
private:
    Ui::Widget *ui;

};

#endif // WIDGET_H

调用方式同上,输出如下:

4).在public之上和Q_OBJECT之下使用枚举的方式:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
    typedef  enum __Action { Open, Save, New, Copy, Cut, Paste, Undo, Redo, Delete }Action;
    Q_ENUM(Action)

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

    void printEnums(Action a);
private:
    Ui::Widget *ui;

};

#endif // WIDGET_H

调用方式同上,输出结果如下:

此时,把Q_ENUM改成Q_ENUMS:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
    typedef  enum __Action { Open, Save, New, Copy, Cut, Paste, Undo, Redo, Delete }Action;
    Q_ENUMS(Action)

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

    void printEnums(Action a);
private:
    Ui::Widget *ui;

};

#endif // WIDGET_H

输出如下:

官方的总结:

Conclusion

Q_ENUM is like the old Q_ENUMS but with those differences:

  • It needs to be placed after the enum in the source code.
  • Only one enum can be put in the macro.
  • It enables QMetaEnum::fromType<T>().
  • These enums are automatically declared as a QMetaTypes (no need to add them in Q_DECLARE_METATYPE anymore).
  • enums passed to qDebug will print the name of the value rather than the number.
  • When put in a QVariant, toString gives the value name.
  • The value name is printed by QCOMPARE (from Qt 5.6).

You can read more articles about Qt internals on our blog.

微博:https://woboq.com/blog/q_enum.html

新加一种枚举的写法:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT


    typedef  enum __Action { Open, Save, New, Copy, Cut, Paste, Undo, Redo, Delete }Action;
    Q_CLASSINFO("Author", "Oscar Peterson")
    Q_CLASSINFO("URL", "http://www.my-organization.qc.ca")
    Q_PROPERTY(Priority priority READ priority WRITE setPriority)

    Q_ENUMS(Action)
    enum Option {
           OptionA = 0x1,  
           OptionB = 0x2, 
           OptionC = 0x4,  
           OptionD = 0x8,  
           OptionE = 0x10 
                 };
    Q_DECLARE_FLAGS(Options, Option)

public:

#if 1
    //这种写法打印出来的是枚举的名字
    enum Priority {
        High, Low, VeryHigh, VeryLow
    };

    Q_ENUM(Priority)
#endif
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

    void setPriority(Priority priority) { m_priority = priority; }
    Priority priority() const { return m_priority; }

    void printEnums(Action a);
    void printEnum(Priority p);
    void printEnum(Option p);


private:
    Ui::Widget *ui;
    Priority m_priority;
};

#endif // WIDGET_H

打印:

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
回答: 根据你提供的引用内容,错误提示中显示了一个ninja错误,指出缺少文件'src/lib/events/libevents/events/common.json',并且没有已知的规则来生成它。\[3\]这个错误可能是由于缺少该文件或者构建系统中缺少生成该文件的规则导致的。你可以检查一下构建系统的配置,确保所有的依赖文件都存在,并且构建规则正确配置。如果文件确实缺失,你需要找到该文件并将其添加到相应的位置。如果构建规则有误,你需要修复构建系统的配置,以确保正确生成所需的文件。 #### 引用[.reference_title] - *1* [CMakeList编译报错ninja: error: missing and no known rule to make it解决方法](https://blog.csdn.net/gxhea/article/details/115616602)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Android.bp编译提示ninja: error: unknown target ‘MODULES-IN-xxx‘终极指南](https://blog.csdn.net/tkwxty/article/details/105142182)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [maven 加入json-lib.jar 报错 Missing artifact net.sf.json-lib:json-lib:jar:2.4:compile](https://blog.csdn.net/jiazimo/article/details/17265061)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Liu-Eleven

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

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

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

打赏作者

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

抵扣说明:

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

余额充值