使用标头和源文件时在何处放置Q_DECLARE_METATYPE语句?

时间:2017-11-22 17:42:53

标签: c++ qt

我在struct页面内使用自定义QWizard。我们这样说struct(或class):

// foo.h

namespace nm{

struct Foo
{
    Foo();
    void bar();
};

}

我希望能够registerField Q_PROPERTY类型为nm::Foo,例如:

// within some QWizardPage class
Q_PROPERTY(nm::Foo foo READ getFoo WRITE setFoo)

我知道为了让我使用它,我必须将它声明为Qt元型:

Q_DECLARE_METATYPE(nm::Foo)

但我无法弄清楚上述陈述的正确位置。我试图将它放在Foo.cpp的末尾,但是出现了编译错误:

  

path / QtCore / qglobal.h:738:错误:静态断言失败:未注册类型,请使用Q_DECLARE_METATYPE宏将其告知Qt的元对象系统。 #define Q_STATIC_ASSERT_X(条件,消息)static_assert(bool(条件),消息)

如果我将它放在头文件的末尾,同时还有一个源文件,我得到:

  

/usr/lib/gcc/x86_64-linux-gnu/5/include/stddef.h:149:错误:'typedef'之前的预期构造函数,析构函数或类型转换    typedef PTRDIFF_TYPE ptrdiff_t;

如果我将所有定义移动到Foo.h并将其用作仅限标题的文件,那么如果我将语句放在文件的末尾(在命名空间之外),它就可以工作。但是,我的类定义有点长,我希望我的类定义放在源文件中。

有什么方法可以在为我的类而不是仅包含头文件的头文件和源文件时使用Q_DECLARE_METATYPE吗?

编辑(解决方案):我必须完全定义我的课程,即提供公共默认ctor,copy ctor和dtor。最终代码如下:

// somewhere in Foo.h
#include <QMetaType>

namespace nm{
struct Foo
{
    Foo();
    Foo(const Foo& other);
    ~Foo();

    void bar();
};
} 

Q_DECLARE_METATYPE(nm::Foo)

1 个答案:

答案 0 :(得分:1)

来自the documentation(重点是我的):

  

只要提供公共默认构造函数,公共复制构造函数和公共析构函数,此宏就会使QMetaType 知道 Type 类型。需要在QVariant中将类型类型用作自定义类型。

     

此宏要求 Type 在使用它时是完全定义的类型。

这就是为什么只有标题解决方案有效的原因,而AFAIK除了在将其声明为元类型之前提供完整的类型定义之外别无他法。