如何将具有指向 QML 的指针成员的非 QObject 类公开?

Posted

技术标签:

【中文标题】如何将具有指向 QML 的指针成员的非 QObject 类公开?【英文标题】:How do I expose a non-QObject class with pointer members to QML? 【发布时间】:2014-02-07 10:10:20 【问题描述】:

我了解如何通过创建一个以我的类为成员的新 QObject 类来公开简单的数据成员。例如:

class MyClass 
public:
    int anInt;
;

还有包装器

class MyClassQWrapped : public QObject 
    Q_OBJECT
    Q_PROPERTY(int anInt READ anInt write setAnInt NOTIFY anIntChanged)
public:
    int anInt()return myClass.anInt;
    void setAnInt(int value)
        if(myClass.anInt==value)return;
        myClass.anInt = value;
        emit anIntChanged;
    
signals:
    anIntChanged();
private:
    MyClass myClass;
;

但是如何用指针数据成员包装对象呢?比如说我有一个链表类,想把它暴露给 qml:

Class LinkedList 
public:
    int anInt;
    LinkedList *next;
;

我不能使用与上面相同的方法,因为这样包装器的属性将是指向LinkedList,而不是LinkedListQWrapped 的指针。如果列表由非 Qt 代码更改,我无法知道哪个(如果有)LinkedListQWrapped 对象对应于给定的LinkedList*

现在,我可以更改 c++ 模型,但我不能让它依赖于 Qt。 我可以想到一种解决方案,将void* 用户数据成员添加到 c++ 类,然后在创建包装器后将其设置为指向相应的包装对象。

我在box2d看到过这种事情。

这是解决问题的推荐方法吗?在库代码中提供void* 用户数据成员以使它们与各种框架(如Qt)配合使用是否很常见?或者这个问题有其他解决方案吗?

【问题讨论】:

【参考方案1】:

我不相信您可以将非QObject 派生类公开给 QML,因为我知道的唯一方法是通过 QQmlContext

查看 QML box2d 扩展,似乎所有面向 QML 的类都以某种方式派生自 QObject,请看这里 box2d repo。

也就是说他们确实使用包装函数在 QML box2d 类型和常规非QObject 类型之间进行转换。即

/**
 * Convenience function to get the Box2DJoint wrapping a b2Joint.
 */
inline Box2DJoint *toBox2DJoint(b2Joint *joint)

     return static_cast<Box2DJoint*>(joint->GetUserData());

【讨论】:

啊,太好了!不知道 box2d 有 QML 扩展。这可能也是我将要这样做的方式。这将是很好的参考。【参考方案2】:

我刚刚问了一个类似的问题:How to expose C++ structs for computations to Qml

事实证明,没有直接的方法。但是,如果您查看对该问题的回答,您会看到我们是如何解决它的。 我们简单地构建了一个包装器,并让所有相关的对象成为它的成员。这些成员有自己的属性,它们只是通过包装器转发。然后您只需管理 getter 和 setter 即可将值传递给包装器的成员。对于从成员发射对象,您可以引入 EmitterHelperObjects(只是继承 QObject 并且其唯一任务是抛出信号的小对象)。 在某些情况下,您可能需要将包装器的指针注册为 MetaType。我还没弄清楚,什么时候需要,什么时候不需要。

所以总结一下方法: 您不直接使用指针,而是通过将 Wrapper 用作“属性转发器”来仅访问其成员的属性。它有点打字,但效果很好。 就个人而言,我不喜欢 Qt / Qml 的这一面,这个 Object one Identity 的东西在某些情况下变得很丑陋。

我知道你很久以前就问过了,但也许它对其他人有帮助。

【讨论】:

已经有一段时间了,但我很确定这也是我解决它的方法。正如你所说,这是很多乏味的写作,但效果很好。

以上是关于如何将具有指向 QML 的指针成员的非 QObject 类公开?的主要内容,如果未能解决你的问题,请参考以下文章

指向任何类类型的非静态成员函数的 C++ 函数指针

指向具有私有构造函数的类的类成员的指针

C ++ - 指向具有相同地址但不同值的不同对象的另一个非静态成员的非静态void *成员

this指针的作用

指向虚拟成员函数的指针是不是具有可比性?

关于虚函数,类的内存分布以及类的成员函数调用原理