Juha Untinen
Juha Untinen

Reputation: 1887

TestCase mouseDrag only clicks item inside Flickable but does not drag

In a QML TestCase, I'm trying to setup automatic scrolling of a ListView that is contained inside a Flickable (to add a custom footer that can be flicked into view, which wouldn't happen with just ListView { footer: Component {} })

However, the mouseDrag only seems to click the correct coordinate, but not drag it to any direction. Here is a simplified version that is as close to the real one as possible:

Implementation.qml

import QtQuick 2.5

FocusScope {
    width: 1920
    height: 1080

    Flickable {
        objectName: 'flickableList'
        boundsBehavior: Flickable.StopAtBounds
        clip: true
        width: parent.width
        height: 240
        contentHeight: 500

        ListView {
            interactive: false
            height: parent.height
            width: parent.width

            model: ['example1', 'example2', 'example3', 'example4', 'example5']
            delegate: Item {
                width: 300
                height: 100
                Text {
                    text: modelData
                }
            }
        }
    }

    Item {
        id: footer
        height: 100
        width: parent.width
    }
}

TheTest.qml

// The relevant part
var theList = findChild(getView(), 'flickableList')
var startY = 220
var endY = 20
mouseDrag(theList, 100, startY, 100, endY, Qt.LeftButton, Qt.NoModifier, 100)

So, when I'm viewing the UI testrunner, I can see it clearly click on the correct delegate (it has a focus highlight in the actual implementation), ie. the third item "example3", which starts at Y 200 and ends at Y 300). But the drag event never happens. Nothing moves on the screen, and compare(theList.contentY, 200) says it is still at position 0. I would expect it to be at 200, since the mouse is supposed to be mouseDragging from position 220 to 20, ie. scrolling the list down by 200. And 220 is also within the visible height (240).

Just to be sure, I also reversed the Y values, but also no movement:

var theList = findChild(getView(), 'flickableList')
var startY = 20
var endY = 220
mouseDrag(theList, 100, startY, 100, endY, Qt.LeftButton, Qt.NoModifier, 100)

Also, as the 3rd item clearly is clicked on (it gets highlighted), the passed item theList (= the Flickable), should be valid.

Edit: Oh, and this does scroll the list, but it goes all the way to the bottom of the list (388 px down in the actual implementation, even when the delta is just 30 pixels):

mousePress(theList, startX, startY)
mouseMove(theList, endX, endY)
mouseRelease(theList, endX, endY)

So the question is:

Does mouseDrag only work for specific types of components (ie. does not work on Flickable?), or is there something missing? How can I get it to scroll the list down? Thanks!

Upvotes: 1

Views: 387

Answers (2)

Mitch
Mitch

Reputation: 24416

Your tag says you're using Qt 5.5 - I would recommend trying Qt 5.14 if possible, as there was a fix that might help:

mouseDrag(): ensure that intermediate moves are done for all drags

[...]

In practice, this means that mouseDrag() never did intermediate moves (i.e. what happens during a drag in real life) for drags that go from right to left or upwards.

https://codereview.qt-project.org/c/qt/qtdeclarative/+/281903

If that doesn't help, or upgrading is not an option, I would recommend looking at Qt's own tests (although they are written in C++):

https://code.qt.io/cgit/qt/qtdeclarative.git/tree/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp#n1150

Upvotes: 1

Marco Medri
Marco Medri

Reputation: 304

I think mouseDrag only works for mouse area. You could wrap every object with that. But in the end, you need to use a mouse area inside you delegate and Drag and Drop it.

https://doc.qt.io/qt-5/qml-qtquick-drag.html

import QtQuick 2.5

FocusScope {
    width: 1920
    height: 1080

    Flickable {
        objectName: 'flickableList'
        boundsBehavior: Flickable.StopAtBounds
        clip: true
        width: parent.width
        height: 240
        contentHeight: 500

        ListView {
            interactive: false
            height: parent.height
            width: parent.width

            model: ['example1', 'example2', 'example3', 'example4', 'example5']
            delegate: DelegateList{
                textAreaText = modelData
            }
        }
    }

    Item {
        id: footer
        height: 100
        width: parent.width
    }
}

And the DelegateList.qml

Item {
    id: root

    property alias textAreaText: textArea.text

    width: 300
    height: 100
    Text {
        id: textArea
    }

    Drag.active: dragArea.drag.active
    Drag.hotSpot.x: 10
    Drag.hotSpot.y: 10

    MouseArea {
        id: dragArea
        anchors.fill: parent

        drag.target: parent
    }
}

Upvotes: 0

Related Questions