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 Update on Monday, May 27th 2025

MouseArea hides ChartView Series signals

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

    Hello! I have moved my topic from general questions here.

    I have faced with the following issue: ChartView has several Series (LineSeries and ScatterSeries in my case) and this series have signals that I want to process. Everything has been okay (I cat catch this signals and process) till I added MouseArea over ChartView to process different mouse and keyboards inputs. So my structure is something like this:

    ChartView {
         MouseArea {
            id: mouseAreaIntensity
            anchors.fill: parent
            acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
            propagateComposedEvents: true
            hoverEnabled: true
         }
    }
    

    In this case my series don't emit any signals (onHovered, onClicked, etc). I have supposed that propagateComposedEvents property let me do this, but this try was failed. How can I solve this issue?

    Thank you in advance!

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