简体   繁体   English

QML可以看到我的Q_GADGET而不是Q_OBJECT

[英]QML can see my Q_GADGET but not Q_OBJECT

Why can my Q_GADGET be read perfectly in QML (JS) but not my Q_OBJECT ? 为什么我的Q_GADGET可以在QML(JS)中完美读取,但不能在我的Q_OBJECT读取?

Running Qt 5.8.0 on Ubuntu 14.04. 在Ubuntu 14.04上运行Qt 5.8.0。

I'm attempting to return a list ( QVariantMap ) of objects to QML. 我正在尝试将对象列表( QVariantMap )返回给QML。 I'm keeping it simple right now, no pointers, etc.. just copies of the 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 are a bunch of QString and QVector3D members on Blob . Blob上有一堆QStringQVector3D成员。

In main.cpp, I also register the type: 在main.cpp中,我还注册了类型:

qmlRegisterType<Blob>("matt", 1, 0, "Blob");

Then my JS code is able to read all the properties (for loop iterating over them) on the object without issue. 然后我的JS代码能够在没有问题的情况下读取对象上的所有属性(用于循环遍历它们)。

But if I use a Q_OBJECT 但是如果我使用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 the JS receives an object where all the properies are the keys from the QVariantMap , but whose values are empty objects. 然后JS接收一个对象,其中所有属性都是来自QVariantMap的键,但其值是空对​​象。

Note, before sending it to the JS, I convert it to a QVariant and back again just to confirm that that works, eg 注意,在将它发送给JS之前,我将其转换为QVariant并再次返回以确认其有效,例如

Blob b;
qDebug() << "Created: " << b;
QVariant var = QVariant::fromValue(b);
qDebug() << "   Converted back = " << var.value<Blob>().toQString();

I'd prefer to use a Q_OBJECT such that I have slots/signals. 我更喜欢使用Q_OBJECT ,以便我有插槽/信号。

The reason I was seeing a difference between Q_OBJECT and Q_GADGET was that I was making copies of my object, which is allowed on a Q_GADGET (a value ) object, but not on a Q_OBJECT (an identity object.) See identities instead of values . 我之间看到Q_OBJECTQ_GADGET之间差异的原因是我正在制作我的对象的副本,这在Q_GADGET )对象上是允许的,但不在Q_OBJECT标识对象)上。请参阅标识而不是值

The solution is to always work on Q_OBJECT s with pointers. 解决方案是始终使用指针处理Q_OBJECT This maintains their identity , and avoid copies. 这保持了他们的身份 ,并避免复制。

Also, my original intent was to use a smart pointer, but the reasons why that is a bad approach are explained in this answer . 此外,我最初的意图是使用智能指针,但在这个答案中解释了为什么这是一个糟糕的方法的原因。

The comment by @dtech also explained that Q_DECLARE_METATYPE is redundant on a Q_OBJECT . @dtech的评论还解释了Q_DECLARE_METATYPEQ_OBJECT上是多余的。

Thus, my final declaration is: 因此,我的最后声明是:

ie

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 a QVariantMap , and they can be read on the QML/JS side. 有了这个,我可以轻松地将一个原始指针放在QVariantMap这些对象上,并且可以在QML / JS端读取它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM