是否可以从 PyQt5 中的线程获取数组?
Posted
技术标签:
【中文标题】是否可以从 PyQt5 中的线程获取数组?【英文标题】:Is it possible to get an array from a thread in PyQt5? 【发布时间】:2019-06-28 17:31:36 【问题描述】:我创建了一个代码,该代码从示波器获取信号并在 GUI 内的 pyqtGraph 中实时绘图,但它是锁定的。我正在尝试使用Qthread解锁GUI,但我是一个业余程序员,我不知道这是否正确。
因此,我在不使用示波器的情况下继续尝试使用此代码,并尝试在线程中进行计算并保持 GUI 运行,但我被卡住了。有没有办法在不锁定 GUI 的情况下获取数组 self.s 并制作实时绘图?
import pyqtgraph as pg
import numpy as np
import time
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal
class plotarT(QThread):
signal = pyqtSignal('PyQt_PyObject')
def __init__(self):
QThread.__init__(self)
def __del__(self):
self.wait()
def update(self):
self.phase = 0
self.t = np.arange(0, 3.0, 0.01)
self.s = np.sin(2 * np.pi * self.t + self.phase) #Sin function
self.phase += 0.1
time.sleep(2) #To simulate the time that oscilloscope take to respond
def run(self):
self.update()
self.signal.emit('QObject')
class Window(QDialog):
def __init__(self):
self.app = QtGui.QApplication(sys.argv)
super().__init__()
self.title = "PyQt5 GridLayout"
self.top = 100
self.left = 100
self.width = 1000
self.height = 600
self.InitWindow()
self.traces = dict()
pg.setConfigOptions(antialias=True)
def InitWindow(self):
self.setWindowIcon(QtGui.QIcon("icon.png"))
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.gridLayoutCreation()
vboxLayout = QVBoxLayout()
vboxLayout.addWidget(self.groupBox)
self.setLayout(vboxLayout)
self.show()
def gridLayoutCreation(self):
self.groupBox = QGroupBox("Grid Layout Example")
gridLayout = QGridLayout()
self.guiplot = pg.PlotWidget()
gridLayout.addWidget(self.guiplot,0,8,8,12)
self.groupBox.setLayout(gridLayout)
gridLayout.addWidget(QLabel('Tempo'), 0,0)
self.time = QLineEdit('')
gridLayout.addWidget(self.time, 1,0)
def plotar(self):
self.guiplot.clear()
self.guiplot.plot(s)
#self.guiplot.plot(c)
def teste(self):
self.get_thread = plotarT()
self.get_thread.start()
def main():
app = QtGui.QApplication(sys.argv)
form = Window()
form.show()
form.teste()
app.exec_()
if __name__ == '__main__':
main()
【问题讨论】:
signal = pyqtSignal(object)
... self.signal.emit(self.s)
【参考方案1】:
试试看:
import pyqtgraph as pg
import numpy as np
#import time
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal
class plotarT(QThread):
signal = pyqtSignal(object) # object
def __init__(self, parent=None):
super().__init__()
self.s = None # +++
self.phase = 0 # +++
def __del__(self):
self.wait()
def update(self):
# self.phase = 0 # ---
self.t = np.arange(0, 3.0, 0.01)
self.s = np.sin(2 * np.pi * self.t + self.phase) # Sin function
self.phase += 0.1
QThread.msleep(200) # time.sleep(0.2)
def run(self):
for i in range(100): # +++ Some cycle
self.update()
self.signal.emit(self.s) # self.s
class Window(QDialog):
def __init__(self):
# self.app = QtGui.QApplication(sys.argv)
super().__init__()
self.title = "PyQt5 GridLayout"
self.top = 100
self.left = 100
self.width = 1000
self.height = 600
self.InitWindow()
self.traces = dict()
pg.setConfigOptions(antialias=True)
def InitWindow(self):
self.setWindowIcon(QtGui.QIcon("icon.png"))
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.gridLayoutCreation()
vboxLayout = QVBoxLayout()
vboxLayout.addWidget(self.groupBox)
self.setLayout(vboxLayout)
self.show()
def gridLayoutCreation(self):
self.groupBox = QGroupBox("Grid Layout Example")
gridLayout = QGridLayout()
self.guiplot = pg.PlotWidget()
gridLayout.addWidget(self.guiplot,0,8,8,12)
self.groupBox.setLayout(gridLayout)
gridLayout.addWidget(QLabel('Tempo'), 0,0)
self.timeEdit = QLineEdit('') # time <-> timeEdit
gridLayout.addWidget(self.timeEdit, 1,0) # time <-> timeEdit
def plotar(self, s):
self.guiplot.clear()
self.guiplot.plot(s)
#self.guiplot.plot(c)
def teste(self):
self.get_thread = plotarT()
self.get_thread.signal.connect(self.displayS) # <--- +++
self.get_thread.start()
def displayS(self, self_s): # <--- +++
""" Here is your `self.s` array.
Draw a graph in real time without blocking the graphical interface.
"""
# print("\n Here is your `self.s` array. \n", self_s)
self.plotar(self_s)
def main():
app = QApplication(sys.argv) # QtGui.
form = Window()
form.show()
form.teste()
app.exec_()
if __name__ == '__main__':
main()
【讨论】:
以上是关于是否可以从 PyQt5 中的线程获取数组?的主要内容,如果未能解决你的问题,请参考以下文章