ScrollView interfering with MouseArea and/or MouseEvents
-
I have a ChartView with a Mouse area and custom script for zooming and panning on the chart. It work good on it is own but when I wrap the whole thing in a ScrollView ,(I can have arbitrarily many charts visible on the screen) it probably interferes with the mouse event handling and the scripts won't work . Below is a standalone demonstration of the problem;
import QtQuick 2.11 import QtQuick.Window 2.11 import QtCharts 2.2 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.4 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") ScrollView { id: scrollView anchors.fill : parent z : -1 clip: true; ScrollBar.vertical.policy : ScrollBar.AlwaysOn ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ChartView { id: df antialiasing: true width : Math.max (implicitWidth ,scrollView.availableWidth ) height: Math.max(implicitWidth , scrollView.availableHeight) LineSeries { name: "LineSeries" XYPoint { x: 0; y: 0 } XYPoint { x: 1.1; y: 2.1 } XYPoint { x: 1.9; y: 3.3 } XYPoint { x: 2.1; y: 2.1 } XYPoint { x: 2.9; y: 4.9 } XYPoint { x: 3.4; y: 3.0 } XYPoint { x: 4.1; y: 3.3 } } Rectangle { id: zoomRect color: "black" opacity: 0.6 visible: false } Rectangle { id: scrollRect visible: false } MouseArea { anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.AllButtons onPressed: { if (mouse.button == Qt.LeftButton) { zoomRect.x = mouseX; zoomRect.y = mouseY; zoomRect.visible = true; } else if(mouse.button == Qt.RightButton) { df.zoomReset(); } if (mouse.button == Qt.MiddleButton) { scrollRect.x = mouseX; scrollRect.y = mouseY } } onMouseXChanged: { zoomRect.width = mouseX - zoomRect.x if ((mouse.buttons & Qt.MiddleButton) == Qt.MiddleButton) { df.scrollLeft(mouseX - scrollRect.x); df.scrollUp(mouseY- scrollRect.y); scrollRect.x = mouseX; scrollRect.y = mouseY; } } onMouseYChanged: { zoomRect.height = mouseY - zoomRect.y } onReleased: { if (mouse.button == Qt.LeftButton) { df.zoomIn(Qt.rect(zoomRect.x, zoomRect.y, zoomRect.width, zoomRect.height)); zoomRect.visible = false console.log ("mouse released") console.log (zoomRect.x , zoomRect.y , zoomRect.width , zoomRect.height) } } } } } }
Without scroll view in onRelease handler of the MouseArea, it correctly prints the x,y position and the width&height of the zoom rectangle. with scroll view width&height prints out at zero and I notice a stutter when drawing the rectangle on screen.
Is there a way to disable to mouse events intercepted by the scroll view ?
Thanks in advance; -
@Diracsbracket said in ScrollView interfering with MouseArea and/or MouseEvents:
@hsolter
Scroll by wheel just works fine, even ifinteractive
is false. Interactive only concerns the flick action ofFlickable
. Have you tried?Yup I've tried it at the original code .With your modification it does not work anymore. if I remove the modification, scroll by wheel works as usual. Maybe scrolling by wheel means flicking in some sense?
-
@hsolter
Oops. My bad.
@hsolter said in ScrollView interfering with MouseArea and/or MouseEvents:Maybe scrolling by wheel means flicking in some sense?
You must be right...
When I first tried, I did it like this:
onPressed: { scrollView.contentItem.interactive = false .... } onReleased: { .... scrollView.contentItem.interactive = true }
That is what I meant with "dynamically".
This preserves the wheelscroll, but then, you must take care that the
released
event never gets stolen or lost of course. -
@Diracsbracket Yeah I see what you mean. Unfortunately in the original code charts are dynamically created and has no notion if they are embedded with scrollView or some other control. I can do that in the scrollView itself if it support handling mouse events (I am not very well versed in QML) even then I might need the sync mouse clicks across controls .
-
Hello,
i found a small solution for the mouse wheel problem by using a timerScrollView { anchors { fill: parent } Component.onCompleted: contentItem.interactive = false background: Rectangle { id: scrollViewbackgroundRect anchors.fill: parent color: "transparent" MouseArea { anchors.fill: parent property var mytimer : new Timer(scrollViewbackgroundRect); onClicked: { console.log("background clicked"); } onWheel: { console.log("enabling interactive") scrollViewTours.contentItem.interactive = true mytimer.interval = 500; mytimer.repeat = false; mytimer.triggered.connect(function () { console.log("disabling interactive") scrollViewTours.contentItem.interactive = false }) mytimer.start(); } } } }
the JS function
function Timer(parent) { return Qt.createQmlObject("import QtQuick 2.0; Timer {}", parent); }