Qt6, QML: Нет горизонтальной полосы прокрутки при использовании ListView
Есть модель со списком путей к картинкам которые потом отображаются через ListView, но если ширина картинки больше окна, то горизонтальная полоса прокрутки не появляется.
UPD: Если у ListView вручную установить значение в свойствве contentWidth, то полоса прокрутки появляется. Не понятно почему это свойство никак не меняется при наличии элементов в ListView.
UPD2: Нашел в доке следующее, похоже что нужно в ручную вычислить максимальную ширину всех существующих элементов в ListView и установить её в contentWidth
Component {
id: imageDelegate
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
Image {
Layout.alignment: Qt.AlignHCenter
source: display
}
}
}
ScrollView {
id: scrollView
anchors.fill: parent
ListView {
id: listView
boundsBehavior: Flickable.StopAtBounds
boundsMovement: Flickable.StopAtBounds
flickDeceleration: 100000
model: stringListModel
delegate: imageDelegate
}
}
Ответы (1 шт):
Проблема связана прежде всего с тем, что ListView переиспользует делегаты для экономии памяти, либо уничтожает невидимые в текущий момент. Таким образом, ширину всех делегатов в модели (если она не помещается в виджет) он знать не может, и по этой же причине вы не сможите её узнать. Поэтому при скроле у вас ширина будет скакать. Если у вас не тысячи элементов и overhead позволяет, то смело используйте связку Flickable+ColumnLayout+ListModel:
Flickable {
contentWidth: layout.implicitWidth
contentHeight: layout.implicitHeight
contenmtItem: ColumnLayout {
id: layout
Repeater {
model: ListModel { id: model }
delegate: Item { }
}
}
}
Ещё удобнее будет сделать вспомогательный элемент и передавать в него Item снаружи через свойство:
property Item degelgateItem: null
Если вам нужно обязательно задавать ширину динамически, но при этом использовать ListView для экономичности, то просто создайте маппер:
property var mapper: new Map()
function setWidth(rowId,iWidth) {
mapper.set(rowId,iWidth);
let maxWidth = 0;
for (const [id,width] of mapper)
maxWidth = Math.max(maxWidth,width);
view.contentWidth = maxWidth;
}
Item {
id: delegate
Component.onCompleted: setWidth(rowId,implicitWidth)
onImplicitWidthChanged: setWidth(rowId,implicitWidth)
}
Что при этом использовать в качестве rowId - решать вам. В любом случае, должно быть свойство, по которому можно определить уникальносить делегата без привязки к модели.