pythonpyqtpyqt5qtchartsqchart

How to get values from a chart?


It is easy to get the coordinates of the mouse on the application -

    self.setMouseTracking(True)

def mouseMoveEvent(self, event):
    mouse_x = event.x()
    mouse_y = event.y()

But for chat it doesn't work at all. How to get coordinate values in chat when pointing with the mouse? Code:

from random import uniform
import sys

from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PyQt5.QtChart import QChart, QChartView, QLineSeries

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setGeometry(100, 100, 680, 500)

        series = QLineSeries()
        for i in range(100):
            series.append(i, uniform(0, 10))

        chart = QChart()
        chart.addSeries(series)
        chart.createDefaultAxes()
        chartview = QChartView(chart)

        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        lay = QVBoxLayout(central_widget)
        lay.addWidget(chartview)
        self.setMouseTracking(True)

    def mouseMoveEvent(self, event):
        mouse_x = event.x()
        mouse_y = event.y()

if __name__ == "__main__":
    App = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(App.exec_())

Solution

  • The mouse event is propagated from the widget above to the one below it, if one of those widgets consumes it then it will no longer be transmitted. In your case, if the mouse passes over the chart then the window will not receive it, so you must listen to the mouse events of the QChartView, and for this there are at least 2 options: override the mouseXEvent of the QChartView or use an event filter . In this case I will use the second option.

    On the other hand, you have to convert the position relative to the QChartView to scene positions, and from the scene positions to the chart positions.

    class Window(QMainWindow):
        def __init__(self):
            super().__init__()
            self.setGeometry(100, 100, 680, 500)
    
            series = QLineSeries()
            for i in range(100):
                series.append(i, uniform(0, 10))
    
            chart = QChart()
            chart.addSeries(series)
            chart.createDefaultAxes()
            self.chartview = QChartView(chart)
    
            central_widget = QWidget()
            self.setCentralWidget(central_widget)
            lay = QVBoxLayout(central_widget)
            lay.addWidget(self.chartview)
    
            self.chartview.setMouseTracking(True)
            self.chartview.viewport().installEventFilter(self)
    
        def eventFilter(self, obj, event):
            if obj is self.chartview.viewport() and event.type() == QEvent.MouseMove:
                lp = event.pos()
                sp = self.chartview.mapToScene(lp)
                vp = self.chartview.chart().mapToValue(sp)
                print(vp)
            return super().eventFilter(obj, event)