0
votes

This post is a copy of a message I already sent on the Qt forum but I couldn't get an answer. You can find the original post here: https://forum.qt.io/topic/113890/prevent-mousearea-s-positionchanged-signal-to-propagate-in-scrollview/4

If the link is dead, everything is copied below:


I am trying to handle a positionChanged signal in a MouseArea (to create kind of a drag&drop effet) that is in a ScrollView.

My problem is that after the mouse travelled a short distance, the parent ScrollView seem's to get the focus (the scrollbar appears) and I stop to receive positionChanged signals.

The objective would be to receive the positionChanged signal (even if the mouse gets out of my MouseArea & over the ScrollView as long as my left mouse button stays pressed) without propagating the signal to the ScrollView.

I have 3 separate examples. This is a simple QML application that should be easy to run. The two first examples work. The third does not work.

What is "working":

  1. Press the mouse button down on the MouseArea
  2. Move the mouse around without releasing the button
  3. The message that logs coordinates should never stop printing, wherever you are on screen until you release the mouse button.

For the third example, I get logs until the mouse moves too much and all the updates stop.

  1. Only ScrollView (works)
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

ApplicationWindow{
    id: root
    visible: true
    width: 1200
    height: 600

    ScrollView {
        clip: true
        anchors.fill: parent

        MouseArea {
            width: 300
            height: 300

            onPositionChanged: {
                console.log('Moved', mouseX, mouseY)
            }
        }
    }
}
  1. Only ColumnLayout (works)
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

ApplicationWindow{
    id: root
    visible: true
    width: 1200
    height: 600

    ColumnLayout {
        MouseArea {
            width: 300
            height: 300

            onPositionChanged: {
                console.log('Moved', mouseX, mouseY)
            }
        }
    }
}
  1. ColumnLayout inside a ScrollView (does not work)
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

ApplicationWindow {
    id: root
    visible: true
    width: 1200
    height: 600

    ScrollView {
        clip: true
        anchors.fill: parent

                // note: It does not work for ColumnLayout, Column, Row or RowLayout. If I use a Item here, it works
        ColumnLayout {
            MouseArea {
                width: 300
                height: 300

                onPositionChanged: {
                    console.log('Moved', mouseX, mouseY)
                }
            }
        }
    }
}

You can find a video of the behavior here: https://i.imgur.com/rIlWnhu.mp4

  1. I press and release the mouse without moving: I get the pressed & released events correctly
  2. I press and move the mouse: I get the pressed event, the move event, then it stops. No more move or released events.
  3. I press and move the mouse without going too far from the position where I pressed the mouse: It works until I get too far Note: I don't get any Released or Exited event, but the containsPressed property is correctly updated (ie: when I no longer receive events, its value is false). This is the property that I use to display the "Mouse pressed" text.

Is this something I do wrong with the ScrollView/ColumnLayout combo or is this a Qt bug ?

1

1 Answers

1
votes

Add this to your MouseArea in your third example:

    preventStealing: true

For more info see:

https://doc.qt.io/qt-5/qml-qtquick-mousearea.html#preventStealing-prop