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 + addressIf 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.
-
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.
-
Explanation of Bea (bea.lam@nokia.com).
http://lists.qt.nokia.com/pipermail/qt-qml/2011-July/002800.html