我试图用自定义类型发射信号。类型声明为Q_DECLARE_METATYPE并注册为qRegisterMetaType。用自定义类型发射信号不起作用
当我发出的信号,然后我得到下一个错误输出流:仅当排队连接被使用(当对象是在不同的线程或用来明确Qt::QueuedConnection
)
Type "MyType" has id: 1024 ; register status: true
QObject::connect: Cannot queue arguments of type 'MyType' (Make sure 'MyType' is registered using qRegisterMetaType().)
错误是可再现和MyType
在名称空间内声明。
样品的编号: MyType.h
#define SHOW_BUG
#ifdef SHOW_BUG
namespace NS
{
struct MyType
{
int val;
};
}
Q_DECLARE_METATYPE(NS::MyType);
#else
struct MyType
{
int val;
};
Q_DECLARE_METATYPE(MyType);
#endif
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;
}
}
Main.cpp的
#include "MyClass.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
NS::MyClass c1;
NS::MyClass c2;
QThread thread;
thread.start();
c2.moveToThread(&thread);
QObject::connect(&c1, &NS::MyClass::sendMyType, &c2, &NS::MyClass::getMyType);
QTimer::singleShot(0, &c1, SLOT(invokeBug()));
return a.exec();
}
你会注意到它,如果你已经看过我的代码:)记住:MOC是愚蠢的。它不知道MyType是否在命名空间中,因为它需要一个完整的C++解析器。 –
我将为ReSharper创建一个规则:) –
这可能可以用moc-ng修复,不过因为这是使用clang解析器,它本质上是一个“完整的C++解析器”。 ;-) – lpapp