Я пытаюсь испустить сигнал с пользовательским типом. Тип объявляется Q_DECLARE_METATYPE и зарегистрирован в 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
#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, хотя, поскольку он использует парсер-кланг, который по сути является «полномасштабным синтаксическим анализатором C++». ;-) – lpapp