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
    评论
好的,如果您想在Pyside2应用程序中添加视频流并显示带刻度的直方图,您可以使用OpenCV库来捕获和处理视频流,并使用Matplotlib库来绘制直方图。 下面是一个简单的例子,可以帮助您开始: ```python import sys import cv2 from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure from PySide2.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel class VideoPlayer(QWidget): def __init__(self, video_source=0): super().__init__() # Open the video source self.video = cv2.VideoCapture(video_source) # Create a figure for the histogram self.figure = Figure() self.canvas = FigureCanvas(self.figure) self.ax = self.figure.add_subplot(111) # Create a label for displaying the video frames self.image_label = QLabel(self) # Set up the layout layout = QVBoxLayout() layout.addWidget(self.image_label) layout.addWidget(self.canvas) self.setLayout(layout) # Start the timer to update the video frames and histogram self.timer = QTimer() self.timer.timeout.connect(self.update_frame) self.timer.start(30) def update_frame(self): # Read the next frame from the video stream ret, frame = self.video.read() if ret: # Convert the frame to grayscale and calculate the histogram gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) hist, bins = np.histogram(gray.ravel(), 256, [0, 256]) # Update the histogram plot self.ax.clear() self.ax.bar(bins[:-1], hist, width=1) self.ax.set_xlim([0, 256]) self.ax.set_ylim([0, 5000]) self.canvas.draw() # Convert the frame to QImage format and display it height, width, channels = frame.shape bytes_per_line = channels * width qimg = QImage(frame.data, width, height, bytes_per_line, QImage.Format_BGR888) pixmap = QPixmap.fromImage(qimg) self.image_label.setPixmap(pixmap) if __name__ == '__main__': app = QApplication(sys.argv) player = VideoPlayer() player.show() sys.exit(app.exec_()) ``` 在这个例子中,我们创建了一个名为`VideoPlayer`的自定义QWidget类,它包含一个用于显示视频帧的QLabel和一个用于显示直方图的Matplotlib图表。我们使用OpenCV库来捕获和处理视频流,并使用Matplotlib库来计算和绘制直方图。我们还使用PySide2的QTimer类来定期更新视频帧和直方图。 请注意,这只是一个简单的例子,您需要根据您的应用程序需求进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值