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. ListView width inside Repeater

ListView width inside Repeater

Scheduled Pinned Locked Moved Solved QML and Qt Quick
10 Posts 2 Posters 1.9k Views 1 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.
  • E Offline
    E Offline
    egor.utsov
    wrote on last edited by
    #1

    Hi all. I am trying to build custom table, that fit to my needs. This is the code:

    GridLayout {
            property var columnName:  ["index", "name", "state", "time", "pps", "format"]
            property var columnWidth: [0.1,     0.4,    0.1,     0.1,    0.1,   0.2]
    
            id: grid
            anchors.fill: parent
            flow: GridLayout.LeftToRight
            columns: columnName.length
            rows: 5
    
            Repeater {
                id: repeater
                model: grid.columnName
    
                ListView {
                    property int prevCurrentIndex: 0
    
                    anchors.fill: parent
                    focus: index === 0
                    model: refTableModel
                    clip: true
                    implicitWidth: contentItem.childrenRect.width
    
                    delegate: Text {
                        width: 40
                        text: model[modelData]
                    }
                    onCurrentIndexChanged: {
                        if (focus !== true)
                            return;
    
                        var dir = currentIndex - prevCurrentIndex;
                        console.log("direction: " + dir);
                        for (var idx = 0; idx < repeater.count; ++idx) {
                            var item = repeater.itemAt(idx);
                            if (item !== this && item !== null) {
                                if (dir > 0) {
                                    item.incrementCurrentIndex();
                                } else {
                                    item.decrementCurrentIndex();
                                }
                            }
                        }
                        prevCurrentIndex = currentIndex;
                    }
                }
            }
        }
    

    What i want is to setup width of each column (implemented with ListView) accordingly to coefficient, denoting the part of whole GridLayout width. But this width somehow equal to zero, and i don't understand why. How to achieve what i needs?

    DiracsbracketD 1 Reply Last reply
    0
    • E egor.utsov

      Hi all. I am trying to build custom table, that fit to my needs. This is the code:

      GridLayout {
              property var columnName:  ["index", "name", "state", "time", "pps", "format"]
              property var columnWidth: [0.1,     0.4,    0.1,     0.1,    0.1,   0.2]
      
              id: grid
              anchors.fill: parent
              flow: GridLayout.LeftToRight
              columns: columnName.length
              rows: 5
      
              Repeater {
                  id: repeater
                  model: grid.columnName
      
                  ListView {
                      property int prevCurrentIndex: 0
      
                      anchors.fill: parent
                      focus: index === 0
                      model: refTableModel
                      clip: true
                      implicitWidth: contentItem.childrenRect.width
      
                      delegate: Text {
                          width: 40
                          text: model[modelData]
                      }
                      onCurrentIndexChanged: {
                          if (focus !== true)
                              return;
      
                          var dir = currentIndex - prevCurrentIndex;
                          console.log("direction: " + dir);
                          for (var idx = 0; idx < repeater.count; ++idx) {
                              var item = repeater.itemAt(idx);
                              if (item !== this && item !== null) {
                                  if (dir > 0) {
                                      item.incrementCurrentIndex();
                                  } else {
                                      item.decrementCurrentIndex();
                                  }
                              }
                          }
                          prevCurrentIndex = currentIndex;
                      }
                  }
              }
          }
      

      What i want is to setup width of each column (implemented with ListView) accordingly to coefficient, denoting the part of whole GridLayout width. But this width somehow equal to zero, and i don't understand why. How to achieve what i needs?

      DiracsbracketD Offline
      DiracsbracketD Offline
      Diracsbracket
      wrote on last edited by Diracsbracket
      #2

      @egor.utsov
      Something like this?

      ApplicationWindow {
          id: window
          visible: true
          width: 640
          height: 480
          title: qsTr("Hello World")
      
          GridLayout {
              id: grid
              property var columnName:  ["index", "name", "state", "time", "pps", "format"]
              property var columnWidth: [0.1,     0.4,    0.1,     0.1,    0.1,   0.2]
      
              anchors.fill: parent
              flow: GridLayout.LeftToRight
              columns: columnName.length
              rows: 1
      
              Repeater {
                  id: repeater
                  model: grid.columnName
      
                  ListView {
                      id: list
                      model: 10
                      clip: true
      
                      width: grid.columnWidth[index]*window.width
                      height: window.height
      
                      delegate: Text {
                          width: 40
                          text: "TEST" + index
                      }
                  }
              }
          }
      
      1 Reply Last reply
      0
      • E Offline
        E Offline
        egor.utsov
        wrote on last edited by
        #3

        @Diracsbracket Thanks! It approach worked, but i am planned to put this table in separate QML file and use it as a component. So i don't have access to ApplicationWindow object. What to do in this case. Use root item of QML document instead of ApplicationWindow?

        DiracsbracketD 1 Reply Last reply
        0
        • E Offline
          E Offline
          egor.utsov
          wrote on last edited by egor.utsov
          #4

          @Diracsbracket I checked approach with separate QML doc and it is not working. I try to create table as

          Window {
            width: 256
            height: 64
          
            CustomTable {
              width: parent.width
              height: parent.height
              model: Model{}
            }
          }
          

          Here, width and height of root item inside CustomTable will be equal to zero at the moment, when ListViews created. But if i create CustomTable like this:

          CustomTable {
              width: 256
              height: 64
              model: Model{}
            }
          

          it will work. But i don't want to depends on absolute values. How can i deal with it? And why sizes not calculated before constructing child items?

          1 Reply Last reply
          0
          • E egor.utsov

            @Diracsbracket Thanks! It approach worked, but i am planned to put this table in separate QML file and use it as a component. So i don't have access to ApplicationWindow object. What to do in this case. Use root item of QML document instead of ApplicationWindow?

            DiracsbracketD Offline
            DiracsbracketD Offline
            Diracsbracket
            wrote on last edited by Diracsbracket
            #5

            @egor.utsov
            You can define two properties

                Component {
                    id: gridComponent
            
                    GridLayout {
                        id: grid
                        property var columnName:  ["index", "name", "state", "time", "pps", "format"]
                        property var columnWidth: [0.1,     0.4,    0.1,     0.1,    0.1,   0.2]
            
                        property real gridWidth: 10 //dummy value
                        property real gridHeight: 10 //dummy value
                        .....
            
                            ListView {
                                id: list
                                 ...
                                width: grid.columnWidth[index]*grid.gridWidth
                                height: grid.gridHeight
                                ...
                            }
                }
            }//Component
            

            and then in JS for example:

                Component.onCompleted: {
                    var myGrid = gridComponent.createObject(someParent, {"gridWidth": someValue, "gridHeight": someValue2})
                }
            
            1 Reply Last reply
            0
            • E Offline
              E Offline
              egor.utsov
              wrote on last edited by egor.utsov
              #6

              @Diracsbracket Where i should catch onCompleted event ? Inside component? Below is not working

              CustomComponent.qml:

              Item {
                id: root
                Component.onCompleted {console.log("width = " + root.width);} // width = 0 <-- problem
              }
              

              Main.qml

              Window {
                width: 256
                height: 64
                CustomComponent {
                  width: parent.width
                  height: parent.height
                }
              }
              
              DiracsbracketD 1 Reply Last reply
              0
              • E egor.utsov

                @Diracsbracket Where i should catch onCompleted event ? Inside component? Below is not working

                CustomComponent.qml:

                Item {
                  id: root
                  Component.onCompleted {console.log("width = " + root.width);} // width = 0 <-- problem
                }
                

                Main.qml

                Window {
                  width: 256
                  height: 64
                  CustomComponent {
                    width: parent.width
                    height: parent.height
                  }
                }
                
                DiracsbracketD Offline
                DiracsbracketD Offline
                Diracsbracket
                wrote on last edited by Diracsbracket
                #7

                @egor.utsov
                If you use the parent's width and height properties to set a child's dimensions, then the child's width and height are set when the child first becomes visible, and this is done after Component.onCompleted() it seems - the parent seems to be assigned after the component is completed.

                So the console.debug() in your particular example shows the still uninitialized value.

                E 1 Reply Last reply
                0
                • DiracsbracketD Diracsbracket

                  @egor.utsov
                  If you use the parent's width and height properties to set a child's dimensions, then the child's width and height are set when the child first becomes visible, and this is done after Component.onCompleted() it seems - the parent seems to be assigned after the component is completed.

                  So the console.debug() in your particular example shows the still uninitialized value.

                  E Offline
                  E Offline
                  egor.utsov
                  wrote on last edited by
                  #8

                  @Diracsbracket what to do then?

                  DiracsbracketD 1 Reply Last reply
                  0
                  • E egor.utsov

                    @Diracsbracket what to do then?

                    DiracsbracketD Offline
                    DiracsbracketD Offline
                    Diracsbracket
                    wrote on last edited by Diracsbracket
                    #9

                    @egor.utsov
                    For example:

                            Item {
                                anchors.fill: parent
                                id: item
                                property bool ok: (height>0) && (width>0)
                    
                                onOkChanged: {
                                    console.debug(item.height + " " + item.width)
                                    var comp = Qt.createComponent("CustomComponent.qml")
                                    var obj = comp.createObject(this, {"gridWidth": item.width, "gridHeight": item.height})
                                }
                    
                            }
                    
                    1 Reply Last reply
                    1
                    • E Offline
                      E Offline
                      egor.utsov
                      wrote on last edited by
                      #10

                      Thanks to @Diracsbracket

                      Final solution:

                      Item {
                          property ListModel model
                          property bool timeToBuildTable: (width > 0) && (height > 0)
                      
                          id: root
                      
                          onTimeToBuildTableChanged: {
                              if (timeToBuildTable) {
                                  loader.anchors.fill = root;
                                  loader.sourceComponent = gridComponent;
                              }
                          }
                      
                          onActiveFocusChanged: loader.item.forceActiveFocus();
                      
                          Loader {
                              id: loader
                              anchors.fill: parent
                          }
                      
                          Component {
                              id: gridComponent
                      
                              FocusScope {
                                  GridLayout {
                                      property var columnName:  ["index", "name", "state", "time", "pps", "format"]
                                      property var columnWidth: [0.1,     0.5,    0.1,     0.1,    0.1,   0.1]
                      
                                      id: grid
                                      anchors.fill: parent
                      
                                      flow: GridLayout.LeftToRight
                                      columns: columnName.length
                                      rows: 5
                                      rowSpacing: 1
                                      columnSpacing: 1
                      
                                      Repeater {
                                          id: repeater
                                          model: grid.columnName
                      
                                          ListView {
                                              property int columnIndex: index
                                              property int prevCurrentIndex: 0
                      
                                              id: column
                      
                                              model: root.model
                                              focus: index === 0
                                              clip: true
                                              spacing: 1
                      
                                              Layout.fillHeight: true
                                              Layout.fillWidth: true
                                              width: root.width * grid.columnWidth[columnIndex]
                      
                                              delegate: Rectangle {
                                                  width: root.width * grid.columnWidth[column.columnIndex]
                                                  height: root.height / grid.rows
                      
                                                  Text {
                                                      text: model[modelData]
                                                  }
                                              }
                      
                                              onCurrentIndexChanged: {
                                                  if (focus !== true)
                                                      return;
                      
                                                  var dir = currentIndex - prevCurrentIndex;
                                                  for (var idx = 0; idx < repeater.count; ++idx) {
                                                      var item = repeater.itemAt(idx);
                                                      if (item !== this && item !== null) {
                                                          if (dir > 0) {
                                                              item.incrementCurrentIndex();
                                                          } else {
                                                              item.decrementCurrentIndex();
                                                          }
                                                      }
                                                  }
                                                  prevCurrentIndex = currentIndex;
                                              }
                                          }
                                      }
                                  }
                              }
                          }
                      }
                      
                      
                      1 Reply Last reply
                      1

                      • Login

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