allrobot 发表于 2022-3-31 14:48

[Python]请问如何解决pyqt显示多个绘图组件后的自我崩溃问题?

本帖最后由 allrobot 于 2022-3-31 15:51 编辑



我尝试添加多线程运行各自的绘图组件,结果无法显示绘图组件



(Show_EMG.py):
import ble
from pyqtgraph import PlotWidget
import pyqtgraph as pg
import numpy as np
from PyQt5 import QtCore

class Plot_Show(object):
    '''
    Form,y,x,data,length = 1800, width = 250, high = 120, text = "sEMG Voltage"
    '''
    def __init__(self,Form,y,x,data,text=""):
      # length = 1800, width = 250, high = 120, text = "sEMG Voltage"
      self.Form=Form
      self.y=y
      self.x=x
      self.data=ble.EMG
      self.length=1800
      if(text==""):
            self.test="sEMG Voltage"
      else:
            self.text = text
      self.graphicsView = PlotWidget(self.Form)
      self.initUI()


    def initUI(self):

      self.graphicsView.setGeometry(QtCore.QRect(self.y, self.x, 250, 120))
      self.graphicsView.hideButtons()
      self.graphicsView.setObjectName(self.text)


      self.graphicsView.setLabel(axis="left",text=self.text)
      self.graphicsView.setLabel(axis='bottom',text='Time')
      self.graphicsView.setMouseEnabled(x=False,y=False)
      self.graphicsView.setAntialiasing(True)
      self.graphicsView.setMenuEnabled(False)
      self.graphicsView.hideButtons()
      self.data1 = np.zeros(self.length)
      self.curve1 = self.graphicsView.plot(self.data1)
      self.ptr1 = 0

      def update1():
            global data1, ptr1
            self.graphicsView.setRange(xRange=,yRange=,padding=0)
            self.data1[:-1] = self.data1# shift data in the array one sample left

            self.data1[-1] = self.data

            self.ptr1 += 1
            self.curve1.setData(self.data1)
            self.curve1.setPos(self.ptr1, 0)

      self.timer = pg.QtCore.QTimer()
      self.timer.timeout.connect(update1)
      self.timer.start(10)

main_plot.py Code:
import array
import random

from pyqtgraph import PlotWidget
import pyqtgraph as pg
import ble
import sys

import Show_EMG
from PyQt5 import QtCore, QtWidgets
import _thread

class Ui_Form(object):
    def __init__(self):
      super().__init__()

    def setupUi(self, Form,**kwargs):
      Form.resize(820, 454)
      Form.setObjectName("Form")
      plot1 = Show_EMG.Plot_Show(Form=Form, y=10, x=10, data=0, text="sEMG2 Voltage")
      plot2 = Show_EMG.Plot_Show(Form=Form, y=10, x=140, data=1, text="sEMG2 Voltage")
      plot3 = Show_EMG.Plot_Show(Form=Form, y=10, x=270, data=2, text="sEMG3 Voltage")
      plot4 = Show_EMG.Plot_Show(Form=Form, y=280, x=10, data=3, text="sEMG4 Voltage")
      plot5 = Show_EMG.Plot_Show(Form=Form, y=280, x=140, data=4, text="sEMG5 Voltage")
      plot6 = Show_EMG.Plot_Show(Form=Form, y=280, x=270, data=5, text="sEMG6 Voltage")
      plot7 = Show_EMG.Plot_Show(Form=Form, y=550, x=10, data=0, text="sEMG7 Voltage")
      plot8 = Show_EMG.Plot_Show(Form=Form, y=550, x=140, data=0, text="sEMG8 Voltage")



      self.gridLayoutWidget = QtWidgets.QWidget(Form)
      self.gridLayoutWidget.setGeometry(QtCore.QRect(550, 270, 261, 121))
      self.gridLayoutWidget.setObjectName("gridLayoutWidget")
      self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
      self.gridLayout.setContentsMargins(0, 0, 0, 0)
      self.gridLayout.setObjectName("gridLayout")
      self.pushButton = QtWidgets.QPushButton(Form)
      self.pushButton.setGeometry(QtCore.QRect(370, 410, 75, 23))
      self.pushButton.setObjectName("pushButton")

      self.retranslateUi(Form)
      QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
      _translate = QtCore.QCoreApplication.translate
      self.pushButton.setText(_translate("Form", "开始记录"))
      Form.setWindowTitle(_translate("Form", "Form"))

def main():
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    _thread.start_new_thread(main)
    _thread.start_new_thread(ble.ble)

