pyqt5使用事件过滤器绘制温度曲线

绘制思路:

  1. 在QT设计师里创建两个标签,并加入布局。

  1. 生产.py文件,建立一个新文件,并继承该Ui文件。

from PyQt5.Qt import *
from untitled import Ui_Form
class Window(QWidget,Ui_Form):
    def __init__(self):
    super().__init__()
  1. 给标签加载事件过滤器


        self.label.installEventFilter(self) #事件过滤器在父节点里去实现,所以用self
        self.label_2.installEventFilter(self)

4写事件过滤器


    def eventFilter(self, watched,event) -> bool:
        if (event.type()==QEvent.Paint):
            if watched==self.label:

                self.hight_paint()

            if watched==self.label_2:

                self.low_paint()


        return super(Window,self).eventFilter(watched,event)
  1. 完成相关绘制功能

  1. 双击更新温度曲线,可以在事件过滤器中重写鼠标双击事件时触发的函数。

    def eventFilter(self, watched,event) -> bool:
        if (event.type()==QEvent.Paint):
            if watched==self.label:

                self.hight_paint()

            if watched==self.label_2:

                self.low_paint()
        elif (event.type()==QEvent.MouseButtonDblClick): #鼠标双击事件
            self.updateTemp()

        return super(Window,self).eventFilter(watched,event)

完整代码为:


from PyQt5.Qt import *
from untitled import Ui_Form
import random




class Window(QWidget,Ui_Form):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("的学习")
        self.setupUi(self)

        self.label.installEventFilter(self)
        self.label_2.installEventFilter(self)
        #定义数组


        self.mHighTemp=[]
        self.mLowTemp=[]

        self.point_radius=3
        self.padding=20  #边界距离
        self.text_offset_X=12
        self.text_offset_Y=10

        self.updateTemp()


    def hight_paint(self):
        painter=QPainter(self.label)
        painter.setRenderHint(QPainter.Antialiasing,True)

        '''计算X坐标'''
        pointX=[self.label.pos().x()+self.padding+int((self.label.width()/6-self.padding))*i for i in range(7)]



        '''计算Y坐标'''
        tempAvage=int(sum(self.mHighTemp)/6) #计算高温平均值
        pointY=[]
        yCenter=int(self.label.height()/2)
        increment=int(self.label.height()/20)

        # for i in range(7):
        #     y=yCenter-((self.mHighTemp[i]-tempAvage)*increment)
        #     pointY.append(y)
        # print(pointY)

        #也可以使用列表推导
        pointY=[yCenter-((self.mHighTemp[i]-tempAvage)*increment) for i in range(7)]


        #3开始绘制
        #3.1 初始化画笔
        pen=QPen()
        pen.setColor(QColor(255,170,0))
        pen.setWidth(2)

        painter.setPen(pen)
        painter.setBrush(QColor(255,170,0))
        painter.setFont(QFont('Microsoft YaHei',14))



        #3.2 画点,绘制文本

        for i in range(7):

            painter.drawEllipse(QPoint(pointX[i],pointY[i]),self.point_radius,self.point_radius)

            painter.drawText(QPoint(pointX[i]-self.text_offset_X,pointY[i]-self.text_offset_Y),
                                f'{self.mHighTemp[i]}C')

        #3.3 绘制曲线
        for i in range(6):
            if i==0:
                pen.setStyle(Qt.DotLine)
                painter.setPen(pen)
            else:
                pen.setStyle(Qt.SolidLine)
                painter.setPen(pen)

            painter.drawLine(pointX[i],pointY[i],pointX[i+1],pointY[i+1])

    def low_paint(self):
        painter = QPainter(self.label_2)#创建画家,并指定绘制对象
        painter.setRenderHint(QPainter.Antialiasing, True)

        '''计算X坐标'''
        pointX = [self.label_2.pos().x() + self.padding + int((self.label_2.width() / 6 - self.padding)) * i for i in
                  range(7)]


        '''计算Y坐标'''
        tempAvage = int(sum(self.mLowTemp) / 6)  # 计算平均值
        pointY = []
        yCenter = int(self.label_2.height() / 2)
        increment = int(self.label_2.height() / 20)



        # 也可以使用列表推导
        pointY = [yCenter - ((self.mLowTemp[i] - tempAvage) * increment) for i in range(7)]


        # 3开始绘制
        # 3.1 初始化画笔
        pen = QPen()
        pen.setColor(QColor(155, 100, 111))
        pen.setWidth(2)

        painter.setPen(pen)
        painter.setBrush(QColor(155, 100, 111))
        painter.setFont(QFont('Microsoft YaHei', 14))

        # 3.2 画点,绘制文本

        for i in range(7):

            painter.drawEllipse(QPoint(pointX[i], pointY[i]), self.point_radius, self.point_radius)

            painter.drawText(QPoint(pointX[i] - self.text_offset_X, pointY[i] - self.text_offset_Y),
                             f'{self.mLowTemp[i]}C')

        # 3.3 绘制曲线
        for i in range(6):
            if i == 0:
                pen.setStyle(Qt.DotLine)
                painter.setPen(pen)
            else:
                pen.setStyle(Qt.SolidLine)
                painter.setPen(pen)

            painter.drawLine(pointX[i], pointY[i], pointX[i + 1], pointY[i + 1])

    def updateTemp(self):
        self.mHighTemp=[random.randint(30,40) for _ in range(7)]
        self.mLowTemp=[random.randint(20,25) for _ in range(7)]

        self.label.update() #触发paintevent事件,刷新界面
        self.label_2.update()


    def eventFilter(self, watched,event) -> bool:
        if (event.type()==QEvent.Paint):
            if watched==self.label:

                self.hight_paint()

            if watched==self.label_2:

                self.low_paint()
        elif (event.type()==QEvent.MouseButtonDblClick): #鼠标双击事件
            self.updateTemp()

        return super(Window,self).eventFilter(watched,event)








