Kevin__Cao 2021-06-04 16:21 采纳率: 71.4%
浏览 319
已结题

pythonPyside2 使用threading.Timer循环定时器导致QT界面卡死?

下面是我写的一个可以读取CSV文件并将其数据在QT界面绘图的程序,由于CSV文件是不断更新的,所以我在 handleCalc13结尾加了threading.Timer循环定时器,当我点击handleCalc13对应的pushbutton后,可以让handleCalc13中的代码每隔0.1秒执行一次,即不断更新绘图,但实际上我点击后QT界面就卡死不动了,请问该如何解决?(如果不加threading.Timer循环定时器,手动不断点击pushbutton是可以不断更新绘图的)


 
class MyFigureCanvas(FigureCanvas):
    '''
    通过继承FigureCanvas类,使得该类既是一个PyQt5的Qwidget,又是一个matplotlib的FigureCanvas,这是连接pyqt5与matplotlib的关键
    '''

    def __init__(self, parent=None, width=10, height=5, xlim=(0, 2500), ylim=(-2, 2), dpi=100):
        # 创建一个Figure
        fig = plt.Figure(figsize=(width, height), dpi=dpi,
                         tight_layout=True)  # tight_layout: 用于去除画图时两边的空白

        FigureCanvas.__init__(self, fig)  # 初始化父类
        self.setParent(parent)

        self.axes = fig.add_subplot(
            111)  # 调用figure下面的add_subplot方法,类似于matplotlib.pyplot下面的subplot方法
        self.axes.spines['top'].set_visible(False)  # 去掉上面的横线
        self.axes.spines['right'].set_visible(False)
        self.axes.set_xlim(xlim)
        self.axes.set_ylim(ylim)

class Stats:

    def __init__(self):
        # 从文件中加载UI定义
        qfile_stats = QFile("D:/PyCharm 2019.1.1/临时程序文件/ui/UR3-control.ui")
        qfile_stats.open(QFile.ReadOnly)
        qfile_stats.close()
        # 从 UI 定义中动态 创建一个相应的窗口对象
        # 注意:里面的控件对象也成为窗口对象的属性了
        # 比如 self.ui.button , self.ui.textEdit
        self.ui = QUiLoader().load(qfile_stats)
        global bujing
        global bujing1

        self.ui.pushButton_1.clicked.connect(self.handleCalc1)
        self.ui.pushButton_2.clicked.connect(self.handleCalc2)
        self.ui.pushButton_3.clicked.connect(self.handleCalc3)
        self.ui.pushButton_4.clicked.connect(self.handleCalc4)
        self.ui.pushButton_5.clicked.connect(self.handleCalc5)
        self.ui.pushButton_6.clicked.connect(self.handleCalc6)
        self.ui.pushButton_7.clicked.connect(self.handleCalc7)
        self.ui.pushButton_8.clicked.connect(self.handleCalc8)
        self.ui.pushButton_9.clicked.connect(self.handleCalc9)
        self.ui.pushButton_10.clicked.connect(self.handleCalc10)
        self.ui.pushButton_11.clicked.connect(self.handleCalc11)
        self.ui.pushButton_13.clicked.connect(self.handleCalc13)
        self.gv_visual_data_content = MyFigureCanvas(width=self.ui.graphicsView.width() / 101,
                                                     height=self.ui.graphicsView.height() / 101,
                                                     xlim=(450, 801),
                                                     ylim=(60, 120))  # 实例化一个FigureCanvas

    #光谱图的绘制
    def handleCalc13(self):
        global timer1
        exampleFile = open(r'%s'%lujing_path)  # 打开csv文件
        exampleReader = csv.reader(exampleFile)  # 读取csv文件
        exampleData = list(exampleReader)
        x_ = list()
        y_ = list()
        for i in range(262, 1188):  # 从第二行开始读取
            x_ .append(float(exampleData[i][0]))  # 将第一列数据从第二行读取到最后一行赋给列表x
            y_ .append(float(exampleData[i][1]))  # 将第二列数据从第二行读取到最后一行赋给列表
        self.gv_visual_data_content.axes.clear()  # 由于图片需要反复绘制,所以每次绘制前清空,然后绘图
        # 初始化 gv_visual_data 的显示
        self.gv_visual_data_content = MyFigureCanvas(width=self.ui.graphicsView.width() / 101,
                                                     height=self.ui.graphicsView.height() / 101,
                                                     xlim=(450, 801),
                                                     ylim=(60, 120))  # 实例化一个FigureCanvas
        self.gv_visual_data_content.axes.plot(x_ , y_ )
        self.gv_visual_data_content.axes.set_title('骨组织漫反射光谱') # 设置标题
        self.gv_visual_data_content.axes.set_xlabel(u'波长', size=10)  # 设置x轴名为“x轴名”
        self.gv_visual_data_content.axes.set_ylabel(u'强度', size=10)  # 设置y轴名为“y轴名”
        # 加载的图形(FigureCanvas)不能直接放到graphicview控件中,必须先放到graphicScene,然后再把graphicscene放到graphicview中
        self.graphic_scene = QGraphicsScene()  # 创建一个QGraphicsScene
        self.graphic_scene.addWidget(
            self.gv_visual_data_content)  # 把图形放到QGraphicsScene中,注意:图形是作为一个QWidget放到放到QGraphicsScene中的
        self.ui.graphicsView.setScene(self.graphic_scene)  # 把QGraphicsScene放入QGraphicsView
        self.ui.graphicsView.show()  # 调用show方法呈现图形
        self.gv_visual_data_content.draw()  # 刷新画布显示图片,否则不刷新显示
        self.gv_visual_data_content.flush_events()
        timer1 = threading.Timer(0.1, self.handleCalc13)
        timer1.start()

 

  • 写回答

3条回答 默认 最新

  • CSDN专家-黄老师 2021-06-04 16:23
    关注

    应该是程序执行响应不过来,导致卡顿了。将绘图的功能用线程执行,不要在主线程执行

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 10月2日
  • 已采纳回答 9月24日

悬赏问题

  • ¥15 逻辑谓词和消解原理的运用
  • ¥15 请求分析基于spring boot+vue的前后端分离的项目
  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥200 关于#c++#的问题,请各位专家解答!网站的邀请码
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?