创建 QQuickItem 子类的实例是不是存在我不打算呈现或添加到 QML 树的实例?

Posted

技术标签:

【中文标题】创建 QQuickItem 子类的实例是不是存在我不打算呈现或添加到 QML 树的实例?【英文标题】:Are there gotchas with creating an instance of a QQuickItem subclass which instance I don't intend to render or add to a QML tree?创建 QQuickItem 子类的实例是否存在我不打算呈现或添加到 QML 树的实例? 【发布时间】:2017-01-12 12:37:18 【问题描述】:

如您所知,QQuickFramebufferObject::Renderer 子类不应直接访问其父项的属性,而应在其synchronize() 方法中将它们复制到自身。所以代码往往看起来像这样(使用来自here 的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 树中)

引用自docs:

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

这似乎暗示这种非视觉使用是一种预期且受支持的用例。但我不确定我没看错。

【问题讨论】:

QtObject 用于非视觉内容,减少开销。限制是它只能有属性,不能有孩子,这有点傻,考虑到它本质上是一个可以有孩子的QObject,功能只是没有暴露给QML。 @ddriver:但是我正在同步的项目 from 一个可视项目,我不能让它成为一个非可视项目,因为那样它不会显示。 【参考方案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;
;

【讨论】:

以上是关于创建 QQuickItem 子类的实例是不是存在我不打算呈现或添加到 QML 树的实例?的主要内容,如果未能解决你的问题,请参考以下文章

判断 UIViewController 子类的实例是不是存在

如何在 C++ 端获取有效的 QQuickItem 实例

来自 C++ 的 QQuickItem 实例化和设置难题(不允许将任何内容传递给构造函数)

如何在 C++ 端获取 QQuickItem 的 C++ 对象实例 [重复]

C++ QQuickItem:如何在项目大小更改时触发函数

如何创建 QQuickItem 的单独副本并将其呈现在不同的窗口上