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. MouseArea hides ChartView Series signals
Forum Updated to NodeBB v4.3 + New Features

MouseArea hides ChartView Series signals

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
15 Posts 4 Posters 1.7k Views 1 Watching
  • 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.
  • J Offline
    J Offline
    jay1
    wrote on last edited by jay1
    #2

    'MouseArea' composed events include "Clicked", "DoubleClicked" and "PressAndHold" [ONLY]. Hover is not considered to be a composed event (Correct me if I am wrong).

    One other important point to look at is the "OnClicked" function for "MouseArea" and "PieSeries/LineSeries". Here I considered the example of "PieSeries"

    MouseArea -> "onClicked(mouse)"
    PieSeries -> "onClicked(slice)"

    so there is a difference in the meaning of the function arguments.

    "propagateCompositeEvents" parameter when set "TRUE" works as expected.

    Sample Code can be checked below where the mouse right click is used by the "MouseArea" and mouse left click is propagated to the "PieSeries" as expected.

        ChartView
        {
            title: "Charts"
            anchors.fill: parent
            antialiasing: true
            id: seriesChart
            theme: ChartView.ChartThemeLight
    
            MouseArea
            {
                id: chartMouseArea
                anchors.fill: parent
                propagateComposedEvents: true
                acceptedButtons: Qt.RightButton
                onClicked:
                {
                    console.log("Mouse Area Clicked")
                }
                hoverEnabled: false
            }
    
            PieSeries {
                id: pieSeriesChart
                property int sliceIndex : 0
                PieSlice { label: "First Pie"; value: 45; onClicked: { pieSeriesChart.sliceIndex = 0; console.log("First Pie Clicked");} }
                PieSlice { label: "Second Pie"; value: 270; onClicked: { pieSeriesChart.sliceIndex = 1; console.log("Second Pie Clicked");} }
                PieSlice { label: "Third Pie"; value: 45; onClicked: { pieSeriesChart.sliceIndex = 2; console.log("Third Pie Clicked");}  }
                onClicked:
                {
                    for(var i = 0; i < pieSeriesChart.count; i++)
                        pieSeriesChart.at(i).exploded = false
                    pieSeriesChart.at(sliceIndex).exploded = true
                    console.log("PieSeries Clicked")
                }
                onHovered:
                {
                    console.log("Pie Slice Hovered")
                }
            }
        }
    

    Debug Log:

    qml: Pie Slice Hovered
    qml: Mouse Area Clicked
    qml: Pie Slice Hovered
    qml: Third Pie Clicked
    qml: PieSeries Clicked
    qml: Pie Slice Hovered
    qml: First Pie Clicked
    qml: PieSeries Clicked
    qml: Pie Slice Hovered
    

    Reference Image:

    Saa2.png

    S 1 Reply Last reply
    1
    • J jay1

      'MouseArea' composed events include "Clicked", "DoubleClicked" and "PressAndHold" [ONLY]. Hover is not considered to be a composed event (Correct me if I am wrong).

      One other important point to look at is the "OnClicked" function for "MouseArea" and "PieSeries/LineSeries". Here I considered the example of "PieSeries"

      MouseArea -> "onClicked(mouse)"
      PieSeries -> "onClicked(slice)"

      so there is a difference in the meaning of the function arguments.

      "propagateCompositeEvents" parameter when set "TRUE" works as expected.

      Sample Code can be checked below where the mouse right click is used by the "MouseArea" and mouse left click is propagated to the "PieSeries" as expected.

          ChartView
          {
              title: "Charts"
              anchors.fill: parent
              antialiasing: true
              id: seriesChart
              theme: ChartView.ChartThemeLight
      
              MouseArea
              {
                  id: chartMouseArea
                  anchors.fill: parent
                  propagateComposedEvents: true
                  acceptedButtons: Qt.RightButton
                  onClicked:
                  {
                      console.log("Mouse Area Clicked")
                  }
                  hoverEnabled: false
              }
      
              PieSeries {
                  id: pieSeriesChart
                  property int sliceIndex : 0
                  PieSlice { label: "First Pie"; value: 45; onClicked: { pieSeriesChart.sliceIndex = 0; console.log("First Pie Clicked");} }
                  PieSlice { label: "Second Pie"; value: 270; onClicked: { pieSeriesChart.sliceIndex = 1; console.log("Second Pie Clicked");} }
                  PieSlice { label: "Third Pie"; value: 45; onClicked: { pieSeriesChart.sliceIndex = 2; console.log("Third Pie Clicked");}  }
                  onClicked:
                  {
                      for(var i = 0; i < pieSeriesChart.count; i++)
                          pieSeriesChart.at(i).exploded = false
                      pieSeriesChart.at(sliceIndex).exploded = true
                      console.log("PieSeries Clicked")
                  }
                  onHovered:
                  {
                      console.log("Pie Slice Hovered")
                  }
              }
          }
      

      Debug Log:

      qml: Pie Slice Hovered
      qml: Mouse Area Clicked
      qml: Pie Slice Hovered
      qml: Third Pie Clicked
      qml: PieSeries Clicked
      qml: Pie Slice Hovered
      qml: First Pie Clicked
      qml: PieSeries Clicked
      qml: Pie Slice Hovered
      

      Reference Image:

      Saa2.png

      S Offline
      S Offline
      St.Stanislav
      wrote on last edited by St.Stanislav
      #3

      @jay1 Thank you again for your replies! I have tested your code and it's working well, but not exactly what I need. Can I use only one certain button to detect both events? I mean clicking left button leads to MouseArea and PieSeries onClicked events. Otherwise, if I could choose button for Series clicking event (e.g. Middle button), it would be nice too.

      I have also noticed that onHovered event is working well (over mouseArea and Series).

      R 1 Reply Last reply
      0
      • S St.Stanislav

        @jay1 Thank you again for your replies! I have tested your code and it's working well, but not exactly what I need. Can I use only one certain button to detect both events? I mean clicking left button leads to MouseArea and PieSeries onClicked events. Otherwise, if I could choose button for Series clicking event (e.g. Middle button), it would be nice too.

        I have also noticed that onHovered event is working well (over mouseArea and Series).

        R Offline
        R Offline
        rhb327
        wrote on last edited by
        #4

        @St-Stanislav I have a similar issue. I have the MouseArea setup to pass events but in my case a QScatterSeries is not picking up what should be a propaged onClicked. Were you able to resolve?

        fcarneyF 1 Reply Last reply
        0
        • R rhb327

          @St-Stanislav I have a similar issue. I have the MouseArea setup to pass events but in my case a QScatterSeries is not picking up what should be a propaged onClicked. Were you able to resolve?

          fcarneyF Offline
          fcarneyF Offline
          fcarney
          wrote on last edited by
          #5

          @rhb327 Wouldnt you set the accepted flag in the mousearea event based upon if you consumed that event or not?

          MouseArea {
              onClicked: {
                  var consumed = condition; // some condition
                  if(consumed)
                      mouse.accepted = true
                  else
                      mouse.accepted = false // will propagate event to underlying items
              }
          }
          

          C++ is a perfectly valid school of magic.

          R 1 Reply Last reply
          0
          • fcarneyF fcarney

            @rhb327 Wouldnt you set the accepted flag in the mousearea event based upon if you consumed that event or not?

            MouseArea {
                onClicked: {
                    var consumed = condition; // some condition
                    if(consumed)
                        mouse.accepted = true
                    else
                        mouse.accepted = false // will propagate event to underlying items
                }
            }
            
            R Offline
            R Offline
            rhb327
            wrote on last edited by
            #6

            @fcarney yeah, that's what I'm trying to do...here's my mousearea:

             MouseArea {
                            anchors.fill: chartView
                            propagateComposedEvents: true
                            property int lastX: 0
                            property int lastY: 0
                            acceptedButtons: Qt.AllButtons
            
                            onClicked: {
                                console.log("YADA1")
                                mouse.accepted = false
                            }
                            onReleased: {
                                if (mouse.button === Qt.LeftButton) {
                                    rep_iconOverLay.model=0
                                    if (lastX !== mouse.x) {
                                        chartView.scrollRight(lastX - mouse.x);
                                        lastX = mouse.x;
                                    }
                                    if (lastY !== mouse.y) {
                                        chartView.scrollDown(lastY - mouse.y);
                                        lastY = mouse.y;
                                    }
                                    rep_iconOverLay.model=chartView.alarmTimeData
                                }
                                else if (mouse.button === Qt.RightButton) {
                                    rep_iconOverLay.model=0
                                    chartView.zoomIn(Qt.rect(zoomRect.x, zoomRect.y, zoomRect.width, zoomRect.height));
                                    zoomRect.visible = false
                                    chartView.pressed=false
                                    rep_iconOverLay.model=chartView.alarmTimeData
                                }
                                mouse.accepted = true
                            }
                            onDoubleClicked: {
                                rep_iconOverLay.model=0
                                chartView.zoomReset()
                                timeAxis.min = xMinn
                                timeAxis.max = xMaxx
                                tempAxis.min = yMinn
                                tempAxis.max = yMaxx
                                rep_iconOverLay.model=chartView.alarmTimeData
                                mouse.accepted = true
                            }
                            onPressed: {
                                if (mouse.button === Qt.LeftButton) {
                                    lastX = mouse.x;
                                    lastY = mouse.y;
                                }
                                else if (mouse.button === Qt.RightButton){
                                    chartView.pressed = false
                                    zoomRect.x = mouse.x
                                    zoomRect.y = mouse.y
                                    zoomRect.visible = true
                                }
                                mouse.accepted = false
                            }
                            onMouseXChanged: {
                                zoomRect.width = mouse.x - zoomRect.x;
                                mouse.accepted = true
                            }
                            onMouseYChanged: {
                                zoomRect.height = mouse.y - zoomRect.y;
                                mouse.accepted = true
                            }
                        }
            
            

            But the series never seems to get the onClick!

             onClicked: {
                                console.log("YADA2")
                                toolTipAlarm.visible=true
                                var pnt = chartView.mapToPosition(point, scatterSeries)
                                toolTipAlarm.x = pnt.x
                                toolTipAlarm.y = pnt.y
            
                                var stepCount=0
                                for(var i=0 ;i<stepDataArray.length; ++i) {
                                    if(parseFloat(stepDataArray[i]).toFixed(3)===point.x.toFixed(3)) {
                                        stepCount = i
                                        break
                                    }
                                }
                                console.log("SDA:", stepDataArray, point.x.toFixed(3), stepCount)
                                toolTipAlarm.text = qsTrId("Step: ") + parseInt(stepCount+1) + " | " + point.x.toFixed(3)
                            }
                            onPressed: {
                                console.log("YADA3")
                            }
            
            fcarneyF 1 Reply Last reply
            0
            • R rhb327

              @fcarney yeah, that's what I'm trying to do...here's my mousearea:

               MouseArea {
                              anchors.fill: chartView
                              propagateComposedEvents: true
                              property int lastX: 0
                              property int lastY: 0
                              acceptedButtons: Qt.AllButtons
              
                              onClicked: {
                                  console.log("YADA1")
                                  mouse.accepted = false
                              }
                              onReleased: {
                                  if (mouse.button === Qt.LeftButton) {
                                      rep_iconOverLay.model=0
                                      if (lastX !== mouse.x) {
                                          chartView.scrollRight(lastX - mouse.x);
                                          lastX = mouse.x;
                                      }
                                      if (lastY !== mouse.y) {
                                          chartView.scrollDown(lastY - mouse.y);
                                          lastY = mouse.y;
                                      }
                                      rep_iconOverLay.model=chartView.alarmTimeData
                                  }
                                  else if (mouse.button === Qt.RightButton) {
                                      rep_iconOverLay.model=0
                                      chartView.zoomIn(Qt.rect(zoomRect.x, zoomRect.y, zoomRect.width, zoomRect.height));
                                      zoomRect.visible = false
                                      chartView.pressed=false
                                      rep_iconOverLay.model=chartView.alarmTimeData
                                  }
                                  mouse.accepted = true
                              }
                              onDoubleClicked: {
                                  rep_iconOverLay.model=0
                                  chartView.zoomReset()
                                  timeAxis.min = xMinn
                                  timeAxis.max = xMaxx
                                  tempAxis.min = yMinn
                                  tempAxis.max = yMaxx
                                  rep_iconOverLay.model=chartView.alarmTimeData
                                  mouse.accepted = true
                              }
                              onPressed: {
                                  if (mouse.button === Qt.LeftButton) {
                                      lastX = mouse.x;
                                      lastY = mouse.y;
                                  }
                                  else if (mouse.button === Qt.RightButton){
                                      chartView.pressed = false
                                      zoomRect.x = mouse.x
                                      zoomRect.y = mouse.y
                                      zoomRect.visible = true
                                  }
                                  mouse.accepted = false
                              }
                              onMouseXChanged: {
                                  zoomRect.width = mouse.x - zoomRect.x;
                                  mouse.accepted = true
                              }
                              onMouseYChanged: {
                                  zoomRect.height = mouse.y - zoomRect.y;
                                  mouse.accepted = true
                              }
                          }
              
              

              But the series never seems to get the onClick!

               onClicked: {
                                  console.log("YADA2")
                                  toolTipAlarm.visible=true
                                  var pnt = chartView.mapToPosition(point, scatterSeries)
                                  toolTipAlarm.x = pnt.x
                                  toolTipAlarm.y = pnt.y
              
                                  var stepCount=0
                                  for(var i=0 ;i<stepDataArray.length; ++i) {
                                      if(parseFloat(stepDataArray[i]).toFixed(3)===point.x.toFixed(3)) {
                                          stepCount = i
                                          break
                                      }
                                  }
                                  console.log("SDA:", stepDataArray, point.x.toFixed(3), stepCount)
                                  toolTipAlarm.text = qsTrId("Step: ") + parseInt(stepCount+1) + " | " + point.x.toFixed(3)
                              }
                              onPressed: {
                                  console.log("YADA3")
                              }
              
              fcarneyF Offline
              fcarneyF Offline
              fcarney
              wrote on last edited by
              #7

              @rhb327 I think your onReleased is eating the event. I am not sure how you are going to handle 2 things at once. You are doing something in onReleased, but you also want the chart to do something.

              C++ is a perfectly valid school of magic.

              1 Reply Last reply
              0
              • R Offline
                R Offline
                rhb327
                wrote on last edited by
                #8

                I've seen example where one MouseArea passes onClicked to another so the same event runs in two handlers (below). My understanding is onPressed and onReleased are not part of composite events so only the onClicked should get passed on from my MouseArea. I've tried adding mouse.accepted = false in every handler in my MouseArea as well but no luck.

                Any thoughts about how one might implement a simple zoom (like in my MouseArea) and maintain ability for tooltips on series? That's really what I'm after. The C++ version of ChartView has some mouse events but not the QML. I was hoping to avoid sub-classing a ChartView in C++.

                Thanks again for inputs...this has been a bit head scratching for me!

                1 Reply Last reply
                0
                • fcarneyF Offline
                  fcarneyF Offline
                  fcarney
                  wrote on last edited by
                  #9

                  Can you provide an ultra simple version that does not work and does zoom? I have a pie chart from above, but it won't zoom. I am using onWheel event of mousearea with other buttons disabled. It gets the event, but it wont zoom. onclick works fine in pieseries too.

                  C++ is a perfectly valid school of magic.

                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    rhb327
                    wrote on last edited by rhb327
                    #10

                    Absolutely...not sure if I'm supposed to zip and upload or cut and paste here but I think this shows my issue reasonably well. I hope it's short enough.

                    import QtQuick 3.12
                    import QtQuick.Window 2.12
                    import QtQuick.Controls 2.5
                    import QtCharts 2.3
                    
                    Window {
                        visible: true
                        width: 640
                        height: 480
                    
                        Rectangle {
                            id: chartDataRect
                            anchors.fill: parent
                            //anchors{left: parent.left; leftMargin: 30; right: parent.rigth; rightMargin: 10; top: parent.top; topMargin: 40}
                            //radius: 6
                            width: 640
                            height: 480
                            color: "#ECEEEE"
                    
                            Component.onCompleted: {
                                scatterSeries.append(1,2)
                                scatterSeries.append(2,4)
                                scatterSeries.append(4,7)
                            }
                    
                            ChartView {
                                id: chartView
                                clip: true
                                anchors.fill: parent
                                legend.visible: false
                                antialiasing: true
                                legend.alignment:  Qt.AlignBottom
                                backgroundColor: "#000000"
                                theme: ChartView.ChartThemeDark
                                width: 2.0
                                property bool pressed: false
                    
                                ValueAxis {
                                    id: timeAxis
                                    color: "#344550"
                                    min: 0
                                    max: 10
                                    labelFormat:"%.1f"
                                    labelsColor: "#FFFFFF"
                                }
                    
                                ValueAxis {
                                    id: tempAxis
                                    min: 0
                                    max: 10
                                    color: "#344550"
                                    labelFormat:"%.1f"
                                    labelsColor: "#FFFFFF"
                                }
                    
                                ScatterSeries {
                                    id: scatterSeries
                                    axisX: timeAxis
                                    axisY: tempAxis
                                    color: "red"
                                    visible: true
                    
                                    // TODO:  Still not working?  MouseArea does not seem to propagate (hover will work).
                                    onClicked: {
                                        console.log("Click Series")
                                    }
                                }
                    
                                MouseArea {
                                    anchors.fill: chartView
                                    propagateComposedEvents: true
                                    //preventStealing: true
                                    property int lastX: 0
                                    property int lastY: 0
                                    acceptedButtons: Qt.LeftButton | Qt.RightButton
                    
                                    onClicked: {
                                        console.log("Click MouseArea")
                                        mouse.accepted = false
                                    }
                                    onPressed: {
                                        console.log("Press MouseArea")
                                        if (mouse.button === Qt.LeftButton) {
                                            lastX = mouse.x;
                                            lastY = mouse.y;
                                        }
                                        else if (mouse.button === Qt.RightButton){
                                            chartView.pressed = false
                                            zoomRect.x = mouse.x
                                            zoomRect.y = mouse.y
                                            zoomRect.visible = true
                                        }
                                        mouse.accepted = true
                                    }
                                    onReleased: {
                                        console.log("Released MouseArea")
                                        if (mouse.button === Qt.LeftButton) {
                                            if (lastX !== mouse.x) {
                                                chartView.scrollRight(lastX - mouse.x);
                                                lastX = mouse.x;
                                            }
                                            if (lastY !== mouse.y) {
                                                chartView.scrollDown(lastY - mouse.y);
                                                lastY = mouse.y;
                                            }
                                        }
                                        else if (mouse.button === Qt.RightButton) {
                                            chartView.zoomIn(Qt.rect(zoomRect.x, zoomRect.y, zoomRect.width, zoomRect.height));
                                            zoomRect.visible = false
                                            chartView.pressed=false
                                        }
                                    }
                                    onDoubleClicked: {
                                        console.log("Double Click MouseArea")
                                        chartView.zoomReset()
                                        timeAxis.min = 0
                                        timeAxis.max = 10
                                        tempAxis.min = 0
                                        tempAxis.max = 10
                                    }
                                    onMouseXChanged: {
                                        console.log("X Change MouseArea")
                                        zoomRect.width = mouse.x - zoomRect.x;
                                    }
                                    onMouseYChanged: {
                                        console.log("Y Change MouseArea")
                                        zoomRect.height = mouse.y - zoomRect.y;
                                    }
                                }
                    
                                Rectangle{
                                    id: zoomRect
                                    color: "#FFFFFF"
                                    opacity: 0.4
                                    visible: false
                                }
                            }
                        }
                    }
                    
                    
                    1 Reply Last reply
                    0
                    • fcarneyF Offline
                      fcarneyF Offline
                      fcarney
                      wrote on last edited by
                      #11

                      If I change the onPressed event in mousearea to:

                      //mouse.accepted = true
                      mouse.accepted = false
                      

                      Then when I click on the red dots I get the "Click Series" message.

                      Adding this to mousearea:

                                     onWheel: {
                                          var delta = wheel.angleDelta;
                                          if(delta.y > 0){
                                              chartView.zoomIn()
                                          }else if(delta.y < 0){
                                              chartView.zoomOut()
                                          }
                                      }
                      

                      Allows zoom in and out. I would also add keyboard +/- or something similar.

                      C++ is a perfectly valid school of magic.

                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        rhb327
                        wrote on last edited by
                        #12

                        Ok...but when you did that zoom stopped working, right?

                        fcarneyF 1 Reply Last reply
                        0
                        • R rhb327

                          Ok...but when you did that zoom stopped working, right?

                          fcarneyF Offline
                          fcarneyF Offline
                          fcarney
                          wrote on last edited by
                          #13

                          @rhb327 said in MouseArea hides ChartView Series signals:

                          but when you did that zoom stopped working, right?

                          Yes
                          This works:

                                             else if (mouse.button === Qt.RightButton){
                                                  chartView.pressed = false
                                                  zoomRect.x = mouse.x
                                                  zoomRect.y = mouse.y
                                                  zoomRect.visible = true
                                                  mouse.accepted = true
                                                  return
                                              }
                                              //mouse.accepted = true
                                              mouse.accepted = false
                          

                          C++ is a perfectly valid school of magic.

                          1 Reply Last reply
                          0
                          • R Offline
                            R Offline
                            rhb327
                            wrote on last edited by
                            #14

                            Yes! Thank you.

                            So I think my learning is that on the right click I need the accepted = true to ensure the released is handled in the same MouseArea for my zoom box. I'm not quite sure what to make in regard to the fact I passed clicked and pressed on via accepted = false. I would have thought I'd only need to pass along clicked. Thanks again.

                            fcarneyF 1 Reply Last reply
                            0
                            • R rhb327

                              Yes! Thank you.

                              So I think my learning is that on the right click I need the accepted = true to ensure the released is handled in the same MouseArea for my zoom box. I'm not quite sure what to make in regard to the fact I passed clicked and pressed on via accepted = false. I would have thought I'd only need to pass along clicked. Thanks again.

                              fcarneyF Offline
                              fcarneyF Offline
                              fcarney
                              wrote on last edited by
                              #15

                              @rhb327 I dont get it either. I think doing panning breaks too. I would put that on middle mouse button only. Maybe don't let that mousearea handle left clicks at all. It seems to be problematic.

                              C++ is a perfectly valid school of magic.

                              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