QML: Horizontal ScrollBar on ListView
-
I want to display a ListView containing strings (e.g. using
Label
s) that are usually of a reasonable length but can occasionally be longer than the maximum width I want to make theListView
. When this happens, the text is clipped to the right and the user has no way to see the missing characters.A horizontal scrollbar seems like the obvious solution here but I cannot get it to work. I have tried attaching a horizontal scrollbar to
ListView
, I have tried wrappingListView
in aScrollView
, setting all sorts of combinations of widths, implicit widths, content widths ...Is it possible to use a horizontal scrollbar for the situation I have described?
Let's say we start with something like this:
import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Window 2.2 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") function getItems() { var items = []; for (var i = 0; i !== 20; ++i) { items[i] = "This string is too long to fit in my ListView!"; } return items; } Rectangle { anchors.centerIn: parent height: 200 width: 100 border.color: "black" ListView { anchors.fill: parent model: getItems() clip: true delegate: Label { text: modelData } } } }
-
ScrollBar may not be right option. Use elide feature for the labels in the delegate. Use tooltip feature/scrolling text feature when particular delegate is selected.
-
@dheerendra Thanks. Can you please explain what you mean about "scrolling text feature"?
-
Scrolling Text - Adding animation to move the text from left to right.
-
@dheerendra is there a straighforward way to control the positioning of long text within a shorter label? I suppose I could take substrings but is there a better way?
-
I will attempt to launch and tweak your QML code later today (presuming i get a moment). I'm curious why a horizontal bar would not work (although the gymnastics might not be worth it in the end).
Just to put forth more options:
fontSizeMode: Text.Fit
https://doc.qt.io/qt-5/qml-qtquick-text.html#fontSizeMode-prop
In addition to the elision options, I have (on occasion) used
fontSizeMode: Text.Fit
, which will shrink the text only when necessary to make it fit. However, this will result in the sometimes jarring visual discrepancy of the short strings being in a larger font, and the long strings being in a smaller font. -
Here is a "partial solution" that gives you scrollability (but not a visible scrollbar) by adding two lines of code inside your
ListView
.I am testing all this with Qt 5.15.0 on Linux.
The key thing to realize up front is that
ListView
"is a"Flickable
(which is similar to aScrollView
).Therefore the
ListView
supports properties such asflickableDirection
which are inherited fromFlickable
. (Go to https://doc.qt.io/qt-5/qml-qtquick-listview.html and search "Inherits".)To make the whole
ListView
"scrollable" (aka "flickable"), you can add the lines shown below.On a touch screen, you will then be able to swipe/drag to "scroll" the content horizontally. On a desktop computer (without a touchscreen), you can click-and-drag the content.
IMPORTANT:
- For
HorizontalFlick
, the content will not scroll/flick unless you ensure thatcontentWidth
is wider than what fits in theListView
's actual width. - For
VerticalFlick
, the content will not scroll/flick unless you ensure thatcontentHeight
is taller than what fits in theListView
's actual height.
ListView { anchors.fill: parent model: getItems() clip: true contentWidth: 500 // 1 of 2 newly inserted lines of code flickableDirection: Flickable.HorizontalFlick // 2 of 2 newly inserted lines of code delegate: Label { text: modelData } }
You can see that in the interest of time and simplicity, I hardcoded
contentWidth: 500
in the above sample code. It would be nicer to compute the necessary width for the longest piece of text instead of hardcoding500
, but that is a separate exercise in QML computation. - For
-
@KH-219Design Thank you very much for this. It's certainly another option to consider.
BTW regarding the
contentWidth
I am already doing work in my real application to attempt to calculate the longest label length. I am usingTextMetrics
but it has to be said that I am getting rather unreliable values from it. But that might be another question...