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



  • 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


  • Moderators

    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.



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


  • Moderators

    @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)
    }
    


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



  • @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!



  • @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
    }
    


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



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.