创建 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 实例化和设置难题(不允许将任何内容传递给构造函数)