pyside2 自定义折线图、直方图

因使用开源版本pyside,遵循LGPL协议,无法使用QChart,所以根据公司产品定义了折线图及直方图

实现效果图:


from PySide2 import QtCore, QtGui , QtWidgets   
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
import sys,random,math,time
class SlineSeries():  #定义一个数据点的信息类
    def __init__(self):
        self.m_chartPtInfos = []    #存储数据点信息的数组
        self.seriesColor = QColor(random.randint(0, 255),random.randint(0, 255),random.randint(0, 255))
        self.isHide = False
        self.callback = None
    def append(self,ptinfo):# QpointF( 0 , 1)
        self.m_chartPtInfos.append(ptinfo)
        if self.callback != None:
            self.callback()
    def replace(self, m_chartPtInfos):
        self.m_chartPtInfos = m_chartPtInfos
        if self.callback != None:
            self.callback()
        
    def hide(self):
        self.isHide = True
    def show(self):
        self.isHide = False
    def isHidden(self):
        return self.isHide
    def setName(self, name):
        self.name = name
    def name(self):
        return self.name

class SChart(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.m_xAxisSize = 4    #x轴的刻度数
        self.m_yAxisSize = 4    #y轴的刻度数
        self.m_chartType = 0    #图表类型
        self.createDefaultAxes()
        # 直方图使用
        self.histogramSeries = SlineSeries()
        # 折线图使用
        self.m_chartSeries = []    #存储series信息的数组
    def removeAllSeries(self):
        self.m_chartSeries.clear()

    def addSeries(self,series):
        self.m_chartSeries.append(series)
        series.callback = self.update

    def createDefaultAxes(self):
        self.m_axisX = Axis()
        self.m_axisY = Axis()

    def handleUpdate(self ,data):
        self.histogramSeries.replace(data)
        self.update()

    def axisX(self):
        return self.m_axisX
    def axisY(self):
        return self.m_axisY
    def paintEvent(self, event):
        p = QPainter(self)
        p.setRenderHint(QPainter.Antialiasing)
        pen = QPen()
        font = QFont()

        xstartPos = 30  # x轴全局坐标起始点
        ystartPos = 10  # y轴全局坐标起始点
        xWidth = self.width() - 50
        yHeight = self.height() - 50
        yAxisSize = self.m_yAxisSize  # y轴刻度数
        xAxisSize = self.m_xAxisSize  # x轴刻度数
        yAxisMax = self.m_axisY.axisMax
        yAxisMin = self.m_axisY.axisMin
        xAxisMax = self.m_axisX.axisMax
        xAxisMin = self.m_axisX.axisMin
        
        xAxisTextLen = xWidth / (xAxisMax - xAxisMin)
        yAxisTextLen = yHeight / yAxisMax

        # 先画X轴、Y轴 和基数线
        # base line
        pen.setWidthF(0.5)
        pen.setStyle(Qt.SolidLine)
        pen.setColor(QColor("#d6d6d6"))
        p.setPen(pen)
        if self.m_chartType == 0:
            for oilprec in [0.25, 0.5, 0.75, 1]:
                baseyPos = xAxisMax * oilprec * xAxisTextLen
                p.drawLine(QPoint(xstartPos + baseyPos, ystartPos), QPoint(xstartPos + baseyPos,ystartPos + yHeight))
        else:
            for oilprec in [0, 0.25, 0.5, 0.75]:
                baseyPos = yAxisMax * oilprec * yAxisTextLen
                p.drawLine(QPoint(xstartPos ,ystartPos + baseyPos), QPoint(xstartPos + xWidth, ystartPos + baseyPos))

        font.setPointSize(8)
        p.setFont(font)
        # xAxis
        pen.setColor(QColor("#d6d6d6"))
        p.setPen(pen)
        p.drawLine(QPoint(xstartPos, ystartPos + yHeight), QPoint(xstartPos + xWidth, ystartPos + yHeight))
        for i in range(int(xAxisSize) + 1):
            pen.setColor(QColor("#d6d6d6"))
            p.setPen(pen)
            # 刻度线
            p.drawLine(xstartPos + (xWidth/xAxisSize)*i, yHeight + 10, xstartPos + (xWidth/xAxisSize)*i, yHeight + 7)
            if self.m_axisX.isHidden() == False:
                # xAxis text
                text = xAxisMin + (xAxisMax - xAxisMin) / xAxisSize * i
                pen.setColor(QColor("#000000"))
                p.setPen(pen)
                p.drawText(xstartPos + (xWidth/xAxisSize)*i - 20, yHeight + 10, 40, 20, Qt.AlignCenter, self.m_axisX.labelFormat%text)

        # yAxis
        pen.setColor(QColor("#d6d6d6"))
        p.setPen(pen)
        p.drawLine(QPoint(xstartPos, 10), QPoint(xstartPos, ystartPos + yHeight))
        for i in range(int(yAxisSize)+1):
            pen.setColor(QColor("#d6d6d6"))
            p.setPen(pen)
            # 刻度线
            p.drawLine(xstartPos, ystartPos + (yHeight/yAxisSize)*i, xstartPos + 3, ystartPos + (yHeight/yAxisSize)*i)
            if self.m_axisY.isHidden() == False:
                # yAxis text
                text = yAxisMax/yAxisSize*(yAxisSize-i)
                pen.setColor(QColor("#000000"))
                p.setPen(pen)
                p.drawText(0, ystartPos + (yHeight/yAxisSize)*i - 10, xstartPos - 5, 20, Qt.AlignRight|Qt.AlignVCenter, self.m_axisY.labelFormat%text)

        # chart
        if self.m_chartType == 0:
            chartPtInfo = self.histogramSeries.m_chartPtInfos
            for i in range(len(chartPtInfo) - 1):
                startinfo = chartPtInfo[i]
                endinfo = chartPtInfo[i + 1]
                pen.setColor(QColor("#d9d9d9"))
                p.setPen(pen)
                p.setBrush(QColor("#d9d9d9"))
                p.drawRect(QRectF(xstartPos + (i-xAxisMin)*xAxisTextLen,
                    ystartPos + (yAxisMax-startinfo)*yAxisTextLen,
                    xAxisTextLen,
                    10 + yHeight - (ystartPos + (yAxisMax-startinfo)*yAxisTextLen)))
                # 描线
                pen.setColor(QColor("#000000"))
                p.setPen(pen)
                p.drawLine(QPointF(xstartPos + (i-xAxisMin)*xAxisTextLen, ystartPos + (yAxisMax-startinfo)*yAxisTextLen),
                        QPointF(xstartPos + (i+1-xAxisMin)*xAxisTextLen, ystartPos + (yAxisMax-endinfo)*yAxisTextLen))
        elif self.m_chartType == 1:
            for series in self.m_chartSeries:
                chartPtInfo = series.m_chartPtInfos
                if series.isHidden() == False:
                    pen.setColor(series.seriesColor)
                    for i in range(len(chartPtInfo) - 1):
                        startinfo = chartPtInfo[i]
                        endinfo = chartPtInfo[i + 1]
                        p.setPen(pen)
                        p.setBrush(QColor(255, 0, 0, 255))
                        pen.setWidthF(2)
                        p.drawLine(QPointF(xstartPos + i*xAxisTextLen, ystartPos + (yAxisMax-startinfo.y())*yAxisTextLen),
                                QPointF(xstartPos + (i+1)*xAxisTextLen, ystartPos + (yAxisMax-endinfo.y())*yAxisTextLen))

    def setChartType(self, num): # 设置表的类型。0:直方图;1:折线图。
        self.m_chartType = num
class Axis():
    def __init__(self):
        super().__init__()
        self.isHide = False
        self.labelFormat = '%d'
    def setRange(self, min, max):
        self.axisMin = min
        self.axisMax = max
    def setLabelFormat(self, format):
        self.labelFormat = format
    def hide(self):
        self.isHide = True
    def show(self):
        self.isHide = False
    def isHidden(self):
        return self.isHide


if __name__ == '__main__':
    app = QApplication(sys.argv)
    curveChart = SChart()
    curveChart.setStyleSheet("background-color:white;")
    curveChart.setFixedSize(250,150)
    # 折线图
    # curveChart.axisY().setRange(0,100)
    # curveChart.setChartType(1)
    # curveChart.axisX().setRange(0,100)
    # curveChart.axisX().hide()
    # def thread11():
    #     series = SlineSeries()
    #     curveChart.addSeries(series)
    #     series2 = SlineSeries()
    #     curveChart.addSeries(series2)
    #     for i in range(100):
    #         if len(series.m_chartPtInfos)==100:
    #             series.m_chartPtInfos.pop(0)
    #         if len(series2.m_chartPtInfos)==100:
    #             pass
    #         else:
    #             series2.append(QPointF(i,random.randint(5, 10)))
    #         series.append(QPointF(i,random.randint(33, 44)))
    #         time.sleep(1)

    #直方图
    curveChart.axisY().hide()
    curveChart.axisY().setRange(0,20000)
    curveChart.axisX().setRange(0,255)
    curveChart.setChartType(0)
    def thread11():
        for i in range(100):
            points = []
            for i in range(255):
                oilConspn = random.randint(0, 15000)
                points.append(oilConspn)
            curveChart.handleUpdate(points)
            time.sleep(0.5)
    import threading
    _thread = threading.Thread(target=thread11)
    _thread.start()

    curveChart.show()
    sys.exit(app.exec_())

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值