0
votes

As you know, a QQuickFramebufferObject::Renderer subclass shouldn't access its parent item's properties directly, and instead should copy them to itself in its synchronize() method. So the code tends to look like this (using the AUTO_PROPERTY macro from here):

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;
    // ...
};

I wanted to avoid duplicating the declaration of properties between the two classes, so right now I'm implementing this alternative solution:

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;
};

I still need to write out and maintain the copying code as you see, but it's better than the other way.

Are there gotchas with doing that? (creating an instance of a QQuickItem subclass which instance I don't intend to render or add to a QML tree).

Quote from the docs:

This is useful for creating QML objects from C++ code, whether to display a QML object that can be visually rendered, or to integrate non-visual QML object data into a C++ application.

This seems to imply that such nonvisual usage is an intended and supported use case. But I'm not sure I'm reading it right.

1
Use QtObject for non-visual stuff, less overhead. The limitation is it can only have properties, not children, which is kinda silly, considering that it is essentially a QObject which can have children, the functionality is just not exposed to QML.dtech
@ddriver: But the item I'm syncing from is a visual item, I can't make it a nonvisual item because then it wouldn't be displayed.Stefan Monov

1 Answers

0
votes

You are trying to re-use a class for two purposes, better split the class into two and use aggregation.

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;
};