Ausstrahlen von Signalen mit benutzerdefinierten Typen funktioniert nicht
Ich versuche zu emittieren signal mit benutzerdefinierten Typ. Typ wird deklariert mit Q_DECLARE_METATYPE und registriert mit qRegisterMetaType.
Wenn ich das signal ausstrahlen, dann kommen die nächsten Fehler an den Ausgabe-stream:
Type "MyType" has id: 1024 ; register status: true
QObject::connect: Cannot queue arguments of type 'MyType' (Make sure 'MyType' is registered using qRegisterMetaType().)
Fehler ist reproduzierbar nur, wenn in der Warteschlange-Verbindung verwendet wird (wenn Objekte in verschiedenen threads oder explizite Qt::QueuedConnection
verwendet wird) und MyType
deklariert ist in einem namespace.
Beispielcode:
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();
}
InformationsquelleAutor Dmitry Sazonov | 2014-01-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den nachstehenden code veranschaulicht den Fehler und die Lösung. Es funktioniert sowohl auf Qt 4 und Qt 5.
InformationsquelleAutor Kuba Ober
Bekam eine Antwort von Qt-team. Sehr seltsam, usecases, aber: Signale muss deklariert werden, mit vollständiger namespace. Dies ist eine Einschränkung von moc, die von Ihr ausgeht, nicht mit einer vollwertigen C++ - parser.
So, das wird funktionieren:
Aber dies nicht:
Ich erstelle eine Regel für ReSharper 🙂
Dies konnte wohl behoben werden mit der moc-ng aber da das mit dem klappern-parser, der ist von Natur aus ein "full-blown C++ parser". 😉
moc-ng ist ziemlich viel das Lösung. Ich wünschte, es wurde ein Teil von Qt, llvm codebase ist einigermaßen tragbar, nachdem alle.
Ich habe diese Frage auf der mailing-Liste damals, aber die Menschen hatten nicht so enthuasiastic darüber. Es war mehr wie nur ein "Spaß-Projekt" für Olivier für die Zeit. Ich denke, das Hauptanliegen war, die Windows-Stabilität.
InformationsquelleAutor Dmitry Sazonov