Home > Software engineering >  How to solve the self-crash problem of running multiple pyqt or pyqtgraph drawing components?
How to solve the self-crash problem of running multiple pyqt or pyqtgraph drawing components?

Time:04-01

enter image description here

I designed the interface, and the custom component tried to output multiple drawing components, and the program crashed after a while.

The program probably consists of the following:ble. Py reads the bluetooth values temporarily holding the EMG array. main_plot.py instantiates the Show_EMG plotting class and outputs the Show_EMG plotting class reading the Bluetooth values of ble.PY

The program crashed itself without reporting any errors, I tried to output errors at different terminals.

ERROR MESSAGE: enter image description here

enter image description here

CMD: enter image description here

pyqtgraph Component Code(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[data]
        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=[self.ptr1,self.ptr1 self.length],yRange=[5,550],padding=0)
            self.data1[:-1] = self.data1[1:]  # 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 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")

                Show_EMG.Plot_Show(Form=Form, y=10, x=10, data=0, text="sEMG2 Voltage")
        Show_EMG.Plot_Show(Form=Form, y=10, x=140, data=1, text="sEMG2 Voltage")
        Show_EMG.Plot_Show(Form=Form, y=10, x=270, data=2, text="sEMG3 Voltage")
        Show_EMG.Plot_Show(Form=Form, y=280, x=10, data=3, text="sEMG4 Voltage")
        Show_EMG.Plot_Show(Form=Form, y=280, x=140, data=4, text="sEMG5 Voltage")
        Show_EMG.Plot_Show(Form=Form, y=280, x=270, data=5, text="sEMG6 Voltage")
        Show_EMG.Plot_Show(Form=Form, y=550, x=10, data=0, text="sEMG7 Voltage")
        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_main=threading.Thread(target=main)
    thread_main.start()
    thread_ble=threading.Thread(target=ble.ble)
    thread_ble.start()

Ble.EMG array default temporarily to:[200. 0. 0. 0. 0. 0.]

More Ble Code detail: enter image description here

Frankly, if all plots get data from the same source and in the same time then you could use one QTimer to run all update1 in all plots - but this timer should be in UIForm instead of PlotShow

  • Related