Problem with finding qml elements placed within ListView's delegate from C++ code (Resolved)
-
wrote on 7 Jul 2011, 18:18 last edited by
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.
-
wrote on 8 Jul 2011, 01:41 last edited by
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 ????
-
wrote on 8 Jul 2011, 03:20 last edited by
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.
-
wrote on 8 Jul 2011, 05:43 last edited by
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. -
wrote on 8 Jul 2011, 05:50 last edited by
[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.
-
wrote on 8 Jul 2011, 06:05 last edited by
findChild("rect") and findChildren("rect") give the same result inside onRectClicked(). There are not children of rootObject with objectName "rect".
-
wrote on 8 Jul 2011, 06:43 last edited by
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
-
wrote on 8 Jul 2011, 07:03 last edited by
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.
-
wrote on 11 Jul 2011, 06:07 last edited by
Explanation of Bea (bea.lam@nokia.com).
http://lists.qt.nokia.com/pipermail/qt-qml/2011-July/002800.html -
wrote on 30 Mar 2013, 08:24 last edited by
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...