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_()) 
 



















