如何在 C++ 端从头开始创建一个具有与现有副本相同属性的新 QQuickItem 副本

How to create a new QQuickItem copy from scratch on C++ side with the same properties as an existing one

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

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

my_item 有效并且设置了所有属性。

场景
我有 2 windows 需要这个 QQuickItem 来交替绘制。我想将此 my_item 渲染为不同的 window。只要我将 my_item 的父级设置为另一个 window

// the_other_window is a QQuickWindow
QQuickWindow * the_other_window;

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

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

QQuickItem * item_copy = new QQuickItem(my_item);

问题: 我想让 item_copymy_item 完全一样。我了解到 QQuickItem 不可复制。所以,想把my_item的所有属性都设置成item_copy。因此从头开始重新创建 my_item。我怎样才能做到这一点?我应该主要复制哪些属性?宽度、高度、x、y 以及其他什么?

有没有一种方法可以将所有有效属性复制到这个新属性中,而无需一个一个地复制?

要复制所有属性,您必须使用metaobject(),通过它我们获取属性,我们可以复制它们,如下所示。注意:并非所有属性都可以写入,为此我们使用方法 isWritable():

检查
QQuickItem *copyQQuickItem(QQuickItem *item){
    QQuickItem *item_Copy = new QQuickItem;

    const QMetaObject *mo = item->metaObject();

    for (int i = mo->propertyOffset(); i < mo->propertyCount(); ++i){
        if(mo->property(i).isWritable()){
            const char* name = mo->property(i).name();
            item_Copy->setProperty(name, item->property(name));
        }
    }
    return item_Copy;
}

示例:

QQuickItem * my_item = engine.rootObjects()[0]->findChild<QQuickItem*>("ItemObjectName");
QQuickItem *item_copy = copyQQuickItem(my_item);

const QMetaObject *mo = my_item->metaObject();

for (int i = mo->propertyOffset(); i < mo->propertyCount(); ++i){
    if(mo->property(i).isWritable()){
        const char* name = mo->property(i).name();
        qDebug()<<name<<my_item->property(name)<<item_copy->property(name);
        Q_ASSERT(my_item->property(name)==item_copy->property(name));
    }
}

输出:

parent QVariant(QQuickItem*, QQuickRootItem(0x55975cfdf520)) QVariant(QQuickItem*, QQuickRootItem(0x55975cfdf520))
x QVariant(double, 0) QVariant(double, 0)
y QVariant(double, 0) QVariant(double, 0)
z QVariant(double, 0) QVariant(double, 0)
width QVariant(double, 100) QVariant(double, 100)
height QVariant(double, 100) QVariant(double, 100)
opacity QVariant(double, 1) QVariant(double, 1)
enabled QVariant(bool, true) QVariant(bool, true)
visible QVariant(bool, true) QVariant(bool, true)
state QVariant(QString, "") QVariant(QString, "")
baselineOffset QVariant(double, 0) QVariant(double, 0)
clip QVariant(bool, false) QVariant(bool, false)
focus QVariant(bool, false) QVariant(bool, false)
activeFocusOnTab QVariant(bool, false) QVariant(bool, false)
rotation QVariant(double, 0) QVariant(double, 0)
scale QVariant(double, 1) QVariant(double, 1)
transformOrigin QVariant(int, 4) QVariant(int, 4)
smooth QVariant(bool, true) QVariant(bool, true)
antialiasing QVariant(bool, false) QVariant(bool, false)
implicitWidth QVariant(double, 0) QVariant(double, 0)
implicitHeight QVariant(double, 0) QVariant(double, 0)