c++ - 是否可以将宏函数作为 QMetaMethod 标记?

标签 c++ qt signals-slots qmetaobject

Qt allows you to have arbitrary tags在插槽/Q_INVOKABLE 方法上使用此语法:

// In the class MainWindow declaration
#ifndef Q_MOC_RUN
// define the tag text as empty, so the compiler doesn't see it
#  define MY_CUSTOM_TAG
#endif
...
private slots:
    MY_CUSTOM_TAG void testFunc();

我想制作一个宏函数标签,如下所示:

#ifndef Q_MOC_RUN
#  define MY_CUSTOM_TAG(...)
#endif
...
private slots:
    MY_CUSTOM_TAG(someData) void testFunc();

我希望它最终会在 tag() 中作为一个字符串结束,就像我的代码将解析的 MY_CUSTOM_TAG(someData) - 然而,MOC 给我这个错误:

error: Parse error at ")"

有没有办法让它工作?还是 MOC 只支持标签的简单宏?

最佳答案

tl;dr 是你可以做到这一点,但 moc 对它接受的内容很挑剔。

根据您链接的文档,Qt 5.0+ 中的 moc 将扩展预处理器宏。您可以通过以下示例确认这一点:

#ifndef Q_MOC_RUN
    #define MY_TAG(...)
#else
    #define MY_TAG(x) x
#endif

class Test : public QObject
{
    Q_OBJECT
public:
    explicit Test(QObject *parent = 0);

public slots:
    MY_TAG(qt) void test();
};

如果您检查 moc 生成的 moc_test.cpp,您应该在生成的字符串表中找到“qt”。

static const qt_meta_stringdata_Test_t qt_meta_stringdata_Test = {
    {
QT_MOC_LITERAL(0, 0, 4), // "Test"
QT_MOC_LITERAL(1, 5, 4), // "test"
QT_MOC_LITERAL(2, 10, 2) // "qt"

    },
    "Test\0test\0qt"
};

您还可以按照链接文档中的描述使用 QMetaMethod::tag() 来测试是否成功。

我测试了其他几个宏,发现 moc 在接受什么方面是严格的。例如,具有多个参数的宏以及包含括号或破折号的宏主体会导致错误。 moc 使用自己的预处理器实现,与 GNU C 预处理器相比,它可能受到限制。

关于c++ - 是否可以将宏函数作为 QMetaMethod 标记?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51367465/

相关文章:

c++ - 未定义模板的隐式实例化 'class'

qt - 使用 QObject 代替容器

python - PyQt4 QComboBox 信号和槽

c++ - QT 是在单独的线程中启动的slot

c++ - Android NDK - 检查接口(interface)

c++ - wcstombs_s(),转换后的字符串长度

c++ - consteval 包装器与 source_location

树莓派 : Cannot find GLESv2 的 qt 交叉编译

c++ - 从 cvMat 到 QImage

c++ - QObject::connect:在使用 Lambda 语法的升级小部件中找不到信号