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
打印: