[Qt-qml] Problem with finding qml elements placed within ListView delegate from C++ code
mathias.malmqvist at nokia.com
mathias.malmqvist at nokia.com
Mon Jul 11 15:05:32 CEST 2011
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: qt-qml-bounces+mathias.malmqvist=nokia.com at qt.nokia.com [qt-qml-bounces+mathias.malmqvist=nokia.com at qt.nokia.com] on behalf of ext bea.lam at nokia.com [bea.lam at nokia.com]
Sent: Monday, July 11, 2011 4:06 AM
To: dshakhovski at gmail.com
Cc: qt-interest at qt.nokia.com; qt-qml at qt.nokia.com
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
Qt-qml at qt.nokia.com
http://lists.qt.nokia.com/mailman/listinfo/qt-qml
More information about the Qt-qml
mailing list