0

如您所知,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 树的实例)

文档中引用:

这对于从 C++ 代码创建 QML 对象很有用,无论是显示可以可视化呈现的 QML 对象,还是将非可视 QML 对象数据集成到 C++ 应用程序中。

这似乎暗示这种非视觉使用是一种预期和受支持的用例。但我不确定我读对了。

4

1 回答 1

0

您正试图将一个类重用于两个目的,最好将类分成两个并使用聚合。

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;
};
于 2017-01-13T09:19:21.940 回答