QML can see my Q_GADGET but not Q_OBJECT
Why Q_GADGET
does mine read fine in QML (JS) but not mine Q_OBJECT
?
Running Qt 5.8.0 on Ubuntu 14.04.
I am trying to return a list ( QVariantMap
) of objects in QML. I keep it simple for now, no pointers, etc. Just copies of objects.
struct Blob
{
Q_GADGET
Q_PROPERTY(QString uuid MEMBER uuid_ CONSTANT)
Q_PROPERTY(QVector3D centroid MEMBER centroid_)
// ...
Blob() {};
~Blob() = default;
Blob(const Blob& blob);
};
Q_DECLARE_METATYPE(Blob)
There Blob
is a group of QString
and QVector3D
.
I also register the type in main.cpp:
qmlRegisterType<Blob>("matt", 1, 0, "Blob");
Then my JS code can read all the properties (to loop over them) without issue.
But if I use Q_OBJECT
struct Blob : public QObject
{
Q_OBJECT
Q_PROPERTY(QString uuid MEMBER uuid_ CONSTANT)
Q_PROPERTY(QVector3D centroid MEMBER centroid_)
// ...
explicit Blob(QObject parent = nullptr) : QObjecT(parent) {};
~Blob() = default;
Blob(const Blob& blob);
};
Q_DECLARE_METATYPE(Blob)
Then JS gets an object in which all properties are keys from QVariantMap
, but whose values ββare empty objects.
Please note, before sending it to JS, I convert it to QVariant and back to confirm it works, for example
Blob b;
qDebug() << "Created: " << b;
QVariant var = QVariant::fromValue(b);
qDebug() << " Converted back = " << var.value<Blob>().toQString();
I would rather use Q_OBJECT
to have slots / signals.
source to share
The reason I observed the difference between Q_OBJECT
and Q_GADGET
was because I was making copies of my object, which is resolved on object Q_GADGET
(value) but not on Q_OBJECT
(identity object.) See identifiers instead of values .
The solution should always work Q_OBJECT
with pointers. This confirms their identity and avoids copying.
Also, my initial intention was to use a smart pointer, but the reasons this is a bad approach are explained in this answer .
@Dtech's comment also explained what is Q_DECLARE_METATYPE
redundant on Q_OBJECT
.
Thus, my final declaration is:
i.e.
class Blob : public QObject
{
Q_OBJECT
Q_PROPERTY(QString uuid MEMBER uuid_ CONSTANT)
Q_PROPERTY(QVector3D centroid MEMBER centroid_)
// ...
explicit Blob(QObject parent = nullptr) : QObjecT(parent) {};
~Blob() = default;
Blob(const Blob& blob);
};
With this, I can easily put a raw pointer to these objects in QVariantMap
and they can be read on the QML / JS side.
source to share