我了解如何通过创建一个将我的类作为成员的新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)一起使用是否常见?或者是否有另一种解决这个问题的方法?
答案 0 :(得分: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());
}
答案 1 :(得分:1)
我刚刚问过类似的问题:How to expose C++ structs for computations to Qml
事实证明,没有直接的方法。但如果你看看这个问题的答案,你会看到我们如何解决它。 我们只是构建了一个包装器,并使所有相关对象成为它的成员。这些成员有自己的属性,它们只是通过包装器转发。然后你只需管理getter和setter就可以将值传递给包装器的成员。要从成员中发出对象,可以引入EmitterHelperObjects(只是小对象,它继承QObject,其唯一任务是抛出信号)。 在某些情况下,您可能需要将包装器的指针注册为MetaType。我没想出来,因为我什么时候需要这样做,什么时候不这样做。总结一下这个方法: 您不直接使用指针,而是通过将Wrapper用作“Property forwarder”来仅访问其成员的属性。它有点打字,但效果很好。 就个人而言,我不喜欢Qt / Qml的这一面,这个对象一个身份的东西在某些情况下变得难看。
我知道你很久以前就曾问过,但也许这对别人有帮助。