BLE代码的更多细节:https://gist.github.com/allrobot/1547447f313942f278118cb2e569f59f


上面尝试添加多线程,但是没有什么效果,似乎是引用QTimer引发的错误?

请问代码需要作出什么改动,使多个自定义绘图组件不会崩溃呀?

ccwuax 发表于 2022-3-31 14:55

不要用_thread,这个在Pyqt里很容易和它内部冲突导致崩溃,试试threading

allrobot 发表于 2022-3-31 15:04

ccwuax 发表于 2022-3-31 14:55
不要用_thread,这个在Pyqt里很容易和它内部冲突导致崩溃,试试threading

刚才改threading了,还是自我崩溃,看来可能不是多线程的原因,应该是自定义组件类有问题,可不知道哪里出问题了。。。
import ble
import sys

import Show_EMG
from PyQt5 import QtCore, QtWidgets
import threading

class Ui_Form(object):
    def __init__(self):
      super().__init__()

    def setupUi(self, Form,**kwargs):
      Form.resize(820, 454)
      Form.setObjectName("Form")

      thread1=threading.Thread(target=Show_EMG.Plot_Show(Form=Form, y=10, x=10, data=0, text="sEMG2 Voltage"))
      thread2=threading.Thread(target=Show_EMG.Plot_Show(Form=Form, y=10, x=140, data=1, text="sEMG2 Voltage"))
      thread3=threading.Thread(target=Show_EMG.Plot_Show(Form=Form, y=10, x=270, data=2, text="sEMG3 Voltage"))
      thread4=threading.Thread(target=Show_EMG.Plot_Show(Form=Form, y=280,x=10, data=3, text="sEMG4 Voltage"))
      thread5=threading.Thread(target=Show_EMG.Plot_Show(Form=Form, y=280,x=140, data=4, text="sEMG5 Voltage"))
      thread6=threading.Thread(target=Show_EMG.Plot_Show(Form=Form, y=280,x=270, data=5, text="sEMG6 Voltage"))
      thread7=threading.Thread(target=Show_EMG.Plot_Show(Form=Form, y=550,x=10, data=0, text="sEMG7 Voltage"))
      thread8=threading.Thread(target=Show_EMG.Plot_Show(Form=Form, y=550,x=140, data=0, text="sEMG8 Voltage"))

      thread1.start()
      thread2.start()
      thread3.start()
      thread4.start()
      thread5.start()
      thread6.start()
      thread7.start()
      thread8.start()

      self.gridLayoutWidget = QtWidgets.QWidget(Form)
      self.gridLayoutWidget.setGeometry(QtCore.QRect(550, 270, 261, 121))
      self.gridLayoutWidget.setObjectName("gridLayoutWidget")
      self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
      self.gridLayout.setContentsMargins(0, 0, 0, 0)
      self.gridLayout.setObjectName("gridLayout")
      self.pushButton = QtWidgets.QPushButton(Form)
      self.pushButton.setGeometry(QtCore.QRect(370, 410, 75, 23))
      self.pushButton.setObjectName("pushButton")

      self.retranslateUi(Form)
      QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
      _translate = QtCore.QCoreApplication.translate
      self.pushButton.setText(_translate("Form", "开始记录"))
      Form.setWindowTitle(_translate("Form", "Form"))

def main():
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    thread_main=threading.Thread(target=main())
    thread_main.start()
    thread_ble=threading.Thread(target=ble.ble())
    thread_ble.start()

ccwuax 发表于 2022-3-31 15:47

你在线程里修改了主界面就会崩溃,用信号

d8349565 发表于 2022-3-31 15:58

这个是做实时更新的动态折线图么?如果是的话,pyecharts的显示效果更好些吧

allrobot 发表于 2022-3-31 16:05

ccwuax 发表于 2022-3-31 15:47
你在线程里修改了主界面就会崩溃,用信号

嘿!我找到问题所在了,应该是自定义绘图组件类的QTimer引发的问题

这是用CMD运行的效果图



如图所示,第一个绘图组件的没有问题,但后边的绘图组件的绘制速度不一致了

allrobot 发表于 2022-3-31 16:12

d8349565 发表于 2022-3-31 15:58
这个是做实时更新的动态折线图么?如果是的话,pyecharts的显示效果更好些吧

看看,不晓得能嵌入到qt吗

我想绘制动态曲线图的
页: [1]
查看完整版本: [Python]请问如何解决pyqt显示多个绘图组件后的自我崩溃问题?