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. (SOLVED) QML - How to get ListView height and width of it's children elements (possibly delegates)

(SOLVED) QML - How to get ListView height and width of it's children elements (possibly delegates)

Scheduled Pinned Locked Moved QML and Qt Quick
qmllistviewdelegatecontentheightcomponent
10 Posts 6 Posters 27.4k 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.
  • S Offline
    S Offline
    svyatoslav911512
    wrote on 2 Jul 2015, 16:54 last edited by svyatoslav911512 7 Apr 2015, 00:48
    #1

    Hello,

    I have some custom menu element for future usage as Context/Popup menu. There is the code:

    BreezeQuickMenu.qml

    import QtQuick 2.4
    
    Item {
        id: root
        property BreezeQuickPalette palette: BreezeQuickPalette
        property alias currentIndex: menuList.currentIndex
        default property alias contents: addItem.children
        property bool autoHideMenu: true
        property int fontSize: 16
        property string iconSource
        property bool menuVisible: false
        signal clicked()
        Behavior on opacity {
            NumberAnimation{
                duration: 250
            }
        }
        Item {
            id: addItem
        }
        ListView{
            id: menuList
            anchors.fill: parent
            model: contents
            clip: true
            delegate: menuElement
        }
        Component {
            id: menuElement
            Rectangle {
                id: menu
                property bool isCurrentItem: ListView.isCurrentItem
                color: palette.alternateBackground
                height: menuText.font.pixelSize*2.7
                width: menuList.width
                Image {
                    id: menuIcon
                    anchors{
                        verticalCenter: parent.verticalCenter
                        left: parent.left
                    }
                }
                Text {
                    id: menuText
                    anchors{
                        verticalCenter: parent.verticalCenter
                        left: menuIcon.right
                        leftMargin: 8
                    }
                    text: title
                    color: palette.normalText
                    font.pointSize: fontSize
                    z: parent.z + 1
                }
                Rectangle {
                    anchors.fill: parent
                    opacity: (menuElementArea.pressed) ? 0.8 : 0
                    color: palette.focusColor
                    Behavior on opacity {
                        NumberAnimation {
                            duration: 100
                        }
                    }
                }
                MouseArea {
                    id: menuElementArea
                    anchors.fill: parent
                    hoverEnabled: true
                    onClicked: {
                        menuList.currentIndex = index
                        if (autoHideMenu) {
                            menuVisible = false
                        }
                        menuList.model[index].clicked()
                    }
                    z: parent.z + 2
                }
            }
        }
    }
    

    BreezeQuickMenuItem.qml

    import QtQuick 2.4
    
    Item {
        id: root
        property string title: "Menu Element"
        signal clicked()
    }
    

    main.qml (main element is ApplicationWindow)

    /* some trimmed code */
    BreezeQuickMenu{
        id: brMenu
        x: 14
        y: 236
        width: 256
        height: 296
        palette: brPalette
        fontSize: 16
        BreezeQuickMenuItem{
            title: "Item 1111111111111"
            onClicked: mbox.show()
        }
        BreezeQuickMenuItem{
            title: "Item 2"
            onClicked: breezeQuickProgressBar1.indeterminate = true
        }
        BreezeQuickMenuItem{
            title: "Item 3"
            onClicked: breezeQuickProgressBar1.indeterminate = false
        }
        BreezeQuickMenuItem{
            title: "Element 4"
        }
        BreezeQuickMenuItem{
            title: "Element 5555666"
        }
    }
    /* some trimmed code */
    

    How can I set implicitWidth and implicitHeight of my custom element to actual ListView width and height? Looks like I need to define bigger width between ListView elements and set implicitWidth to it's value. But I don't know how to do it, contentWidth property won't work. Please help me to understand what can I do for finishing this goal. Full code there:

    $ git clone git://git.code.sf.net/p/breezequick/code breezequick-code

    P 1 Reply Last reply 3 Jul 2015, 07:11
    0
    • S svyatoslav911512
      2 Jul 2015, 16:54

      Hello,

      I have some custom menu element for future usage as Context/Popup menu. There is the code:

      BreezeQuickMenu.qml

      import QtQuick 2.4
      
      Item {
          id: root
          property BreezeQuickPalette palette: BreezeQuickPalette
          property alias currentIndex: menuList.currentIndex
          default property alias contents: addItem.children
          property bool autoHideMenu: true
          property int fontSize: 16
          property string iconSource
          property bool menuVisible: false
          signal clicked()
          Behavior on opacity {
              NumberAnimation{
                  duration: 250
              }
          }
          Item {
              id: addItem
          }
          ListView{
              id: menuList
              anchors.fill: parent
              model: contents
              clip: true
              delegate: menuElement
          }
          Component {
              id: menuElement
              Rectangle {
                  id: menu
                  property bool isCurrentItem: ListView.isCurrentItem
                  color: palette.alternateBackground
                  height: menuText.font.pixelSize*2.7
                  width: menuList.width
                  Image {
                      id: menuIcon
                      anchors{
                          verticalCenter: parent.verticalCenter
                          left: parent.left
                      }
                  }
                  Text {
                      id: menuText
                      anchors{
                          verticalCenter: parent.verticalCenter
                          left: menuIcon.right
                          leftMargin: 8
                      }
                      text: title
                      color: palette.normalText
                      font.pointSize: fontSize
                      z: parent.z + 1
                  }
                  Rectangle {
                      anchors.fill: parent
                      opacity: (menuElementArea.pressed) ? 0.8 : 0
                      color: palette.focusColor
                      Behavior on opacity {
                          NumberAnimation {
                              duration: 100
                          }
                      }
                  }
                  MouseArea {
                      id: menuElementArea
                      anchors.fill: parent
                      hoverEnabled: true
                      onClicked: {
                          menuList.currentIndex = index
                          if (autoHideMenu) {
                              menuVisible = false
                          }
                          menuList.model[index].clicked()
                      }
                      z: parent.z + 2
                  }
              }
          }
      }
      

      BreezeQuickMenuItem.qml

      import QtQuick 2.4
      
      Item {
          id: root
          property string title: "Menu Element"
          signal clicked()
      }
      

      main.qml (main element is ApplicationWindow)

      /* some trimmed code */
      BreezeQuickMenu{
          id: brMenu
          x: 14
          y: 236
          width: 256
          height: 296
          palette: brPalette
          fontSize: 16
          BreezeQuickMenuItem{
              title: "Item 1111111111111"
              onClicked: mbox.show()
          }
          BreezeQuickMenuItem{
              title: "Item 2"
              onClicked: breezeQuickProgressBar1.indeterminate = true
          }
          BreezeQuickMenuItem{
              title: "Item 3"
              onClicked: breezeQuickProgressBar1.indeterminate = false
          }
          BreezeQuickMenuItem{
              title: "Element 4"
          }
          BreezeQuickMenuItem{
              title: "Element 5555666"
          }
      }
      /* some trimmed code */
      

      How can I set implicitWidth and implicitHeight of my custom element to actual ListView width and height? Looks like I need to define bigger width between ListView elements and set implicitWidth to it's value. But I don't know how to do it, contentWidth property won't work. Please help me to understand what can I do for finishing this goal. Full code there:

      $ git clone git://git.code.sf.net/p/breezequick/code breezequick-code

      P Offline
      P Offline
      p3c0
      Moderators
      wrote on 3 Jul 2015, 07:11 last edited by p3c0 7 Mar 2015, 07:11
      #2

      Hi @svyatoslav911512,
      The description looks quite vague. Can you elaborate it more precisely ? Please point out which custom elements are you referring. Need more description and more clearly.

      157

      1 Reply Last reply
      0
      • S Offline
        S Offline
        svyatoslav911512
        wrote on 3 Jul 2015, 08:45 last edited by
        #3

        Hi,

        I mean BreezeQuickMenu.qml as my custom element for menu and BreezeQuickMenuItem.qml as it's children elements. The idea is to set implicitWidth and implicitHeight of root Item in BreezeQuickMenu.qml to be as height of ListView (menuList) and witdth of the most wide element in ListView. Is it more clear now?

        P 1 Reply Last reply 3 Jul 2015, 10:21
        0
        • S svyatoslav911512
          3 Jul 2015, 08:45

          Hi,

          I mean BreezeQuickMenu.qml as my custom element for menu and BreezeQuickMenuItem.qml as it's children elements. The idea is to set implicitWidth and implicitHeight of root Item in BreezeQuickMenu.qml to be as height of ListView (menuList) and witdth of the most wide element in ListView. Is it more clear now?

          P Offline
          P Offline
          p3c0
          Moderators
          wrote on 3 Jul 2015, 10:21 last edited by
          #4

          @svyatoslav911512
          For that you will need to access ListView delegates. Use children property for that. Basically you will need to iterate over all the delegates of ListView , get their width and apply some logic to find greatest width of them all. Something like

          for(var child in listview.contentItem.children) {
              console.log(listview.contentItem.children[child].width)
          }
          

          157

          S 2 Replies Last reply 3 Jul 2015, 11:18
          1
          • P p3c0
            3 Jul 2015, 10:21

            @svyatoslav911512
            For that you will need to access ListView delegates. Use children property for that. Basically you will need to iterate over all the delegates of ListView , get their width and apply some logic to find greatest width of them all. Something like

            for(var child in listview.contentItem.children) {
                console.log(listview.contentItem.children[child].width)
            }
            
            S Offline
            S Offline
            svyatoslav911512
            wrote on 3 Jul 2015, 11:18 last edited by
            #5

            @p3c0 Thank you! I will try to use thid way.

            1 Reply Last reply
            0
            • P p3c0
              3 Jul 2015, 10:21

              @svyatoslav911512
              For that you will need to access ListView delegates. Use children property for that. Basically you will need to iterate over all the delegates of ListView , get their width and apply some logic to find greatest width of them all. Something like

              for(var child in listview.contentItem.children) {
                  console.log(listview.contentItem.children[child].width)
              }
              
              S Offline
              S Offline
              svyatoslav911512
              wrote on 4 Jul 2015, 00:48 last edited by
              #6

              @p3c0 said:

              @svyatoslav911512
              For that you will need to access ListView delegates. Use children property for that. Basically you will need to iterate over all the delegates of ListView , get their width and apply some logic to find greatest width of them all. Something like

              for(var child in listview.contentItem.children) {
                  console.log(listview.contentItem.children[child].width)
              }
              

              Working like a charm, thanks!

              S 1 Reply Last reply 6 Jan 2017, 10:05
              0
              • S svyatoslav911512
                4 Jul 2015, 00:48

                @p3c0 said:

                @svyatoslav911512
                For that you will need to access ListView delegates. Use children property for that. Basically you will need to iterate over all the delegates of ListView , get their width and apply some logic to find greatest width of them all. Something like

                for(var child in listview.contentItem.children) {
                    console.log(listview.contentItem.children[child].width)
                }
                

                Working like a charm, thanks!

                S Offline
                S Offline
                stcorp
                wrote on 6 Jan 2017, 10:05 last edited by
                #7

                @svyatoslav911512 said in (SOLVED) QML - How to get ListView height and width of it's children elements (possibly delegates):

                @p3c0 said:

                @svyatoslav911512
                For that you will need to access ListView delegates. Use children property for that. Basically you will need to iterate over all the delegates of ListView , get their width and apply some logic to find greatest width of them all. Something like

                for(var child in listview.contentItem.children) {
                    console.log(listview.contentItem.children[child].width)
                }
                

                Working like a charm, thanks!

                If anyone is interested, a slightly easier way is to set the implicitWidth property of the ListView to contentItem.childrenRect.width. At least that worked for me.

                ListView{
                    implicitWidth: contentItem.childrenRect.width
                }
                
                1 Reply Last reply
                9
                • M Offline
                  M Offline
                  Mertanian
                  wrote on 16 Jun 2017, 10:24 last edited by
                  #8

                  I know that the question is old, but I have found it by Google search and think it needs some attention, as accepted answer seems to be wrong.
                  @p3c0's soultion does not work for me. I get a feeling that this is a bad practice. For me model contains 17 items, but by accessing contentItem.children I can access first 16 items (on indexes 0, and 2-16). On index 1 there is something I do not know what it is, but it is not an item of my GridView.

                  What worked for me was:

                  for(var child in listview.count) {
                      listview.currentIndex = child
                      console.log(listview.currentItem.width)
                  }
                  

                  I think that this is much better (and safer) solution.

                  Crawl.WC 1 Reply Last reply 19 Feb 2020, 05:26
                  1
                  • M Mertanian
                    16 Jun 2017, 10:24

                    I know that the question is old, but I have found it by Google search and think it needs some attention, as accepted answer seems to be wrong.
                    @p3c0's soultion does not work for me. I get a feeling that this is a bad practice. For me model contains 17 items, but by accessing contentItem.children I can access first 16 items (on indexes 0, and 2-16). On index 1 there is something I do not know what it is, but it is not an item of my GridView.

                    What worked for me was:

                    for(var child in listview.count) {
                        listview.currentIndex = child
                        console.log(listview.currentItem.width)
                    }
                    

                    I think that this is much better (and safer) solution.

                    Crawl.WC Offline
                    Crawl.WC Offline
                    Crawl.W
                    wrote on 19 Feb 2020, 05:26 last edited by
                    #9

                    @Mertanian There is such a problem.

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      seyed
                      wrote on 28 Aug 2023, 10:37 last edited by
                      #10

                      If the delegates of the ListView is what you looking for, so you can set the list size from the delegate:

                      ListView {
                          id: myList
                          width: implicitWidth
                          height: implicitHeight
                          delegate: Component {
                              Rectangle {
                                  width: _col.width; height: _col.height
                                  onHeightChanged: myList.height = Math.max(myList.height, height);
                                  onWidthChanged: myList.width = Math.max(myList.width, width);
                                  Column {
                                      id: _col
                                      Text: "Salam :)"
                                  }
                              }
                          }
                      }
                      

                      This approach is more meaningful when delegates are same size and you can limit the calculation with first item (index === 0)

                      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