(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
andimplicitHeight
of my custom element to actualListView
width and height? Looks like I need to define bigger width betweenListView
elements and setimplicitWidth
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
-
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
andimplicitHeight
of rootItem
in BreezeQuickMenu.qml to be as height ofListView
(menuList) and witdth of the most wide element inListView
. Is it more clear now? -
@svyatoslav911512
For that you will need to accessListView
delegates. Usechildren
property for that. Basically you will need to iterate over all the delegates ofListView
, get their width and apply some logic to find greatest width of them all. Something likefor(var child in listview.contentItem.children) { console.log(listview.contentItem.children[child].width) }
-
@p3c0 said:
@svyatoslav911512
For that you will need to accessListView
delegates. Usechildren
property for that. Basically you will need to iterate over all the delegates ofListView
, get their width and apply some logic to find greatest width of them all. Something likefor(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 accessListView
delegates. Usechildren
property for that. Basically you will need to iterate over all the delegates ofListView
, get their width and apply some logic to find greatest width of them all. Something likefor(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 accessingcontentItem.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.
-
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
)