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. Repeater and itemAt issue
Forum Updated to NodeBB v4.3 + New Features

Repeater and itemAt issue

Scheduled Pinned Locked Moved QML and Qt Quick
16 Posts 5 Posters 12.5k Views 3 Watching
  • 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.
  • B Offline
    B Offline
    babazaroni
    wrote on last edited by
    #1

    Hello, I am experimenting with QML and trying to access an item created by repeator, but am getting the error:

    TypeError: Result of expression 'repeater.itemAt(0)' [null] is not an object.

    I can access the repeater.count but not any items.

    How can I do this?

    @import QtQuick 1.1

    Item {
    width: parent.width
    height: parent.height

    Row {
        id: rows
        Repeater {
            id: repeater
            model: 10
            Rectangle {
                  width: 10; height: 20;
          }
        }
    }
    Rectangle {
        x: repeater.itemAt(0).x  // this fails with TypeError: Result of expression 'repeater.itemAt(0)' [null] is not an object.
        y: 100 * repeater.count  // this works
        width: 10; height: 10
    }
    

    }
    @

    1 Reply Last reply
    0
    • I Offline
      I Offline
      ixSci
      wrote on last edited by
      #2

      Hi babazaroni! Repeater is not an actual parent of the items but the repeater's parent is. Repeater just adds children to the positioner item so you should use your Row with rows id to work with children.

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mbrasser
        wrote on last edited by
        #3

        Hi,

        There are a couple issues at play here:

        1. The order in which the bindings are initially evaluated. In this case, repeater.itemAt(0).x is evaluated before the Repeater has actually created its children.
        2. The fact that methods can't NOTIFY (like properties do) when their return value would change. In this case, even when the items are finally created, repeater.itemAt(0).x is not reevaluated.

        You could work around this by assigning the value (or binding) at component completion instead, e.g.

        @
        Component.onCompleted: myRect.x = repeater.itemAt(0).x //once-off assignment
        @

        or

        @
        Component.onCompleted: myRect.x = (function(){ return repeater.itemAt(0).x; }) //binding
        @

        Regards,
        Michael

        1 Reply Last reply
        1
        • Stefan Monov76S Offline
          Stefan Monov76S Offline
          Stefan Monov76
          wrote on last edited by
          #4

          @mbrasser :
          Thanks, your advice makes sense and I tried it but I'm still getting a null from itemAt.

          My code:

          import QtQuick 2.7
          import QtQuick.Window 2.2
          
          Window {
              visible: true
              width: 640
              height: 480
              
              Column {
                  Row {
                      Repeater {
                          id: rectRepeater
                          model: 3
                          Rectangle {
                              width: 30
                              height: 30
                              color: "red"
                              radius: 10
                          }
                      }
                  }
                  Row {
                      Repeater {
                          model: 3
                          Text {
                              Component.onCompleted: {
                                  text: rectRepeater.itemAt(0).width;
                              }
                          }
                      }
                  }
              }
          }
          

          I'd appreciate any ideas on that one.

          1 Reply Last reply
          0
          • p3c0P Offline
            p3c0P Offline
            p3c0
            Moderators
            wrote on last edited by
            #5

            @Stefan-Monov76 Probably because the Item is not instantiated by the time this Repeater starts creating the items. You can easily solve this by delaying the creation of items in the other Repeater.

            Column {
                    anchors.fill: parent
                    Row {
                        Repeater {
                            id: rectRepeater
                            model: 3
                            Rectangle {
                                width: 30
                                height: 30
                                color: "red"
                                radius: 10
                            }
            
                            Component.onCompleted: {
                                textRepeater.model = 3
                            }
                        }
            
                    }
                    Row {
                        Repeater {
                            id: textRepeater
                            Text {
                                text : rectRepeater.itemAt(0).width
                            }
                        }
                    }
                }
            

            157

            Stefan Monov76S 1 Reply Last reply
            1
            • p3c0P p3c0

              @Stefan-Monov76 Probably because the Item is not instantiated by the time this Repeater starts creating the items. You can easily solve this by delaying the creation of items in the other Repeater.

              Column {
                      anchors.fill: parent
                      Row {
                          Repeater {
                              id: rectRepeater
                              model: 3
                              Rectangle {
                                  width: 30
                                  height: 30
                                  color: "red"
                                  radius: 10
                              }
              
                              Component.onCompleted: {
                                  textRepeater.model = 3
                              }
                          }
              
                      }
                      Row {
                          Repeater {
                              id: textRepeater
                              Text {
                                  text : rectRepeater.itemAt(0).width
                              }
                          }
                      }
                  }
              
              Stefan Monov76S Offline
              Stefan Monov76S Offline
              Stefan Monov76
              wrote on last edited by
              #6

              @p3c0 :
              Thanks a lot, this works. But shouldn't @mbrasser's solution (which is used in my previous post) also have worked?

              1 Reply Last reply
              0
              • p3c0P Offline
                p3c0P Offline
                p3c0
                Moderators
                wrote on last edited by
                #7

                @Stefan-Monov76 That is because there is no guarantee that those component have been instantiated even by then.

                157

                Stefan Monov76S 1 Reply Last reply
                0
                • p3c0P p3c0

                  @Stefan-Monov76 That is because there is no guarantee that those component have been instantiated even by then.

                  Stefan Monov76S Offline
                  Stefan Monov76S Offline
                  Stefan Monov76
                  wrote on last edited by
                  #8

                  @p3c0 :
                  Your own code relies on rectRepeater having instantiated its items by the time onCompleted fires. My code relies on exactly the same. So there shouldn't be any difference, should there?

                  1 Reply Last reply
                  0
                  • p3c0P Offline
                    p3c0P Offline
                    p3c0
                    Moderators
                    wrote on last edited by
                    #9

                    @Stefan-Monov76 My code atleast guarantees that the 2nd Repeater doesnot start instantiating items before 1st repeater have finished instantiating them because 2nd Repeater's Items depends on 1st Repeater's Item.

                    157

                    Stefan Monov76S 1 Reply Last reply
                    0
                    • p3c0P p3c0

                      @Stefan-Monov76 My code atleast guarantees that the 2nd Repeater doesnot start instantiating items before 1st repeater have finished instantiating them because 2nd Repeater's Items depends on 1st Repeater's Item.

                      Stefan Monov76S Offline
                      Stefan Monov76S Offline
                      Stefan Monov76
                      wrote on last edited by
                      #10

                      @p3c0 :
                      If I'm not mistaken, Component.onCompleted fires only when the entire top-level component (in this case the Window) has finished loading. Even when I've put the Component.onCompleted handler inside my Text item. So my code only accesses the first Repeater's items when the Window has loaded. And if the Window has loaded, then the first Repeater has already instantiated its items. No?

                      1 Reply Last reply
                      0
                      • p3c0P Offline
                        p3c0P Offline
                        p3c0
                        Moderators
                        wrote on last edited by
                        #11

                        @Stefan-Monov76 No. Each component has this attached property.

                        157

                        Stefan Monov76S 1 Reply Last reply
                        0
                        • p3c0P p3c0

                          @Stefan-Monov76 No. Each component has this attached property.

                          Stefan Monov76S Offline
                          Stefan Monov76S Offline
                          Stefan Monov76
                          wrote on last edited by
                          #12

                          @p3c0 :
                          Thanks again for the continued replies. I don't intend to argue or prove myself right, just to clear up the situation for myself, mind you! :)
                          The docs say a component is one of two things:

                          • a type defined by the top-level element of a QML file (one type per file) - in my case, I have defined exactly one such component, and it "derives" from Window
                          • an object defined inline by instantiating the Component type, that you can later instantiate via a Loader object. This scenario is irrelevant here.

                          So my Text objects are not components, they are merely objects, and since they are not components, they don't have a Component.onCompleted signal, they use the Window's Component.onCompleted signal.

                          It's important to me to be strict when using the term "Component", it has a very specific meaning in QML.

                          1 Reply Last reply
                          0
                          • p3c0P Offline
                            p3c0P Offline
                            p3c0
                            Moderators
                            wrote on last edited by
                            #13

                            @Stefan-Monov76 That's fine :)
                            component in this case I was referring to QML types that are inherits Item. I generally prefer to say QML components when referring to these types. Sorry for not being clear.
                            So basically any QML type that inherits Item has the Component.onCompleted signal. For eg. Text, Rectangle, Row ...
                            Here is the complete list:
                            http://doc.qt.io/qt-5/qml-qtquick-item.html
                            Look for the row named by "Inherited By".

                            157

                            Stefan Monov76S 1 Reply Last reply
                            0
                            • p3c0P p3c0

                              @Stefan-Monov76 That's fine :)
                              component in this case I was referring to QML types that are inherits Item. I generally prefer to say QML components when referring to these types. Sorry for not being clear.
                              So basically any QML type that inherits Item has the Component.onCompleted signal. For eg. Text, Rectangle, Row ...
                              Here is the complete list:
                              http://doc.qt.io/qt-5/qml-qtquick-item.html
                              Look for the row named by "Inherited By".

                              Stefan Monov76S Offline
                              Stefan Monov76S Offline
                              Stefan Monov76
                              wrote on last edited by
                              #14

                              @p3c0 :
                              Hmm, the docs for the Item type that you link to don't mention having the onCompleted signal.

                              1 Reply Last reply
                              0
                              • p3c0P Offline
                                p3c0P Offline
                                p3c0
                                Moderators
                                wrote on last edited by
                                #15

                                @Stefan-Monov76 It is an attached signal. It is mentioned here.

                                An attached signal handler is referred to in the same way. For example, the Component.onCompleted attached signal handler is commonly used to execute some JavaScript code when a component's creation process has been completed.

                                157

                                Stefan Monov76S 1 Reply Last reply
                                0
                                • p3c0P p3c0

                                  @Stefan-Monov76 It is an attached signal. It is mentioned here.

                                  An attached signal handler is referred to in the same way. For example, the Component.onCompleted attached signal handler is commonly used to execute some JavaScript code when a component's creation process has been completed.

                                  Stefan Monov76S Offline
                                  Stefan Monov76S Offline
                                  Stefan Monov76
                                  wrote on last edited by
                                  #16

                                  @p3c0 :
                                  Ok, thanks.

                                  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