Qt 使用自定义类型发出信号不起作用

Qt 使用自定义类型发出信号不起作用,qt,Qt,我试图用自定义类型发出信号。类型用Q\u DECLARE\u元类型声明,并用qRegisterMetaType注册 当我发出信号时,我得到输出流的下一个错误: Type "MyType" has id: 1024 ; register status: true QObject::connect: Cannot queue arguments of type 'MyType' (Make sure 'MyType' is registered using qRegisterMetaType()

我试图用自定义类型发出信号。类型用Q\u DECLARE\u元类型声明,并用qRegisterMetaType注册

当我发出信号时,我得到输出流的下一个错误:

Type "MyType" has id:  1024 ; register status:  true
QObject::connect: Cannot queue arguments of type 'MyType' (Make sure 'MyType' is registered using qRegisterMetaType().)
只有在使用排队连接(当对象位于不同线程中或使用显式
Qt::QueuedConnection
时)并且在命名空间内声明了
MyType
时,才能复制错误

示例代码: MyType.h

MyClass.h:

#include "MyType.h"

namespace NS
{

    class MyClass
        : public QObject
    {
        Q_OBJECT
    public:
        MyClass( QObject *parent = NULL );
        ~MyClass();

    signals:
        void sendMyType( const MyType& tt );

    public slots:
        void invokeBug();
        void getMyType( const MyType& tt );
    };

}
MyClass.cpp

#include <QDebug>

namespace NS
{

    MyClass::MyClass(QObject *parent)
        : QObject(parent)
    {
        qRegisterMetaType< MyType >();
    }

    MyClass::~MyClass()
    {
    }

    void MyClass::invokeBug()
    {
        const int id = qMetaTypeId< MyType >();
        const bool test = QMetaType::isRegistered( id );
        qDebug() << "Type \"MyType\" has id: " << id << "; register status: " << test;

        MyType tt;
        tt.val = 42;
        emit sendMyType( tt );
    }

    void MyClass::getMyType( MyType const& tt )
    {
        qDebug() << "Slot fired: " << tt.val;
    }

}

下面的代码说明了故障和解决方案。它在Qt4和Qt5上都起作用

Now we fail 
QObject::connect: No such signal NS::Object::badSignal(NS::MyType) in ../metatype-21119397/main.cpp:32
Now we succeed 
Successful slot call 1 
#包括
#包括
名称空间NS{
结构MyType
{
int-val;
MyType(){}
MyType(intv):val(v){}
};
类对象:公共QObject{
Q_对象
公众:
Q_SIGNAL void goodSignal(const NS::MyType&);
Q_信号无效不良信号(常数MyType&);
Q_插槽无效插槽(常量NS::MyType&x){

QDebug Ge()从QT团队得到了一个答案。非常奇怪的用法,但是:信号必须用<强>完整的命名空间< /强>声明。这是MOC的限制,来自于它没有完整的C++解析器。 因此,这将起作用:

  class MyObject {
    ...
    // correct
    Q_SIGNAL void sendMyType( const NS::MyType& tt );
  };
但这不会:

namespace NS {
  ...
  class MyObject {
    ...
    // wrong
    Q_SIGNAL void sendMyType( const MyType& tt );
  };
}

如果你看过我的代码,你会注意到的:记住:MOC是愚蠢的。它不知道MyType在命名空间中,因为它需要一个完整的C++解析器。我将为ReSARPER创建一个规则:这可能是用MOC NG固定的,因为它使用的是CLAN解析器,它本质上是一个“完全的C++分析器”。.;-)@LaszloPapp:moc ng几乎就是解决方案。我希望它成为Qt的一部分,llvm代码库毕竟是可移植的。@KubaOber:当时我在邮件列表上问过这个问题,但人们对它并没有那么热情。它更像是一个“有趣的项目”对于奥利维尔来说,我认为主要的问题是窗户的稳定性。
  class MyObject {
    ...
    // correct
    Q_SIGNAL void sendMyType( const NS::MyType& tt );
  };
namespace NS {
  ...
  class MyObject {
    ...
    // wrong
    Q_SIGNAL void sendMyType( const MyType& tt );
  };
}