Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Call for Presentations - Qt World Summit

    Solved ScrollView interfering with MouseArea and/or MouseEvents

    QML and Qt Quick
    3
    8
    3057
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      hsolter last edited by

      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 1 Reply Last reply Reply Quote 0
      • Diracsbracket
        Diracsbracket @hsolter last edited by Diracsbracket

        Hi @hsolter
        You can do for example:

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

        Or dynamically change interactive, etc...

        1 Reply Last reply Reply Quote 2
        • H
          hsolter last edited by

          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??

          Diracsbracket 1 Reply Last reply Reply Quote 0
          • Diracsbracket
            Diracsbracket @hsolter last edited by Diracsbracket

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

            H 1 Reply Last reply Reply Quote 0
            • H
              hsolter @Diracsbracket last edited by hsolter

              @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?

              Diracsbracket 1 Reply Last reply Reply Quote 0
              • Diracsbracket
                Diracsbracket @hsolter last edited by Diracsbracket

                @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.

                H 1 Reply Last reply Reply Quote 0
                • H
                  hsolter @Diracsbracket last edited by

                  @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 .

                  1 Reply Last reply Reply Quote 0
                  • A
                    Aghiles Gharbi last edited by

                    Hello,
                    i found a small solution for the mouse wheel problem by using a timer

                    ScrollView {
                    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);
                    }
                    
                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post