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

Schreibe einen Kommentar