if __name__ == '__main__':
    import sys
    app=QApplication(sys.argv)

    win=Window()
    win.show()

    sys.exit(app.exec_())


以上代码为看了别人Qt用c++写的代码,自己把它改成的python代码。pyqt的高级应用实在太少。想提高pyqt水平,必须要去看c++的Qt项目。这两者有些差别还是挺大的。python确实比c++容易的多。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyQt5事件过滤器是一种机制,通过它可以拦截和处理发送给QObject对象的事件事件过滤器可以拦截并处理对象接收到的事件,也可以将事件传递给对象进行处理。在PyQt5中,实现事件过滤器的注意事项如下: 1. 首先,需要安装事件过滤器。在代码中,使用`installEventFilter()`方法将事件过滤器加载到对象上,例如`self.label.installEventFilter(self)`。 2. 然后,需要重写`eventFilter()`方法。这个方法接收两个参数:`a0`表示事件的接收对象,`a1`表示事件对象本身。方法的返回值是一个布尔值,用于指示是否拦截事件。如果返回True,表示拦截事件并进行处理;如果返回False,表示不拦截事件,将其传递给对象进行处理。方法的定义如下:`def eventFilter(self, a0: 'QObject', a1: 'QEvent') -> bool:`。 3. 在`eventFilter()`方法中,可以通过判断事件类型来选择处理特定的事件。例如,通过`a1.type()==QEvent.Enter`判断鼠标进入事件,通过`a1.type()==QEvent.Leave`判断鼠标离开事件。 4. 在事件处理中,可以根据需要对对象进行相应的操作。例如,可以改变对象的样式、文本等属性。 下面是一个示例,展示了一个标签控件,使用事件过滤器实现鼠标进入时字体变红、背景色变青,鼠标离开时字体变黑、背景色变黄的效果: ```python from PyQt5.Qt import * class Window(QWidget): def __init__(self): super().__init__() self.setWindowTitle("事件过滤器的学习") self.resize(500, 500) self.setup_ui() self.red = 'QLabel#label{color:#FF0000;background-color:cyan}' self.black = 'QLabel#label{color:#000000;background-color:yellow;}' def setup_ui(self): self.label = QLabel(self) self.label.resize(50, 30) self.label.setObjectName('label') self.label.installEventFilter(self) # 给标签加载事件过滤器 def eventFilter(self, a0: 'QObject', a1: 'QEvent') -> bool: if a0 == self.label: if a1.type() == QEvent.Enter: self.label.setText('我是红色') self.label.setStyleSheet(self.red) return True elif a1.type() == QEvent.Leave: self.label.setText('我是黑色') self.label.setStyleSheet(self.black) return True return super().eventFilter(a0, a1) if __name__ == '__main__': import sys app = QApplication(sys.argv) win = Window() win.show() sys.exit(app.exec_()) ``` 在这个示例中,我们创建了一个窗口类`Window`,其中包含一个标签控件`label`。在`setup_ui()`方法中,我们将标签加载了事件过滤器,并在`eventFilter()`方法中处理了鼠标进入和离开事件。当鼠标进入标签时,标签的文本变为"我是红色",样式变为红色的字体和青色的背景;当鼠标离开标签时,标签的文本变为"我是黑色",样式变为黑色的字体和黄色的背景。 希望这个示例能帮助您理解PyQt5事件过滤器的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值