Как мне открыть класс не-QObject с указателями на QML?

0

Я понимаю, как выставлять простые члены данных, создавая новый класс 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 object соответствует данному LinkedList*.

Теперь мне позволено изменить модель c++, но я не могу позволить ей зависеть от Qt. Я могу думать о одном решении, в котором я добавляю элемент данных пользователя void* класс c++, а затем устанавливаю его, чтобы указать на соответствующий обернутый объект, как только я создал оболочку.

Я видел подобное в box2d.

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

Теги:
qt
wrapper
qml
qobject

2 ответа

1
Лучший ответ

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

Глядя на QML box2d extentsion, кажется, что все классы QML, связанные с классами, производятся из QObject так или иначе, посмотрите здесь box2d repo.

Тем не менее, они используют функции обертки для преобразования между типами QML box2d и обычными типами QObject non-. т.е.

/**
 * Convenience function to get the Box2DJoint wrapping a b2Joint.
 */
inline Box2DJoint *toBox2DJoint(b2Joint *joint)
{
     return static_cast<Box2DJoint*>(joint->GetUserData());
}
  • 0
    Ах, отлично! Не знал, что есть расширение QML для box2d. Наверное, так я и сделаю. Это будет приятно использовать в качестве ссылки.
1

Я просто задал аналогичные вопросы: как разоблачить C++ структуры для вычислений в Qml

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

Итак, подытожим подход: вы не используете указатель напрямую, но получаете доступ только к свойствам своих членов, используя Wrapper как "Forwarder". Его немного печатается, но работает довольно хорошо. Лично мне не нравится эта сторона Qt/Qml, эта одна вещь One Identity в некоторых ситуациях оказывается уродливой.

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

  • 0
    Это было какое-то время, но я уверен, что именно так я и решил. Как вы говорите, это очень утомительное написание, но оно работает довольно хорошо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню