How make QML ListView not flickable?

4.2k Views Asked by At

I was wondering if there's any way for ListView to behave like a desktop control and not react with scrolling to mouse dragging?

I know about the interactive property, but I still want the ListView to react to clicks, mouse wheel, arrow keys, and have a ScrollBar.

2

There are 2 best solutions below

3
On BEST ANSWER

For starters, setting interactive to false will pretty much immobilize the view.

There is a keyNavigationEnabled property which doesn't seem to work at this moment(this critical bug).

So will need to do a little extra work to get it to work as you want:

  MouseArea {
    anchors.fill: ll
    onWheel: ll.flick(0, wheel.angleDelta.y * 5)
  }
  ListView {
    id: ll
    model: 50
    width: 50
    height: 200
    spacing: 5
    focus: true
    interactive: false
    boundsBehavior: Flickable.StopAtBounds
    Keys.onPressed: {
      if (event.key === Qt.Key_Up) flick(0, 500)
      else if (event.key === Qt.Key_Down) flick(0, -500)
    }
    delegate: Rectangle {
      width: 50
      height: 50
      color: "red"
      MouseArea {
        anchors.fill: parent
        onClicked: console.log("clicked")
      }
    }
  }

Interactivity is disabled, key navigation is implemented manually, and a background MouseArea is used to capture wheel events. Note that you don't have to do anything special to enable clicking on items for a non-interactive view, it works regardless of the view is interactive or not.

0
On

Adding DragHandler with a target: null prevents it being dragged with the mouse:

import QtQuick 2.12

ListView {
    DragHandler {
        target: null
    }
}

If you've got MouseArea in the child items of ListView / GridView then you've got to also patch the MouseAreas like that:

MouseArea {
    drag.target: Item {}
    DragHandler {}
}

Otherwise it somehow propagates and drags the flickable.

Works in Qt 6.6. Maybe someone has an explanation for the logic of this.