2014-02-07 2 views
0

Я понимаю, как выставлять простые члены данных, создавая новый класс QObject, который имеет мой класс в качестве члена. Например:Как открыть класс QQbject с элементами указателя в QML?

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. Я могу придумать одно решение, в котором я добавляю пользовательский элемент данных к классу C++, а затем задаю его, чтобы он указывал на соответствующий обернутый объект, как только я создал оболочку.

Я видел такого рода вещи, сделанные в box2d.

Это рекомендуемый способ решить эту проблему? Общепринято ли предоставлять пользователям void* пользовательские данные в библиотечном коде, чтобы заставить их играть хорошо с различными инфраструктурами, такими как Qt? Или есть другое решение этой проблемы?

ответ

1

Я не верю, что вы можете выставлять классы, отличные от QObject, для QML, так как я знаю только через QQmlContext.

Глядя на QML box2d extentsion, кажется, что все классы 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()); 
} 
+0

А, отлично! Не знаю, было ли расширение QML для box2d. Вероятно, я тоже это сделаю. Это будет полезно использовать в качестве ссылки. – bobbaluba

1

Я просто задал подобные вопросы: How to expose C++ structs for computations to Qml

Оказалось, что нет прямой путь. Но если вы посмотрите на ответ на этот вопрос, вы увидите, как мы его решили. Мы просто построили обертку и сделали все ее соответствующие элементы. У этих членов есть свои собственные свойства, которые они просто пересылают через обертку. Тогда вам просто нужно управлять получателем и сеттером для передачи значений членам обертки. Для испускания объектов из членов вы можете ввести EmitterHelperObjects (только небольшие объекты, которые наследуют QObject и чья задача состоит в том, чтобы бросать сигналы). В некоторых случаях вам может потребоваться зарегистрировать указатель обертки как MetaType. Я не понял этого, потому что, когда мне нужно это делать, а когда нет.

Итак, чтобы подытожить подход вверх: Вы не используете указатель напрямую, но получаете доступ только к свойствам своего члена, используя Wrapper как «Property forwarder». Его немного печатается, но работает довольно хорошо. Лично мне не нравится эта сторона Qt/Qml, эта одна. Объект One. Идентичность в некоторых ситуациях оказывается уродливой.

Я знаю, что вы давно задали вопрос, но, возможно, это помогает другим.

+0

Прошло некоторое время, но я уверен, что так я и решил. Как вы говорите, это много утомительного письма, но оно работает очень хорошо. – bobbaluba