龙空技术网

实战PyQt5:160-QChart图表之对图表进行交互操作

爱好史地的coder 116

前言:

现在姐妹们对“qt与python程序交互”大概比较看重,你们都想要剖析一些“qt与python程序交互”的相关资讯。那么小编也在网络上汇集了一些对于“qt与python程序交互””的相关内容,希望咱们能喜欢,看官们一起来了解一下吧!

图表交互操作

在图表可视化中,一些场景中需要对图表进行交互操作,QChart的各种图表类继承自QT的GraphicsView 框架,因此可以很方便对图表中的各种元素进行进行交互操作,例如,可以使用鼠标拖动QLineSeries图形序列中的某个点,改变其值,并在图表中交互显示。

使用鼠标进行交互操作,需要在继承自QChartView的类中重新实现三个和鼠标有关的事件函数,它们是mousePressEvent(), mouseMoveEvent()和MouseReleaseEvent(), 记录鼠标移动的点,将其传送给QChart类,然后就其转换成对应图标序列坐标的点,替换序列中相应的点值,就可以实现交互对图表的交互操作。

折线交互操作示例

示例代码演示了如何使用鼠标来交互调整QLineSeries中的点,并在图表中动态显示出来。完整代码如下:

import sys, mathfrom PyQt5.QtCore import Qt, QPoint, QPointFfrom PyQt5.QtGui import QPainter, QPenfrom PyQt5.QtWidgets import QApplication, QMainWindowfrom  PyQt5.QtChart import QChart, QChartView, QLineSeries, QAbstractAxis, QValueAxis class MyChart(QChart):    def __init__(self, parent=None):        super(MyChart, self).__init__(parent)        self.clicked = False            def clickPoint(self, point):        series = self.series()[0]        if series is None:            return                #找到最近的点        self.movingPoint = QPoint()        self.clicked = False                points = series.pointsVector()        for pnt in points:            if self.distance(pnt, point) < self.distance(self.movingPoint, point):                self.movingPoint = pnt                self.clicked = True       def distance(self, p1, p2):        dx = p1.x() - p2.x()        dy = p1.y() - p2.y()        return  math.sqrt(dx * dx + dy * dy)        def setPointClicked(self, clicked):        self.clicked = clicked            def handlePointMove(self, point):        if not self.clicked:            return        #将从ChartView中单击的点映射到图表所占据的区域。        mappedPoint = point        mappedPoint.setX(point.x() - self.plotArea().x())        mappedPoint.setY(point.y() - self.plotArea().y())                #获取x轴和y轴,以便能够将映射的坐标点转换为图表比例。        axisX = self.axes(Qt.Horizontal)[0]        hAxis = None        if axisX.type() == QAbstractAxis.AxisTypeValue:            hAxis = axisX                    axisY = self.axes(Qt.Vertical)[0]        vAxis = None        if axisY.type() == QAbstractAxis.AxisTypeValue:            vAxis = axisY                    if hAxis and vAxis:            #计算在x轴和y轴上两点的单位因子            xUnit = self.plotArea().width() / hAxis.max()            yUnit = self.plotArea().height() / vAxis.max()                        #将mappedPoint转换为实际的图表比例。              x = mappedPoint.x() / xUnit            y = mappedPoint.y() / yUnit                        #用新的点替换旧的点            series = self.series()[0]            series.replace(self.movingPoint, QPointF(x, y))                        #更新self.movingPoint,这样我们就可以在mousemoveEvent期间进行替换。            self.movingPoint.setX(x)            self.movingPoint.setY(y)            class MyChartView(QChartView):    def __init__(self, chart, parent=None):        super(MyChartView, self).__init__(chart, parent)        self.chart = chart        self.mousePos = None            def mousePressEvent(self, event):        self.mousePos = event.pos()        QChartView.mousePressEvent(self, event)            def mouseMoveEvent(self, event):        self.chart.handlePointMove(event.pos())        QChartView.mouseMoveEvent(self, event)            def mouseReleaseEvent(self, event):        if event.pos() != self.mousePos:            self.chart.handlePointMove(event.pos())            self.chart.setPointClicked(False)        QChartView.mouseReleaseEvent(self, event)            class DemoChartInteractions(QMainWindow):    def __init__(self, parent=None):        super(DemoChartInteractions, self).__init__(parent)                    # 设置窗口标题        self.setWindowTitle('实战 Qt for Python: QChart折线图演示')              # 设置窗口大小        self.resize(480, 360)                self.createChart()        def createChart(self):                    #设置折线数据        lineSeries = QLineSeries()        lineSeries.append(0, 6)        lineSeries.append(2, 4)        lineSeries.append(3, 8)        lineSeries.append(7, 13)        lineSeries.append(10, 5)        lineSeries.append(11, 1)        lineSeries.append(13, 3)        lineSeries.append(17, 6)        lineSeries.append(18, 3)        lineSeries.append(20, 2)                #线加粗        pen = lineSeries.pen()        pen.setWidth(5)        lineSeries.setPen(pen)                #创建图表        chart = MyChart()        chart.addSeries(lineSeries)        chart.legend().hide()        chart.setTitle('鼠标拖放移动数据点')                #x轴        axisX = QValueAxis()        chart.addAxis(axisX, Qt.AlignBottom)        axisX.setRange(0, 20)        lineSeries.attachAxis(axisX)                #Y轴        axisY = QValueAxis()        chart.addAxis(axisY, Qt.AlignLeft)        axisY.setRange(0, 13)        lineSeries.attachAxis(axisY)                lineSeries.pressed.connect(chart.clickPoint)                #图表视图        chartView = MyChartView(chart)        chartView.setRenderHint(QPainter.Antialiasing)                self.setCentralWidget(chartView)              if __name__ == '__main__':    app = QApplication(sys.argv)    window = DemoChartInteractions()    window.show()    sys.exit(app.exec())   

运行结果如下图:

本文知识点使用QLineSerie.replace()方法对其中的点进行动态替换。使用鼠标对图表进行交互控制。

请多多关注,评论,收藏,点赞,和转发。

前一篇: 实战PyQt5: 159-使用OpenGL加速图表绘制

标签: #qt与python程序交互