QML 可以看到我的 Q_GADGET 但看不到 Q_OBJECT

Mat*_*att 5 c++ qt qml

为什么 my 可以Q_GADGET在 QML (JS) 中完美读取,但 my 却不能Q_OBJECT

在 Ubuntu 14.04 上运行 Qt 5.8.0。

QVariantMap我正在尝试将对象列表 ( ) 返回到 QML。我现在保持简单,没有指针等......只是对象的副本。

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)
Run Code Online (Sandbox Code Playgroud)

上有一堆QStringQVector3D成员Blob

在 main.cpp 中,我还注册了类型:

qmlRegisterType<Blob>("matt", 1, 0, "Blob");
Run Code Online (Sandbox Code Playgroud)

然后我的 JS 代码就能够毫无问题地读取对象上的所有属性(for 循环迭代它们)。

但如果我使用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)
Run Code Online (Sandbox Code Playgroud)

然后 JS 接收一个对象,其中所有属性都是来自 的键QVariantMap,但其值是空对​​象。

请注意,在将其发送到 JS 之前,我将其转换为 QVariant 并再次返回以确认其有效,例如

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

我更喜欢使用这样Q_OBJECT的,我有插槽/信号。

Mat*_*att 0

Q_OBJECT我看到和之间存在差异的原因Q_GADGET是我正在复制我的对象,这在Q_GADGET)对象上是允许的,但在Q_OBJECT身份对象)上不允许。请参见identities 而不是 value

解决方案是始终Q_OBJECT使用指针来处理 s。这样可以保持其身份,并避免复制。

另外,我的初衷是使用智能指针,但这个答案解释了为什么这是一个不好的方法的原因。

@dtech 的评论还解释说这Q_DECLARE_METATYPE对于Q_OBJECT.

因此,我的最终声明是:

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);
};
Run Code Online (Sandbox Code Playgroud)

这样,我可以轻松地将指向这些对象的原始指针放入 a 中QVariantMap,并且可以在 QML/JS 端读取它们。