Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. ScrollView interfering with MouseArea and/or MouseEvents
Forum Updated to NodeBB v4.3 + New Features

ScrollView interfering with MouseArea and/or MouseEvents

Scheduled Pinned Locked Moved Solved QML and Qt Quick
8 Posts 3 Posters 4.6k Views
  • 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 Offline
    H Offline
    hsolter
    wrote on last edited by
    #1

    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;

    DiracsbracketD 1 Reply Last reply
    0
    • H hsolter

      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;

      DiracsbracketD Offline
      DiracsbracketD Offline
      Diracsbracket
      wrote on last edited by Diracsbracket
      #2

      Hi @hsolter
      You can do for example:

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

      Or dynamically change interactive, etc...

      1 Reply Last reply
      2
      • H Offline
        H Offline
        hsolter
        wrote on last edited by
        #3

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

        DiracsbracketD 1 Reply Last reply
        0
        • H hsolter

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

          DiracsbracketD Offline
          DiracsbracketD Offline
          Diracsbracket
          wrote on last edited by Diracsbracket
          #4

          @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
          0
          • DiracsbracketD 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 Offline
            H Offline
            hsolter
            wrote on last edited by hsolter
            #5

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

            DiracsbracketD 1 Reply Last reply
            0
            • H 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?

              DiracsbracketD Offline
              DiracsbracketD Offline
              Diracsbracket
              wrote on last edited by Diracsbracket
              #6

              @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
              0
              • DiracsbracketD 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 Offline
                H Offline
                hsolter
                wrote on last edited by
                #7

                @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
                0
                • A Offline
                  A Offline
                  Aghiles Gharbi
                  wrote on last edited by
                  #8

                  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
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved