Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Unsolved QML: Horizontal ScrollBar on ListView

    QML and Qt Quick
    3
    8
    990
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      Bob64 last edited by Bob64

      I want to display a ListView containing strings (e.g. using Labels) that are usually of a reasonable length but can occasionally be longer than the maximum width I want to make the ListView. 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 wrapping ListView in a ScrollView, 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
                  }
              }
          }
      }
      
      
      1 Reply Last reply Reply Quote 0
      • dheerendra
        dheerendra Qt Champions 2022 last edited by

        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
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

        B 1 Reply Last reply Reply Quote 1
        • B
          Bob64 @dheerendra last edited by

          @dheerendra Thanks. Can you please explain what you mean about "scrolling text feature"?

          dheerendra 1 Reply Last reply Reply Quote 0
          • dheerendra
            dheerendra Qt Champions 2022 @Bob64 last edited by

            @Bob64

            Scrolling Text - Adding animation to move the text from left to right.

            Dheerendra
            @Community Service
            Certified Qt Specialist
            http://www.pthinks.com

            B 1 Reply Last reply Reply Quote 0
            • B
              Bob64 @dheerendra last edited by

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

              1 Reply Last reply Reply Quote 0
              • KH-219Design
                KH-219Design last edited by

                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.

                www.219design.com
                Software | Electrical | Mechanical | Product Design

                1 Reply Last reply Reply Quote 0
                • KH-219Design
                  KH-219Design last edited by

                  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 a ScrollView).

                  Therefore the ListView supports properties such as flickableDirection which are inherited from Flickable. (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 that contentWidth is wider than what fits in the ListView's actual width.
                  • For VerticalFlick, the content will not scroll/flick unless you ensure that contentHeight is taller than what fits in the ListView'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 hardcoding 500, but that is a separate exercise in QML computation.

                  www.219design.com
                  Software | Electrical | Mechanical | Product Design

                  B 1 Reply Last reply Reply Quote 1
                  • B
                    Bob64 @KH-219Design last edited by

                    @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 using TextMetrics but it has to be said that I am getting rather unreliable values from it. But that might be another question...

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post