Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. ListView that scrolls horizontally also
Forum Update on Monday, May 27th 2025

ListView that scrolls horizontally also

Scheduled Pinned Locked Moved Solved QML and Qt Quick
7 Posts 4 Posters 3.6k Views
  • 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.
  • SeeLookS Offline
    SeeLookS Offline
    SeeLook
    wrote on last edited by
    #1

    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 }
    }
    

    Screenshot_20191012_220044.png

    1 Reply Last reply
    0
    • SeeLookS Offline
      SeeLookS Offline
      SeeLook
      wrote on last edited by
      #2

      ListView inherits from Flickable which is quite configurable for both scroll bars, but it seems like ListView locks horizontal bar, so I didn't find better solution than to 'cheat the system' :)
      and wrap ListView with Flickable and use its scrolls

      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
          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 }
        }
      }
      

      Screenshot_20191013_140419.png

      This solution is quite bearable for me, but still, maybe there is something more elegant.

      T 1 Reply Last reply
      0
      • SeeLookS SeeLook

        ListView inherits from Flickable which is quite configurable for both scroll bars, but it seems like ListView locks horizontal bar, so I didn't find better solution than to 'cheat the system' :)
        and wrap ListView with Flickable and use its scrolls

        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
            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 }
          }
        }
        

        Screenshot_20191013_140419.png

        This solution is quite bearable for me, but still, maybe there is something more elegant.

        T Offline
        T Offline
        Tom_H
        wrote on last edited by
        #3

        @SeeLook You could wrap it in a ScrollView.

        1 Reply Last reply
        1
        • Shrinidhi UpadhyayaS Offline
          Shrinidhi UpadhyayaS Offline
          Shrinidhi Upadhyaya
          wrote on last edited by Shrinidhi Upadhyaya
          #4

          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:-
          46beb47e-3a73-4304-a0a4-836854937223-image.png

          For more information about ScrollView[https://doc.qt.io/qt-5/qml-qtquick-controls2-scrollview.html]

          Shrinidhi Upadhyaya.
          Upvote the answer(s) that helped you to solve the issue.

          1 Reply Last reply
          1
          • SeeLookS Offline
            SeeLookS Offline
            SeeLook
            wrote on last edited by
            #5

            @Tom_H , @Shrinidhi-Upadhyaya , Thanks for answers.
            Wrapping ListView by ScrollView is even mentioned in the Qt docs
            Let it be.
            Thank You.

            1 Reply Last reply
            0
            • SeeLookS Offline
              SeeLookS Offline
              SeeLook
              wrote on last edited by
              #6

              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 the Flickable over the ScrollView (but it doesn't change a conclusion)
              Because when we set contentHeight: list.contentItem.height it resizes wrapping Flickable content item to size of our ListView 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 inner ListView 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 }
                }
              }
              
              1 Reply Last reply
              0
              • R Offline
                R Offline
                returnx
                wrote on last edited by
                #7

                The clear way is use flickableDirection property.
                You can set flickableDirection to the Flickable.AutoFlickIfNeeded or Flickable.HorizontalAndVerticalFlick enums.

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved