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
source to share
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.
source to share