Passing Q_GADGET as signal parameter from C ++ to QML

Cannot get property of C ++ object inside QML code. The object is passed as a parameter to the signal.

It is expected that in QML it is possible to highlight an text

object property Record

. And the value should be abc

. QML sees an object as QVariant(Record)

, and its property text

as undefined

.

Record

is a value type of type QPoint

, so it uses a declaration Q_GADGET

.

HPP:

#ifndef LISTENP_HPP_
#define LISTENP_HPP_

#include <QObject>

#include "Record.hpp"

class ListenP: public QObject
{
Q_OBJECT

public:
    ListenP();
    virtual ~ListenP();

    void emitGotRecord();

signals:
    void gotRecord(Record r);
};

#endif /* LISTENP_HPP_ */

      

caste:

#include "ListenP.hpp"

ListenP::ListenP() :
        QObject()
{
}

ListenP::~ListenP()
{
}

void ListenP::emitGotRecord()
{
    emit gotRecord(Record("abc"));
}

      

hpp to write:

#ifndef RECORD_HPP_
#define RECORD_HPP_

#include <QObject>
#include <QMetaType>

class Record
{
Q_GADGET

Q_PROPERTY(QString text READ text WRITE setText)

public:
    Record(const QString& text = "");
    ~Record();

    QString text() const
    {
        return m_text;
    }

    void setText(const QString& text)
    {
        m_text = text;
    }

private:
    QString m_text;
};

Q_DECLARE_METATYPE(Record)

#endif /* RECORD_HPP_ */

      

cpp to write:

#include "Record.hpp"

Record::Record(const QString& text) :
        m_text(text)
{
}

Record::~Record()
{
}

namespace
{
const int RecordMetaTypeId = qMetaTypeId<Record>();
}

      

The QML part:

Connections {
    target: listenPModel
    onGotRecord: {
        console.log(r)
        console.log(r.text)
    }
}

      

main part:

QGuiApplication app(argc, argv);

auto listenP = std::make_shared<ListenP>();
QQuickView view;
view.rootContext()->setContextProperty("listenPModel", &*listenP);
view.setSource(QStringLiteral("src/qml/main.qml"));
view.show();

QtConcurrent::run([=]
{
    QThread::sleep(3);
    listenP->emitGotRecord();
});

return app.exec();

      

The log shows:

qml: QVariant(Record)
qml: undefined

      

+3


source to share


1 answer


the release notes for Qt 5.5 talk about new features:

  • Qt Core
    • Now you can have Q_PROPERTY and Q_INVOKABLE in Q_GADGET and there is a way to query the QMetaObject of such a gadget using the QMetaType system

Indeed, compiling and running your example with Qt 5.4 gives the same result as yours, whereas with Qt 5.5 I got it Record

correctly recognized, that is, I got the result:



qml: Record(abc)
qml: abc

      

Also, as stated in the Q_DECLARE_METATYPE

documentation , the type passed to the macro - Record

in this case, must provide (1) a public default constructor, (2) a public copy constructor, and (3) a public destructor. Since it Record

is a very simple class, there is no need to provide a copy constructor, as the default is sufficient.

+7


source







All Articles