python-使用Qchart总结3-绘制曲线图在这篇文章基础上,来改造一下,绘制一下动态曲线图吧
一、明确需求
①点击按钮,开始动态加载曲线,细节:一个一个点加载出来
二、实现
①在UI上添加按钮,打开原先的untitled.ui文件,添加一个按钮,更改名字,保存文件
②重新生成UI的py文件,右键选中后选择重新编译
③先把静态添加的点隐藏
④数据源:采用线程发送数据,所以先创建一个线程发送的方法,上代码
A=[(1, 40),(2, 99),(3,76)]#要发送的数据 class DataRefresh(QThread): dataRefreshed = pyqtSignal(list) #表示发送过去的是数组类型,所以注意下面 emit里面传的需要是数组类型 def run(self): global c c=0 print(c) while c<len(A):#因为是一个一个点绘制,所以一个一个点传送,注意:需要循环,不然只会发送1遍 self.dataRefreshed.emit(list(A[c])) time.sleep(5) c=c+1
插入位置:主类外面即可
⑤因为需要点击按钮开始绘制动态曲线,所以就是按钮需要与上述④的线程发送数据关联,来启动线程,所以在下图所示的地方添加连接信号,每一个大概意思都标明,可自行理解;
说明:实例化线程就是上述④里写的类,实例化,得到一个对象,然后把这个对象带的数据传给
self.plot_qchart.handle_update这个方法
上代码
class Window(QMainWindow, Ui_MainWindow):#这个是将图表与UI图连接起来 def __init__(self): super().__init__() self.setup_ui() # 渲染画布 self.connect_signals() def setup_ui(self): self.setupUi(self) self.plot_qchart = User_QSplineSeries() #将图表实例化 self.graphicsView.setChart(self.plot_qchart) self.graphicsView.setRenderHint(QPainter.Antialiasing) # 抗锯齿 self.graphicsView.setRubberBand(QChartView.RectangleRubberBand) def connect_signals(self):#连接信号 self.dataRefreshThread=DataRefresh() self.pushButton.clicked.connect(self.start_thread) # 跑线程 self.dataRefreshThread.dataRefreshed.connect(self.plot_qchart.handle_update) #新的视频任务进入时候后面加进去 def start_thread(self): print("线程开始") self.dataRefreshThread.start()
⑥数据发过来了,要显示在曲线图上,曲线图上就需要有个对象来接收一下,所以要在曲线图的类里面加一个接收函数即上述所说的
self.plot_qchart.handle_update来接收,所以要在绘制曲线的类里面,写一下接收的函数
在绘制的曲线图的类里面 加一个接受函数,需要注意传过来的格式,先看看传过来的数据格式
所以接收的ydata就是[1,40]这样的数据类型,通过append给曲线添加点,把数据绘制在曲线图上
def handle_update(self,ydata):#注意,传过来的格式 self.series.append(QPointF(ydata[0],ydata[1]))
⑦实现效果
三、全部代码
import sys import time from PyQt5.Qt import * from PyQt5.QtChart import QChartView, QChart, QValueAxis, QSplineSeries from PyQt5.QtGui import QPainter, QColor, QFont from PyQt5.QtWidgets import QMainWindow, QApplication from untitled import Ui_MainWindow #从生成好的py文件内导入设计好的UI类 A=[(1, 40),(2, 99),(3,76)] class DataRefresh(QThread): dataRefreshed = pyqtSignal(list) #表示发送过去的是数组类型,所以注意下面 emit里面传的需要是数组类型 def run(self): global c c=0 print(c) while c<len(A):#因为是一个一个点绘制,所以一个一个点传送,注意:需要循环,不然只会发送1遍 self.dataRefreshed.emit(list(A[c])) time.sleep(5) c=c+1 class Window(QMainWindow, Ui_MainWindow):#这个是将图表与UI图连接起来 def __init__(self): super().__init__() self.setup_ui() # 渲染画布 self.connect_signals() def setup_ui(self): self.setupUi(self) self.plot_qchart = User_QSplineSeries() #将图表实例化 self.graphicsView.setChart(self.plot_qchart) self.graphicsView.setRenderHint(QPainter.Antialiasing) # 抗锯齿 self.graphicsView.setRubberBand(QChartView.RectangleRubberBand) def connect_signals(self):#连接信号 self.dataRefreshThread=DataRefresh() self.pushButton.clicked.connect(self.start_thread) # 跑线程 self.dataRefreshThread.dataRefreshed.connect(self.plot_qchart.handle_update) #新的视频任务进入时候后面加进去 def start_thread(self): print("线程开始") self.dataRefreshThread.start() class User_QSplineSeries(QChart): #绘制曲线图 def __init__(self, parent=None, ): super(User_QSplineSeries, self).__init__(parent) self.window = parent #设置x轴 self.axisX = QValueAxis() self.axisX.setRange(0, 10)#X轴的范围 self.axisX.setTickCount(11) self.axisX.setLabelFormat("%d")#X轴上数字显示的类型 self.axisX.setLabelsColor(QColor(0, 0, 0)) # X轴上显示数字的颜色 self.addAxis(self.axisX, Qt.AlignBottom) #X轴放底部 # 设置y轴 self.axisY = QValueAxis() self.axisY.setRange(0,200)#Y轴的范围 self.addAxis(self.axisY, Qt.AlignLeft) #设置Y坐标放在左侧 self.axisY.setTitleText("单位:分钟")#设置Y坐标的名称 self.setTitle("视频时长曲线图")#设置整个图表的标题 self.setTitleFont(QFont("微软雅黑"))#设置整个图表的标题的字体 #---------------------------------------- #添加曲线 self.series =QSplineSeries() #使用曲线 self.series.setName("视频提示等待时长") #设置曲线的名字 # 添加曲线上的点,添加数据用这个 # self.series.append(1,60) # self.series.append(2,50) # self.series.append(8,90) #给曲线添加值 x=8 y=90的意思;分别加了2个点 #-------- self.series.setVisible(True)#将曲线显示出来 #设置曲线上点的显示 font = QFont() font.setPointSize(12) self.series.setPointLabelsFont(font)#给显示的点坐标设置字体大小 self.series.setPointLabelsFormat("@yPoint分钟 ")#设置点坐标显示的格式 self.series.setPointLabelsVisible(True)#将点坐标显示出来 self.series.setPointLabelsClipping(False) #将曲线加到坐标图里面去 self.addSeries(self.series) self.series.attachAxis(self.axisX)#让曲线与坐标轴对应 self.series.attachAxis(self.axisY) self.series.setColor(QColor(126,211,33))#设置曲线的颜色 def handle_update(self,ydata): self.series.append(QPointF(ydata[0],ydata[1])) if __name__ == "__main__": app = QApplication(sys.argv) mywindow = Window() mywindow.show() sys.exit(app.exec_())