Solved ListView that scrolls horizontally also
-
Hi,
How to achieve such a thing?
When I have delegate that its width is greater than available list width?
Unfortunately only vertical scroll bar appears:ListView { id: list width: 300; height: 600 model: 20 delegate: Rectangle { width: list.width * 1.8; height: 100 border { width: 1; color: "black"} Text { anchors.centerIn: parent text: (index + 1) + ". delegate" } } ScrollBar.vertical: ScrollBar { active: true; visible: true } ScrollBar.horizontal: ScrollBar { active: true; visible: true } }
-
ListView
inherits fromFlickable
which is quite configurable for both scroll bars, but it seems likeListView
locks horizontal bar, so I didn't find better solution than to 'cheat the system' :)
and wrapListView
withFlickable
and use its scrollsColumn { width: 300; height: 600 property real sc: 1.0 Row { id: buttRow spacing: 10 Button { icon.name: "zoom-in"; onClicked: sc = Math.min(2.0, sc * 1.125) } Button { icon.name: "zoom-out"; onClicked: sc = Math.max(0.5, sc * 0.888889) } Text { text: "Zoom: " + sc; anchors.verticalCenter: parent.verticalCenter } } Flickable { id: fl width: parent.width; height: parent.height - buttRow.height contentWidth: width * sc contentHeight: list.contentItem.height clip: true ListView { id: list width: fl.width * sc; height: parent.height model: 20 delegate: Rectangle { width: list.width; height: 100 border { width: 1; color: "black"} Text { anchors.centerIn: parent text: (index + 1) + ". delegate" } } } ScrollBar.horizontal: ScrollBar { active: true; visible: true } ScrollBar.vertical: ScrollBar { active: true; visible: true } } }
This solution is quite bearable for me, but still, maybe there is something more elegant.
-
@SeeLook You could wrap it in a
ScrollView
. -
Hi @SeeLook , you can use a ScrollView
Here is a sample code:-
ScrollView { width: 200 height: 200 clip: true ColumnLayout { anchors.fill: parent Repeater { model: 10 delegate: Rectangle { width: 400; height: 100 border { width: 1; color: "black"} Text { anchors.centerIn: parent text: (index + 1) + ". delegate" } } } } }
Sample Output:-
For more information about ScrollView[https://doc.qt.io/qt-5/qml-qtquick-controls2-scrollview.html]
-
@Tom_H , @Shrinidhi-Upadhyaya , Thanks for answers.
WrappingListView
byScrollView
is even mentioned in the Qt docs
Let it be.
Thank You. -
Not that fast...
It is not so clear as it looks like.As I wrote,
Repeater
is not sufficient due to number of delegates to be created.
And for my purposes I decided to use theFlickable
over theScrollView
(but it doesn't change a conclusion)
Because when we setcontentHeight: list.contentItem.height
it resizes wrappingFlickable
content item to size of ourListView
content item, so the list have a space to create all one million delegates at once.
No good...But below is the remedy: wrapping
Flickable
handles horizontal scrolling when innerListView
behaves its way, using only vertical scroll.Column { width: 300; height: 600 property real sc: 1.0 Row { id: buttRow spacing: 10 Button { icon.name: "zoom-in"; onClicked: sc = Math.min(2.0, sc * 1.125) } Button { icon.name: "zoom-out"; onClicked: sc = Math.max(0.5, sc * 0.888889) } Text { text: "Zoom: " + sc; anchors.verticalCenter: parent.verticalCenter } } Flickable { id: fl width: parent.width; height: parent.height - buttRow.height contentWidth: width * sc // contentHeight: list.contentItem.height // no good clip: true ListView { id: list width: fl.width * sc; height: parent.height model: 20 delegate: Rectangle { width: list.width; height: 100 * sc border { width: 1; color: "black"} Text { anchors.centerIn: parent text: (index + 1) + ". delegate" } } ScrollBar.vertical: ScrollBar { active: true; visible: true } } ScrollBar.horizontal: ScrollBar { active: true; visible: true } } }
-
The clear way is use flickableDirection property.
You can set flickableDirection to the Flickable.AutoFlickIfNeeded or Flickable.HorizontalAndVerticalFlick enums.