2017-04-13 59 views
3

为什么我的Q_GADGET可以在QML(JS)中完美读取,但不能在我的Q_OBJECT中读取?QML可以看到我的Q_GADGET,但不是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) 

还有的QStringQVector3D成员Blob一堆。

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

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

然后我的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) 

然后JS接收的对象,所有的性的判定都是从QVariantMap钥匙,但这些值是空的对象。

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

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

我宁愿使用Q_OBJECT这样我有插槽/信号。

回答

0

我看到Q_OBJECTQ_GADGET之间的差异的原因是,我是让我的对象,这是允许一个Q_GADGET(一)对象的副本,但不能在Q_OBJECT(一身份对象)见identities instead of values

解决方法是始终在指针上工作Q_OBJECT。这保持其身份,并避免副本。

此外,我最初的目的是使用智能指针,但是这是一个不好的方法的原因在this answer中解释。

@dtech的评论也解释说Q_DECLARE_METATYPEQ_OBJECT上是多余的。

因此,我最后的声明:

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); 
}; 

有了这个,我可以很容易地把原始指针到这些对象在QVariantMap,他们可以在QML阅读/ JS方。

+0

你*总是*与基于指针派生的'QObject'一起工作。声明一个派生为元类型的QObject不起作用,因为它需要一个可复制的对象,此外,所有派生的'QObject'都得到了MOC处理,所以它们默认为meta类型。 – dtech

+0

@dtech,我想我现在已经使用您评论的建议(以及似乎已被删除的问题评论)改进了此答案。 – Matt

相关问题