Есть ли проблемы с созданием экземпляра подкласса QQuickItem, экземпляр которого я не собираюсь отображать или добавлять в дерево QML?

Как вы знаете, подкласс QQuickFramebufferObject::Renderer не должен напрямую обращаться к свойствам своего родительского элемента, а вместо этого должен копировать их себе в свой synchronize() метод. Таким образом, код имеет тенденцию выглядеть так (используя AUTO_PROPERTY макрос отсюда):

class MyItem : public QQuickFramebufferObject {
    AUTO_PROPERTY(int, foo)
    AUTO_PROPERTY(float, bar)
    // ...
};

class MyItemRenderer : public QQuickFramebufferObject::Renderer {
public:
    void synchronize(QQuickFrameBufferObject* qqfbo) {
        auto src = (MyItem*)qqfbo;
        foo = src->foo();
        bar = src->bar();
    }
private:
    int foo;
    float bar;
    // ...
};

Я хотел избежать дублирования объявления свойств между двумя классами, поэтому сейчас я реализую это альтернативное решение:

class MyItem : public QQuickFramebufferObject {
    AUTO_PROPERTY(int, foo)
    AUTO_PROPERTY(float, bar)
    // ...
};

class MyItemRenderer : public QQuickFramebufferObject::Renderer {
public:
    MyItemRenderer() {
        copiedData = new MyItem();
    }
    void synchronize(QQuickFrameBufferObject* qqfbo) {
        auto src = (MyItem*)qqfbo;
        copiedData.setFoo(src->foo());
        copiedData.setBar(src->bar());
    }
private:
    MyItem* copiedData;
};

Мне все еще нужно выписать и поддерживать код для копирования, как вы видите, но это лучше, чем другой способ.

Есть ли что-нибудь с этим? (создание экземпляра подкласса QQuickItem, экземпляр которого я не собираюсь отображать или добавлять в дерево QML).

Цитата из документов:

Это полезно для создания объектов QML из кода C++, независимо от того, отображать ли объект QML, который можно визуально визуализировать, или интегрировать невизуальные данные объекта QML в приложение C++.

Кажется, это подразумевает, что такое невизуальное использование является предполагаемым и поддерживаемым вариантом использования. Но я не уверен, что читаю это правильно.

1 ответ

Вы пытаетесь повторно использовать класс для двух целей, лучше разделить класс на две части и использовать агрегацию.

class MyItem ....
{
    friend class MyItemRenderer;

private:
    Data m_data; // contains the property variables
};

class MyItemRenderer ...
{
public:
    void synchronize(QQuickFrameBufferObject* qqfbo) {
        auto myItem = static_cast<MyItem*>(qqfbo);
        m_data = myItem->m_data;
    }
private:
    Data m_data;
};
Другие вопросы по тегам