Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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;



  • Hi @hsolter
    You can do for example:

        ScrollView
        {
            id: scrollView
             ...
            Component.onCompleted: contentItem.interactive = false
           ....
        }
    

    Or dynamically change interactive, etc...



  • Wow. Works like a charm. of course in that case I can't scroll by mouse wheel and have to
    scroll by moving the vertical scroll bar. I wonder that's the right way??



  • @hsolter
    Scroll by wheel just works fine, even if interactive is false. Interactive only concerns the flick action of Flickable. Have you tried?



  • @Diracsbracket said in ScrollView interfering with MouseArea and/or MouseEvents:

    @hsolter
    Scroll by wheel just works fine, even if interactive is false. Interactive only concerns the flick action of Flickable. 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 .


Log in to reply