2017-02-16 233 views
2

我有一个QML对象,它可以在其中创建相同的对象。函数addChildRect从C++中调用。每个对象都提供有其独特的idobjectName(对于每个对象它们都是相同的)。我想使用QObject::findChild,从C++访问它们,但对于动态创建的对象,此函数总是返回空指针。我的建议是,该函数只解析最初在QML中的对象。我怎样才能访问从C++动态创建的对象?从C++访问动态创建的QML对象

Rect.qml

Rectangle { 
    color: "red" 
    function addChildRect(id,x,y,width,height) 
    { 
     var component; 
     component = Qt.createComponent("Rect.qml"); 
     component.createObject(this, { 
           id:id, 
           objectName:id, 
           x:x, 
           y:y, 
           width:width, 
           height:height}); 
    } 
} 

C++代码:

//find element 
auto parentRectView = engine.rootObjects().first()->findChild<QObject*>(QString::number(id())); 


//create element 
QMetaObject::invokeMethod(parentRectView,"addChildRect", 
          Q_ARG(QVariant,id()), 
          Q_ARG(QVariant,m_position.x()), 
          Q_ARG(QVariant,m_position.y()), 
          Q_ARG(QVariant,m_size.height()), 
          Q_ARG(QVariant,m_size.width())); 
+2

我想你应该为动态创建的对象设置父对象来查找是否使用'QObject :: findChild'。此外,为了避免不必要的操作,您可以将指向从addChildRect创建的对象的指针返回给C++ – folibis

+0

@folibis感谢您的回答?我是否正确理解你,我应该在QML对象构造代码中添加'parent:this'? 也可以请你提供一个简单的例子,如何从QML返回指针? – Lecko

+0

查看我的回答下面 – folibis

回答

2

假设我们有以下QML代码(main.qml):

Window { 
    width: 300 
    height: 400 
    visible: true 
    id: window 

    Component { 
     id: testItem 
     Rectangle { 
      width: 100 
      height: 100 
      color: "green" 
      anchors.centerIn: parent 
     } 
    } 

    function addItem(name) 
    { 
     var component = testItem.createObject(window.contentItem, {objectName: name}); 
     return component; 
    } 
} 

讲究 - 作为父母,我通过Item,在我的情况下,这是Window.contentItem - 隐藏的根项目Window,因为Window不是Item。 我不是javascript大师,但我认为你在这里使用的是this是指向函数的指针,而不是Item

好,这里是一个C++代码:

QQmlApplicationEngine engine; 
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 
QObject *item = dynamic_cast<QObject *>(engine.rootObjects().at(0)); 
QVariant retVal; 
QMetaObject::invokeMethod(item, "addItem", Qt::DirectConnection, 
          Q_RETURN_ARG(QVariant, retVal), 
          Q_ARG(QVariant, "test")); 

qWarning() << retVal; 

在我的情况下,输出会像

的QVariant(QObject的*,QQuickRectangle(0x2c125490,名称= “测试”) )

你只需要投QVariantQQuickItemQObject

至于找到动态创建的对象,你是对的。例如,下面的代码的输出:

QObject *rect = qvariant_cast<QObject*>(retVal); 
qWarning() << rect; 
QObject *myitem = item->findChild<QObject *>("test"); 
qWarning() << myitem; 

将是:

QQuickRectangle(0x2c270d38, name = "test") 
QObject(0x0) 

findChild回报空虽然rectparent被设置。 也许有人可以解释这种奇怪的行为。

+0

谢谢!我明白了! – Lecko

+0

对'QObject'使用'qobject_cast'并派生,在几个方面比较好,包括性能。 – dtech

+0

QML中的@folibis'parent'是“parentItem”,如在'QQuickItem :: parentItem()'中那样,它不一定与QObject父类相同,如'QObject :: parent() –