Although Bea is correct, this is a really bad practice. The internal 
implementation of the ListView is not part of the public API and 
can change at any time (e.g. when switching to scene graph 
drawing), and the ListView also manage the lifetime of the list 
items so there's no grantee that the objects you're accessing 
won't just be deleted by the ListView.

Much better to make your list items access your c++ code than 
the other way around.


Cheers
Mathias

________________________________________
From: [email protected] 
[[email protected]] on behalf of ext 
[email protected] [[email protected]]
Sent: Monday, July 11, 2011 4:06 AM
To: [email protected]
Cc: [email protected]; [email protected]
Subject: Re: [Qt-qml] Problem with finding qml elements placed within ListView 
delegate from C++ code

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

_______________________________________________
Qt-qml mailing list
[email protected]
http://lists.qt.nokia.com/mailman/listinfo/qt-qml
_______________________________________________
Qt-qml mailing list
[email protected]
http://lists.qt.nokia.com/mailman/listinfo/qt-qml

Reply via email to