C++ 预处理器和 QT MOC
C++ Preprocessor and QT MOC
我正在尝试一些事情(也许是愚蠢的)。
已使用一些宏在 C++ 域中创建 "amounts" 个函数;
#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
type name() { return m_##name; } \
void set##name(type data) { m_##name = data; }
#include <backend/config.i>
#undef THR_CONFIG_VALUE
基于以下 config.i 文件:
THR_CONFIG_VALUE("", "type", int, ThisType, 0)
THR_CONFIG_VALUE("", "auto", bool, AutoVar1, false)
THR_CONFIG_VALUE("", "auto", bool, AutoVar2, false)
效果很好,我得到了一些 getter setter 函数,也以相同的方式生成成员变量(备案)。
现在我开始混用 QT 的东西,尝试使用 MOC 生成 Q_PROPERTIES:
#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
Q_PROPERTY(type name READ name WRITE set##name NOTIFY indexChanged)
#include <backend/vessel/thruster/thruster_config.i>
#undef THR_CONFIG_VALUE
交通部不理会此类企图。这本来可以让我少输入 170 Q_PROPERTY 行,将来还会少输入 100 行。
问题1:为什么,预处理器和MOC序列?
问题2:有没有"QT way"?
谢谢,
Qt 有自己的方法来像您一样根据变量的名称生成 getter 和 setter。
我已经为 Qt 实现了一个宏,它可以满足您的需求,但它必须在 QObject
或 Q_GADGET
的上下文中使用。 (Q_PROPERTY
不能在它们之外使用。)
当我第一次写这个宏时,我不明白 Q_PROPERTY 不生成 setter、getter、通知方法,甚至不存储值。这些需要单独生成(在宏中很容易)。
Q_PROPERTY
的 NOTIFY
部分需要定义 signal
。由于信号在调用预处理器之前由 MOC 编码为 C++,因此使用 #define
将不起作用。 (我的代码中没有使用 NOTIFY
。)
不完整的例子:
#define THR_CONFIG_VALUE(type, name) \
Q_PROPERTY(type name READ name WRITE set##name) \
type m_##name; \
void set##name(const type &a_value) { m_##name = a_value; } \
...
现在我有了一个有效的实现。使用了 Verdigris 的贡献。
有点棘手,必须启用 c++14 并将此定义添加到 PRO 文件中:
DEFINES += __cpp_constexpr=201304 __cpp_variable_templates=201304
还因为我使用了名称空间;必须在命名空间内执行包含:
FRONTEND_BEGIN_NAMESPACE
#include <frontend/gui/helper/wobjectdefs.h>
然后就可以了:
#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
W_PROPERTY(type, name MEMBER m_##name)
#include <backend/config.i>
#undef THR_CONFIG_VALUE
我正在尝试一些事情(也许是愚蠢的)。
已使用一些宏在 C++ 域中创建 "amounts" 个函数;
#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
type name() { return m_##name; } \
void set##name(type data) { m_##name = data; }
#include <backend/config.i>
#undef THR_CONFIG_VALUE
基于以下 config.i 文件:
THR_CONFIG_VALUE("", "type", int, ThisType, 0)
THR_CONFIG_VALUE("", "auto", bool, AutoVar1, false)
THR_CONFIG_VALUE("", "auto", bool, AutoVar2, false)
效果很好,我得到了一些 getter setter 函数,也以相同的方式生成成员变量(备案)。
现在我开始混用 QT 的东西,尝试使用 MOC 生成 Q_PROPERTIES:
#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
Q_PROPERTY(type name READ name WRITE set##name NOTIFY indexChanged)
#include <backend/vessel/thruster/thruster_config.i>
#undef THR_CONFIG_VALUE
交通部不理会此类企图。这本来可以让我少输入 170 Q_PROPERTY 行,将来还会少输入 100 行。
问题1:为什么,预处理器和MOC序列? 问题2:有没有"QT way"?
谢谢,
Qt 有自己的方法来像您一样根据变量的名称生成 getter 和 setter。
我已经为 Qt 实现了一个宏,它可以满足您的需求,但它必须在 QObject
或 Q_GADGET
的上下文中使用。 (Q_PROPERTY
不能在它们之外使用。)
当我第一次写这个宏时,我不明白 Q_PROPERTY 不生成 setter、getter、通知方法,甚至不存储值。这些需要单独生成(在宏中很容易)。
Q_PROPERTY
的 NOTIFY
部分需要定义 signal
。由于信号在调用预处理器之前由 MOC 编码为 C++,因此使用 #define
将不起作用。 (我的代码中没有使用 NOTIFY
。)
不完整的例子:
#define THR_CONFIG_VALUE(type, name) \
Q_PROPERTY(type name READ name WRITE set##name) \
type m_##name; \
void set##name(const type &a_value) { m_##name = a_value; } \
...
现在我有了一个有效的实现。使用了 Verdigris 的贡献。
有点棘手,必须启用 c++14 并将此定义添加到 PRO 文件中:
DEFINES += __cpp_constexpr=201304 __cpp_variable_templates=201304
还因为我使用了名称空间;必须在命名空间内执行包含:
FRONTEND_BEGIN_NAMESPACE
#include <frontend/gui/helper/wobjectdefs.h>
然后就可以了:
#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
W_PROPERTY(type, name MEMBER m_##name)
#include <backend/config.i>
#undef THR_CONFIG_VALUE