Problem with finding qml elements placed within ListView's delegate from C++ code (Resolved)



  • Hi,
    I have a problem when I tried to find a qml element placed within ListView's delegate from C++ code.

    E.g.

    @Rectangle {
    ...
    ListView{
    ...
    delegate: Rectangle{
    objectName: "rect"
    }

       model: ListModel{
                  ListElement{}
                  ListElement{}
                  ListElement{}
              }
    

    }
    }@

    And somewhere in C++ code

    @QDeclarativeView view = new QDeclarativeView;
    view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));
    QObject
    rootObject = view->rootObject();
    QObject* obj = rootObject->findChild<QObject*>("rect");@

    obj will be null.

    If in qml I ask Rectangle's ancestor, e.g.
    @...
    delegate: Rectangle{
    objectName: "rect"
    Component.onCompleted: { console.log("rect container " + parent.parent) }
    }
    ...@
    output will be QdeclarativeListView + address

    If I still be able to get a pointer to Rectangle as QObject*, as follows

    @Rectangle {
    ...
    signal rectClicked(variant id)

    ListView{
    ...
    objectName: “listView”
    delegate:
    Item {
    ...
    MouseArea {
    onClicked: rectClicked(rect)
    anchors.fill: parent
    }
    Rectangle{
    id: rect
    objectName: "rect"
    }
    }
    ...
    }
    ...
    }@

    in C++ slot connected to rectClicked signal

    @void SomeObject::onRectClicked(QVariant element)
    {
    QObject* rootObject = declarativeView->rootObject();
    QObject* listView = rootObject->findChild<QObject*>("listView");

    QObject* obj = element.value<QObject*>()->parent()->parent();
    //obj will be null instead of the equality of listView
    //(element.value<QObject*>() is QDeclarativeRectangle)
    }@

    So delegate component children are not in root object's tree.



  • The problem I see is that ListView will create objects of delegate component type dynamically when ever needed. So, All the rectangles will have same objectName ????



  • The below link may help
    http://developer.qt.nokia.com/doc/qt-4.7/qtbinding.html
    Search for "Locating child objects"

    If objectName is used inside a delegate of a ListView, Repeater or some other element that creates multiple instances of its delegates, there will be multiple children with the same objectName. In this case, QObject::findChildren() can be used to find all children with a matching objectName.



  • If i can receive click signal this means delegate item is already instantiated. And findChildren("rect") will return a list of size 0. Checked. In case when we use Repeater, e.g.
    @Rectangle {
    ...
    Column {
    anchors.fill: parent
    Repeater {
    model: 10
    Rectangle{
    id: image
    objectName: "rect"
    }
    }
    }
    ...
    }@
    all children are found perfectly.



  • [quote author="autodafe" date="1310103806"]If i can receive click signal this means delegate item is already instantiated. And findChildren("rect") will return a list of size 0. Checked. [/quote]

    This will work as this is happening at run time. Can you try on thing..

    Try to run the below code inside your onRectClicked() and see if you get all the children
    @QObject* rootObject = view->rootObject();
    rootObject->findChildren<QObject*>("rect");@

    When onRectClicked() is called, you for sure have all the ListView delegate components instantiated.



  • findChild("rect") and findChildren("rect") give the same result inside onRectClicked(). There are not children of rootObject with objectName "rect".



  • Ok what I could see by debugging ListView is that objectName's of all the items ( and children) of Delegate items are empty at run time.

    Looks like ListView clears the objectName of all the delegates.
    Looks like a bug as the documentation says we can get delegate instances also with findChildern().

    I have uploaded a image which shows the problem !https://picasaweb.google.com/thisisbhaskar/Workrelated#5626868193032468930



  • In fact there are not delegate item among ListVew's children. I saw addresses of all children and haven't Rectangle's address. We can find Rectangle's address as follows
    @...
    delegate: Rectangle{
    objectName: "rect"
    id: rect
    Component.onCompleted: { console.log(rect) }
    }
    ...@

    And it will be the same as QObject address in my onRectClicked slot.





  • The two links above doesn't work.

    Can anyone tell me how to solve exactly this problem? I can't connect a signal in a delegate to a slot in my C++ code...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.