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

Posted

技术标签:

【中文标题】如何创建 QQuickItem 的单独副本并将其呈现在不同的窗口上【英文标题】:How create a separate copy of a QQuickItem & render it on a different window 【发布时间】:2017-09-08 12:56:32 【问题描述】:

我有一个像这样从 C++ 端获取的QQuickItem

QQuickItem * my_item = qmlEngine->rootObjects()[0]->findChild<QQuickItem*>("ItemObjectName");

my_item 有效且已设置所有属性。

场景 我有 2 个窗口 需要交替绘制此 QQuickItem。我想将此my_item 渲染到另一个窗口。只要我将my_item 的父级设置为另一个窗口,这就可以正常工作

// the_other_window is a QQuickWindow
QQuickWindow * the_other_window;

// here I set parent
my_item->setParentItem(the_other_window->contentItem());

这需要我再次执行setParentItem 回到my_item 的原始窗口,否则它会在原始窗口中不可见。这是有效的,但给了我不必要的依赖。相反,我正在尝试创建QQuickItem 的副本并在其上执行setParentItem。像这样复制:

QQuickItem * item_copy = new QQuickItem(my_item);

问题: 但这似乎不会创建QQuickItem 的副本,因此我在the_other_window 上看不到my_item 的副本。

问题: 我只想知道,如何在不影响原始QQuickItem 的可见性/状态的情况下将QQuickItem 创建到另一个指针QQuickItem * item_copy 中并在另一个窗口上呈现它?

【问题讨论】:

你不能改用ShaderEffectSource吗? 【参考方案1】:

QQuickItem 的接口不提供可克隆性。如果是这样,那么它的所有子类都必须重新实现一个虚拟的clone() 函数。

确实,QQuickItem 派生自 QObject,它显式禁用类似复制的操作(复制构造函数和赋值运算符),因此它们在任何 QQuickItem 派生类中也被禁用。即使你有一个 QQuickItem 的特定子类,你认为你知道如何复制它,你也不能为它实现“真正的”复制。

在后一种情况下,最接近的做法是实例化一个新的空白项,然后手动将相关属性的所有值从旧实例复制到新实例。您可以将代码封装在 copy 函数中。

【讨论】:

创建一个空白QQuickItem 并将所有属性复制到新的。是否可以参考一些这样做的例子?我现在正在尝试计算如何将现有属性复制到空白 QQuickItem 感谢您澄清复制部分。我创建了一个不同的问题here。如果你愿意,请提出一些建议 你应该共享数据部分而不是复制任何东西,并且简单地实例化两个不同的可视对象,引用同一个数据对象。 @dtech:这在源代码中更尴尬,因为你有一个额外的对象(间接一步)。它会在不同组件之间造成不一致 - 您建议让那些需要复制以保留“数据包对象”,而所有其他组件 - 将其数据直接保留为属性。此外,您将无法将 Item 类型本身的属性移动到您的数据包对象 - 例如 xwidth 等。 @StefanMonov - 相反。您的方法将在一个对象发生更改的那一刻中断,该更改不会反映在其副本中,因此它们不再是副本。而如果您绑定到单个数据对象,则更改将反映在所有视图中。如果您愿意,您仍然可以转换副本,方法是使用专用转换或包装在转换父级中。

以上是关于如何创建 QQuickItem 的单独副本并将其呈现在不同的窗口上的主要内容,如果未能解决你的问题,请参考以下文章

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

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

如何使用 AJAX 渲染部分内容?拉拉维尔 5.2

如何在 QQuickItem 中绘制文本

有效地从 QPaintDevice 到 QQuickItem 中的 QSGTexture

将背景图像添加到 QQuickItem