【问题标题】:PyQt5 Real time plotting Threading from device [duplicate]PyQt5实时绘制来自设备的线程[重复]
【发布时间】:2021-03-19 07:00:43
【问题描述】:

我目前正在构建软件以从设备接收数据并在我的 GUI 上实时绘图。这组数据来自设备的列表。我查了很多方法,似乎“计时器”很有用。但是,当我尝试使用它进行绘图时,它不起作用并崩溃。以下是我从设备接收数据的线程。 freqsweep_max 是从设备 API 文件中定义的。

class Worker(QThread):
    signal_x = pyqtSignal(object, object)


    def __init__(self):
        super().__init__()


    def run(self):
        while True:

            self.data_x = freqs
            self.data_y = sweep_max
            self.signal_x.emit(self.data_x, self.data_y)
            time.sleep(0.1)

以下是我的带有 GUI 的主要 python 文件。

import sys
from PyQt5.QtCore import *
from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import *
import LLAGUI1
from SignalThread import MyWidget, Worker

from sadevice.sa_api import *


from PyQt5 import QtCore, QtWidgets
import pyqtgraph as pg



class MainClass(QDialog,LLAGUI1.Ui_Dialog):

    def __init__(self):
        super().__init__()
        self.setupUi(self)

        ############Part of real time plotting but getting error because of plotCurve has no input
        self.timer = QtCore.QTimer(self)
        self.timer.setInterval(100) # in milliseconds
        self.timer.start()
        self.timer.timeout.connect(self.plotCurve)
        #############################################################################
        
        self.mywid = pg.GraphicsWindow()
        self.plotItem = self.mywid.addPlot(title="Linewidth Measurement")
        self.plotDataItem = self.plotItem.plot([], symbolSize=1, symbolPen=None)
        self.graphWidget.addItem(self.plotDataItem)
        self.make_connection()


    def make_connection(self):
        self.w = Worker()
        self.w.start()
        self.w.signal_x.connect(self.plotCurve)


    def plotCurve(self, x, y):
        self.plotDataItem.setData(x,y)
        print(x)
        print(y)


if __name__=='__main__':
    app=QApplication(sys.argv)


    lla=MainClass()
    lla.show()
    app.exec_()

由于没有输入 plotCurve,我的以下部分代码出现错误。如果不遵循 4 行,曲线就不是实时的,即使它一直在接收数据,它也只是绘制并停止。我试图将make_connection 放在那里,但它也给了我错误。

self.timer = QtCore.QTimer(self)
        self.timer.setInterval(100) # in milliseconds
        self.timer.start()
        self.timer.timeout.connect(self.plotCurve)

请把我从这个线程错误中解救出来,我真的很感激任何想法! 谢谢!

【问题讨论】:

  • 您正在访问未定义的属性。你在哪里设置属性MainClass.plotCurve
  • @bnaecker 我不确定我是否正确理解了您的问题。你的意思是我没有定义 plotCurve 吗?如果是这样,如果向下滚动,它会在MainClass 中定义。如果你的意思是plotCurve 的输入,它没有设置,我不知道在哪里设置它,因为它应该是实时输入。 make_connection 正在接收线程数据并传递给plotCurve
  • 啊,我错过了,忽略我:)

标签: python multithreading plot pyqt5


【解决方案1】:

好的,经过一番搜索,this的帖子帮了大忙!

对于那些可能遇到类似问题的人,以下是我修改后的代码。我对 pyqtSlot 的理解并不完全正确。

class MainClass(QDialog,LLAGUI1.Ui_Dialog):

    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.worker = Worker()
        self.make_connection(self.worker)
        self.worker.start()
        self.graph = pg.PlotWidget()
        self.graph.setYRange(-120,10)
        self.plot = self.graph.plot()
        self.gridLayout_graph.addWidget(self.graph, 0, 0)
        self.show()

        self.pushButton_amp_set.clicked.connect(self.setAmp)


    def make_connection(self, data_object):
        data_object.signal.connect(self.grab_data)

    @pyqtSlot(object, object)
    def grab_data(self, data, data1):
        print(data)
        print(data1)
        self.plot.setData(data, data1)

    #
    # def onStart(self):
    #     self.curve = MyWidget()
    #     # self.verticalLayout_3.
    #     self.verticalLayout_3.addWidget(self.curve)

    def setAmp(self):
        Min = float(self.lineEdit_amp_min.text())
        Max = float(self.lineEdit_amp_max.text())
        self.graph.setYRange(Min, Max)

    def CenterSpan(self):
        center = int(self.lineEdit_freq_center.text())
        span = int(self.lineEdit_freq_span.text())

        sa_config_center_span(handle, center, span)
        # self.w = MyWidget()






if __name__=='__main__':
    app=QApplication(sys.argv)

    lla=MainClass()
    lla.show()

    app.exec_()

工作线程如下:

class Worker(QThread):
    signal = pyqtSignal(object, object)

    def __init__(self):
        super().__init__()

    def run(self):
        while True:
            freqs = [start_freq + i * bin_size for i in range(sweep_length)]
            sweep_max = list(sa_get_sweep_32f(handle)["max"])
            self.data_x = freqs
            self.data_y = sweep_max
            self.signal.emit(self.data_x, self.data_y)
            time.sleep(0.01)

【讨论】:

    猜你喜欢
    • 2018-10-02
    • 1970-01-01
    • 1970-01-01
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    相关资源
    最近更新 更多