Neel Basu
Neel Basu

Reputation: 12904

Does QMetaType work with templated Type

I've typedef ProxyTray<QImage, ImageCaptureService> TrayType; in my class (Which is QObject but ProxyTray is not QObject). I am using that type in Signal, Slots as argument type.

does qRegisterMetaType accept such type ? How would I model the string type name for parameterized types ?

Upvotes: 1

Views: 1741

Answers (2)

You can declare templated metatypes with :

Q_DECLARE_METATYPE_TEMPLATE_1ARG(TemplatedClass)
Q_DECLARE_METATYPE_TEMPLATE_2ARG(TemplatedClass)

e.g.

template<class T>
class Foo { 

};
Q_DECLARE_METATYPE_TEMPLATE_1ARG(Foo)

allows to pass Foo<int>, Foo<QString>, etc... to signals and slots.

template<class T, class U>
class Foo { 

};
Q_DECLARE_METATYPE_TEMPLATE_2ARG(Foo)

allows to pass Foo<int, double>, Foo<bool, bool>, etc...

There are two caveats however :

  • This is not part of the official Qt API and may disappear at some point.
  • The template types have to be themselves registered using Q_DECLARE_METATYPE: Foo<Bar> requires Bar to be registered as a metatype too (as of Qt 5.6)

Upvotes: 3

Mehrwolf
Mehrwolf

Reputation: 8535

Yes, templated types can be used in Qt signal/slots. As you already have a typedef for your type, you can simply use Q_DECLARE_METATYPE as in the following example:

#include <QtCore>

template <typename T>
struct Proxy
{
    T data;
};
typedef Proxy<QImage> TrayType;
Q_DECLARE_METATYPE(TrayType)

class Donor : public QObject
{
    Q_OBJECT
public:
    Donor()
    {
        m_proxy.data = QImage(10, 20, QImage::Format_Mono);
    }

    void test()
    {
        emit produce(m_proxy);
    }

signals:
    void produce(const TrayType& proxy);

private:
    TrayType m_proxy;
};

class Acceptor : public QObject
{
    Q_OBJECT
public slots:
    void consume(const TrayType& proxy)
    {
        qDebug() << "The mage size is" << proxy.data.size();
    }
};

int main(int argc, char* argv[])
{
    QCoreApplication app(argc, argv);

    QScopedPointer<Donor> donor(new Donor);
    QScopedPointer<Acceptor> acceptor(new Acceptor);
    QObject::connect(donor.data(), SIGNAL(produce(TrayType)),
                     acceptor.data(), SLOT(consume(TrayType)));

    // Test the signal-slot connection.
    donor->test();
    return app.exec();
}

Upvotes: 1

Related Questions