Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Problem with finding qml elements placed within ListView's delegate from C++ code (Resolved)
QtWS25 Last Chance

Problem with finding qml elements placed within ListView's delegate from C++ code (Resolved)

Scheduled Pinned Locked Moved QML and Qt Quick
10 Posts 3 Posters 10.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    autodafe
    wrote on last edited by
    #1

    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 + address

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

    1 Reply Last reply
    0
    • T Offline
      T Offline
      thisisbhaskar
      wrote on last edited by
      #2

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

      1 Reply Last reply
      0
      • T Offline
        T Offline
        thisisbhaskar
        wrote on last edited by
        #3

        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.

        1 Reply Last reply
        0
        • A Offline
          A Offline
          autodafe
          wrote on last edited by
          #4

          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.

          1 Reply Last reply
          0
          • T Offline
            T Offline
            thisisbhaskar
            wrote on last edited by
            #5

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

            1 Reply Last reply
            0
            • A Offline
              A Offline
              autodafe
              wrote on last edited by
              #6

              findChild("rect") and findChildren("rect") give the same result inside onRectClicked(). There are not children of rootObject with objectName "rect".

              1 Reply Last reply
              0
              • T Offline
                T Offline
                thisisbhaskar
                wrote on last edited by
                #7

                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

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  autodafe
                  wrote on last edited by
                  #8

                  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.

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    autodafe
                    wrote on last edited by
                    #9

                    Explanation of Bea (bea.lam@nokia.com).
                    http://lists.qt.nokia.com/pipermail/qt-qml/2011-July/002800.html

                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      Jaco
                      wrote on last edited by
                      #10

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

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved