2017-02-16 234 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() –