【Python_PyQtGraph 学习笔记(三)】基于GraphicsLayoutWidget实现显示曲线对象 鼠标位置处坐标的功能

基于GraphicsLayoutWidget实现显示曲线对象 鼠标位置处坐标的功能

前言

在PyQtGraph的官方例程中有此功能的实现,可参考Crosshair / Mouse interaction;但是坐标值的变化是超过整数时才变化,不符合实际开发中要求的精度。
在实现该功能的过程中主要参考了(详细分析)如何使用pyqt5和pyqtgraph在图像上增加图例并显示鼠标位置处的变量值,但是在获取鼠标所在位置的曲线的横纵坐标时使用了不同的方法,下面进行详细的介绍。

正文

首先要创建曲线对象:

        self.__m_temCurveLst = [0] * 10  # 温度曲线数组
        self.__m_humCurveLst = [0] * 10  # 湿度曲线数组
        self.ui.temCurve = self.ui.Curve.plot(self.__m_temCurveLst, pen=pg.mkPen('black', width=1), name="温度曲线")
        self.ui.humCurve = self.ui.Curve.plot(self.__m_humCurveLst, pen=pg.mkPen('green', width=1), name="湿度曲线")

self.ui.Curve是图形对象PlotItem

如何基于GraphicsLayoutWidget创建曲线对象可以参考【Python_PyQtGraph 学习笔记】GraphicsLayoutWidget类的基本用法(持续更新)

之后的想法是:是否可以创建一个曲线上的点对象,然后获取鼠标的横坐标,根据鼠标的横坐标设置点对象的位置,这样曲线上的纵坐标就可以通过点对象的纵坐标而得到。
看文字可能不好理解,下面通过代码来进行展示。
创建坐标显示的标签:

        self.ui.pwLabel = pg.LabelItem(justify='right')  # 创建坐标的标签
        self.ui.pw.addItem(self.ui.pwLabel)  # 将坐标添加到GraphicsLayoutWidget布局中来

创建曲线对象上的点对象:

        self.temPoint = pg.CurvePoint(self.ui.temCurve)  # 创建温度曲线上的点
        self.humPoint = pg.CurvePoint(self.ui.humCurve)  # 创建湿度曲线上的点

创建了一个箭头对象,可以更加清楚的看到点对象运动到了曲线对象的具体位置:

 		self.arrow = pg.ArrowItem(angle=90)  # 创建一个箭头
        self.arrow.setParentItem(self.ui.temPoint)  # 将箭头添加到温度点上

这个箭头功能实现后,如果不想要可以注释掉,单纯的是为了更加直观的看到点的运动位置。
创建鼠标跟随的十字线:

		self.vLine = pg.InfiniteLine(angle=90, movable=False)  # 鼠标跟随的垂直方向的线
        self.hLine = pg.InfiniteLine(angle=0, movable=False)  # 鼠标跟随的水平方向的线
        self.ui.Curve.addItem(self.vLine, ignoreBounds=True)
        self.ui.Curve.addItem(self.hLine, ignoreBounds=True)

此功能也是属于可有可无的。
创建鼠标事件对象:

 		self.vb = self.ui.Curve.vb  # 不含有坐标轴,但有鼠标功能的支持,获取鼠标事件,用户可以使用鼠标缩放/平移 ViewBox 的内容
        self.proxy = pg.SignalProxy(self.ui.Curve.scene().sigMouseMoved, rateLimit=60, slot=self.__f_mouseMoved)

鼠标移动槽函数的实现:

 # 私有方法: GraphicsLayoutWidget 鼠标移动响应函数
    def __f_mouseMoved(self, evt):
        """
        function:
              in:
             out:
          return:  int >0 ok, <0 somewrong
          others:
        """
        pos = evt[0]  # 使用信号代理将原始参数转换为元组,获取事件的鼠标位置
        mousePoint = self.vb.mapSceneToView(pos)  # 鼠标所处的X轴坐标
        if self.ui.Curve.sceneBoundingRect().contains(pos):  # 如果鼠标位置在绘图部件中
            if self.__m_curvePtr > 1:  # 判断plot是否有大于一个点
                self.temPoint.setPos(mousePoint.x() / (self.__m_curvePtr - 1))  # Point设置位置的float类型范围是0-1
                self.humPoint.setPos(mousePoint.x() / (self.__m_curvePtr - 1))  # Point设置位置的float类型范围是0-1
                self.ui.pwLabel.setText("时间:%0.2f\n"
                                        "温度:%0.2f\n"
                                        "湿度:%0.2f\n"
                                        % (mousePoint.x(),
                                           self.temPoint.pos().y(),
                                           self.humPoint.pos().y()
                                           ))
                # self.ui.pwLabel.setText("x:%0.2f\n"
                #                         "y:%0.2f"
                #                         % (mousePoint.x(), mousePoint.y()))
                self.vLine.setPos(mousePoint.x())  # 设置垂直线的位置
                self.hLine.setPos(mousePoint.y())  # 设置水平线的位置

self.__m_curvePtr: 曲线指针,曲线列表中每添加i一个数,指针+1
注意: 我们所获取的鼠标横坐标mousePoint.x()这个是大于1的,但是点对象的setPos()方法设置的参数是0~1范围内的。所以需要得到目前已经绘制的点的数量,也就是曲线的长度,两者相除即可得到点对象在曲线对象中的比例。这样就可以把点设置到鼠标所在位置的曲线上来,也就能得到鼠标所在位置曲线的纵坐标。

实现的效果图:

你可能感兴趣的:(Python学习笔记,#,PyQtGraph学习笔记,python,ui,pyqt)