因使用开源版本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_())