私はカスタムタイプで信号を放射しようとしています。型はQ_DECLARE_METATYPEで宣言され、qRegisterMetaTypeで登録されています。カスタムタイプの信号を送信できません
Iが信号を発するとき、Iは、出力ストリームに次のエラーを得る:(オブジェクトが異なるスレッドであるか、または明示的な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がネームスペースにあることを知ることができません。なぜなら、MyTypeが完全なC++パーサを必要とするからです。 –
私はReSharperのルールを作成します:) –
これはおそらくmoc-ngで修正できますが、これは本質的に「本格的なC++パーサー」であるclangパーサーを使用しているためです。 ;-) – lpapp