python - 是否可以从 PyQt5 的线程中获取数组?

标签 python multithreading pyqt5 pyqtgraph

我创建了一个代码,它从示波器获取信号并在 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()

最佳答案

尝试一下:

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()

enter image description here

关于python - 是否可以从 PyQt5 的线程中获取数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54525233/

相关文章:

python - 根据用户输入动态更改标签文本

python - 从字典选择中填充 pyqt5 输入

python - 在 pyplot 水平堆积条形图 (barh) 中操作顶部和底部边距

java - 使用不可变数据的惰性初始化总是线程安全的吗?

python - 如何在发送到 Spring Boot 休息 Controller 的请求正文中保留换行符

swift - 在 cocoa 后台连续运行代码

java - HBase多线程扫描真的很慢

python - 在 PyQt 中单击时悬停事件

python - 按键值对对列表字典进行排序

python - 未绑定(bind)本地错误 : local variable 'rows' referenced before assignment