[Qt-qml] Problem with finding qml elements placed within ListView delegate from C++ code

bea.lam at nokia.com bea.lam at nokia.com
Mon Jul 11 05:06:16 CEST 2011


On 08/07/2011, at 4:19 AM, ext Дмитрий Шаховский wrote:

> Hi,
> I have a problem when I tried to find a qml element placed within ListView 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.


QObject::findChild() won't find the delegate objects because they are added as "child items" in the graphics scene, rather than child objects in the QObject* hierarchy. Child items in a graphics scene are accessible through QGraphicsItem::childItems().

Also, ListView inherits from Flickable, and delegate items within a Flickable are parented to a separate item that holds the contents of the Flickable, rather than the Flickable itself. This separate item is accessible through the 'contentItem' property:  http://doc.qt.nokia.com/4.7/qml-flickable.html#contentItem-prop

So to find a delegate instance within the view, add an objectName to the view:


ListView {
	objectName: "view"


and in main.cpp:

    QObject *listView = rootObject->findChild<QObject*>("view");
    QDeclarativeItem *contentItem = qvariant_cast<QDeclarativeItem*>(listView->property("contentItem"));

    foreach (QGraphicsItem *item, contentItem->childItems()) {
        if (qobject_cast<QDeclarativeItem*>(item)->objectName() == "rect") {
            qDebug() << "Found:" << item;
        }
    }

> 
> 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.

Yes, calling QObject::parent() here is referring to the QObject* parent, rather than the parent item in the graphics scene. In QML, referring to item.parent actually refers to the QDeclarativeItem* parent item, not the QObject* parent (as you can see by the QDeclarativeItem::parent docs).


regards,

Bea



More information about the Qt-qml mailing list