如何解决运行多个PYQT或PYQTGRAPH绘图组件的自我崩溃问题?
我设计了界面,自定义组件尝试输出多个绘图组件,过了一会程序就崩溃了。
该程序可能包含以下内容:ble. Py
读取临时保存 EMG 数组的蓝牙值。 main_plot.py
实例化Show_EMG绘图类并输出Show_EMG绘图类读取ble.PY
的蓝牙值
程序自行崩溃,没有报告任何错误,我尝试输出错误在不同的航站楼。
pyqtgraph 组件代码(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 代码:
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 数组暂时默认为:[200. 0. 0. 0. 0. 0.]
更多 Ble 代码详细信息: https://gist.github.com/allrobot/1547447f313942f278118cb2e569f59f
我尝试在main_plot.py,但程序仍然自行崩溃...
也许 QTimer 应该是问题的原因?
如何更改代码来解决自崩溃问题?我需要修复自定义组件类,但我是 PyQT 的新手,您有什么建议吗?
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.
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:
https://gist.github.com/allrobot/1547447f313942f278118cb2e569f59f
I tried to add threads in main_plot.py, but the program still crashes itself...
Perhaps QTimer should be the cause of the problem?
How can I change the code to solve the self-crash problem?I need to fix the custom component classes, but I am novice to PyQT, you have any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如您已经知道(所有)GUI不应在分离的线程中运行。
但是我用代码遇到的主要问题是,如果未分配给全球变量或类变量,则PYQT中的某些元素无效。
当
绘图
未分配给变量时,其qtimer
对我不起作用。因此,我将所有情节都放在列表上,现在所有QTimers(没有特殊线程)对我有用。
完整的工作代码。
我使用类
ble
仿真模块ble.py
,并将所有代码在一个文件中(用于测试)。我还做了一些小更改: pep 8- python代码的样式指南
坦率地说,如果所有图都从同一源获取数据,则可以在所有图中使用一个qtimer运行所有
update1
- 但是此计时器应在usiform
而不是plotshow
编辑中:
版本仅使用一个
qtimer
inuiform
要执行update_plot()
for Listself.plots
上的所有图。As you already know (all) GUIs shouldn't run in separated thread.
But main problem which I had with code is that some elements in PyQt don't work if they are not assigned to global or class variables.
And when
Plot
is not assigned to variable then itsQTimer
doesn't work for me.So I put all Plot on list and now all QTimers (without special threads) works for me.
Full working code.
I used class
ble
to simulate moduleble.py
and to have all code in one file (for tests).I made also few small changes: PEP 8 -- Style Guide for Python Code
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 inUIForm
instead ofPlotShow
EDIT:
Version which use only one
QTimer
inUIForm
to executeupdate_plot()
for all plots on listself.plots
.谢谢@furas和@musicamante建议,问题已经解决。
该错误非常简单。
我将刷新率设置得太快。因为我在自定义组件类中设置
self.timer.timer.start(10)
,所以程序自身崩溃。Thank @furas and @musicamante suggests, the problem is solved.
The bug is surprisingly simple.
I set the refresh rate too fast. Because I setting
self.timer.start(10)
in the custom component class, So the program crashes itself.????It only need settingself.timer.start(100)
, the program can working...