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

跟風遠走 提交于 2019-12-24 18:29:17

问题


I have a QQuickItem fetched from C++ side like this.

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

my_item is valid & has all the properties set on to it.

Scenario
I have 2 windows which need this QQuickItem to be drawn on alterantively. I want to render this my_item to a different window. This works perfectly fine as long as I set the Parent of the my_item to the other window

// the_other_window is a QQuickWindow
QQuickWindow * the_other_window;

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

This requires me to do setParentItem again back to my_item's original window otherwise it goes invisible on the original window. This is working but gives me unnecessary dependency. Instead I am trying to create a copy of the QQuickItem & do a setParentItem on that. By copying like this:

QQuickItem * item_copy = new QQuickItem(my_item);

Question: I want to make item_copy as exactly the same as my_item. I learnt that QQuickItem is not copyable. So, want to set all properties of my_item into item_copy. Thus recreating my_item from scratch. How can I do this? What properties should I copy primarily? width, height, x, y & what else?

Is there a method to copy all the valid properties into this new one without copying each one by one?


回答1:


To copy all the properties you must use the metaobject(), through this we obtain the properties and we can copy them as shown below. Note: not all properties can be written, for this we check with the method 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;
}

Example:

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));
    }
}

Output:

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)


来源:https://stackoverflow.com/questions/46118043/how-to-create-a-new-qquickitem-copy-from-scratch-on-c-side-with-the-same-prope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!