【发布时间】:2020-05-08 09:39:08
【问题描述】:
这里是场景,我使用QThreadPool并行执行不同的功能。我有一个名为self.firstRun = [] 的列表和一个函数,该列表以下列方式使用。
def setdata(self):
self.firstRun.append(1)
print(self.firstRun)
time.sleep(5)
这个函数被另一个名为wait2的函数调用
def wait2(self):
worker = Worker(self.setdata)
self.threadpool.start(worker)
可以看出,函数wait2 调用类Worker 并将函数setdata 发送到该类以进行线程化。当我执行这个程序时,我希望函数setdata 在第一次运行时会给我[1] 作为输出,在第二次运行时给我[1,1],依此类推。 (我已经包含了 sleep 只是为了清楚地阅读输出)。但问题是,当我执行这个程序时,它会在第一次运行时给出以下输出。
[1]
[1, 1]
[1, 1, 1]
[1, 1, 1, 1]
我希望程序首先给出[1],然后随着它进一步执行,它应该给我一个递增的列表。这是完整的代码
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import*
from PyQt5.QtWidgets import*
from PyQt5.QtCore import*
from pyqtgraph import PlotWidget
import time
import numpy as np
class Worker(QRunnable):
def __init__(self, fn, *args, **kwargs):
super(Worker, self).__init__()
self.fn = fn
self.args = args
self.kwargs = kwargs
@pyqtSlot()
def run(self):
result = self.fn(*self.args,**self.kwargs)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1000, 800)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.widget = PlotWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(19, 19, 300, 300))
self.widget.setObjectName("widget")
self.widget_2 = PlotWidget(self.centralwidget)
self.widget_2.setGeometry(QtCore.QRect(350, 20, 300, 300))
self.widget_2.setObjectName("widget_2")
self.widget_3 = PlotWidget(self.centralwidget)
self.widget_3.setGeometry(QtCore.QRect(680, 20, 300, 300))
self.widget_3.setObjectName("widget_3")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(40, 420, 141, 41))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(210, 420, 141, 41))
self.pushButton_2.setObjectName("pushButton_2")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(50, 490, 311, 31))
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(40, 540, 61, 21))
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setGeometry(QtCore.QRect(170, 540, 61, 21))
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName("label_3")
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setGeometry(QtCore.QRect(300, 540, 61, 21))
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
self.label_4.setObjectName("label_4")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.firstRun = []
self.x = []
self.y = []
self.data_line1 = self.widget.plot(self.x,self.y)
self.timer = QtCore.QTimer()
self.timer.setInterval(10)
self.timer.timeout.connect(self.wait2)
self.timer.start()
self.threadpool = QThreadPool()
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Start"))
self.pushButton_2.setText(_translate("MainWindow", "Stop"))
self.label.setText(_translate("MainWindow", "Text"))
self.label_2.setText(_translate("MainWindow", "TextLabel"))
self.label_3.setText(_translate("MainWindow", "TextLabel"))
self.label_4.setText(_translate("MainWindow", "TextLabel"))
def wait2(self):
worker = Worker(self.setdata)
self.threadpool.start(worker)
def setdata(self):
self.firstRun.append(1)
print(self.firstRun)
time.sleep(5)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
最后我必须说,我使用了来自网站 Learpyqt.com 的 QThreadPool 部分代码
编辑 1
当我从QTimer 分离函数wait2 并将其绑定到按钮pushButton_2 时,每次单击该按钮时,它都会给出所需的结果。
但我希望它附加QTimer 以自动更新此功能setdata。
self.pushButton_2.clicked.connect(self.wait2)
编辑 2
当我从 setdata 函数中删除睡眠时,它会按我的意愿工作。但是由于这个程序是我的大项目的一部分,而不是 time.sleep() 我有多个读取函数,它们从其他 python 文件中读取数据。这会导致延迟,我根本无法消除。因此,即使我在这种情况下删除 time.sleep(),也不能解决我原来的问题。
编辑 3
我正在读取多个传感器,压力、温度、加速度计、陀螺仪、磁力计。每个传感器的读取时间都不同。我优先考虑陀螺仪、加速度计和磁力计以获得最大采样率。当我一次读取所有传感器时,所有这些中最慢的是温度,因此所有传感器都必须等到读取温度。因此,它降低了其他传感器的采样率。这就是我引入 QThreading 的原因,以便我可以将温度、压力与加速度计、磁力计、陀螺仪分开。现在,假设我每 10 毫秒调用一次函数(保持温度和压力),其顺序是它先读取温度,然后读取压力,然后它应该保持这个顺序。但在我的情况下,它有时会覆盖温度并转向压力,有时会读取温度 10 次,然后读取压力一次。这种不规则的读数是基本问题。
编辑 4
这是我之前做过的
self.timer_1 = QtCore.QTimer()
self.timer_1.setInterval(1)
self.timer_1.timeout.connect(self.getValues)
self.timer_1.start()
self.timer_2 = QtCore.QTimer()
self.timer_2.setInterval(10)
self.timer_2.timeout.connect(self.UpdatePlot_1)
self.timer_2.start()
self.timer_3 = QtCore.QTimer()
self.timer_3.setInterval(10)
self.timer_3.timeout.connect(self.UpdatePlot_2)
self.timer_3.start()
def UpdatePlot_1(self):
if self.Lstartbutton:
self.plot_1.setData(self.t,self.temperature)
self.plot_2.setData(self.t,self.pressure)
def UpdatePlot_2(self):
if self.Lstartbutton:
self.plot_3.setData(self.t,self.roll)
self.plot_4.setData(self.t,self.rollDrift)
self.plot_5.setData(self.t,self.rollAccel)
def getValues(self):
if len(self.firstRun) <= 50:
self.firstRun.append(1)
self.t = np.arange(1,len(self.firstRun)+1)
gyro2.updateGyroValues()
gyro2.updateHeadings()
xi,yi,xii,yii,zii,s1,s2 = gyro2.printHeadings()
xiii,yiii,ziii = compass.axes()
temperature = sensor.read_temperature()
pressure = sensor.read_pressure()
self.temperature.append(temperature)
self.pressure.append(pressure)
self.roll.append(xii)
self.rollDrift.append(s1)
self.pitch.append(yii)
self.pitchDrift.append(s2)
self.rollAccel.append(xi)
self.pitchAccel.append(yi)
else:
self.t = list(self.t)
self.firstRun1.append(1)
self.t = self.t[1:]
self.t.append(self.t[-1]+1)
gyro2.updateGyroValues()
gyro2.updateHeadings()
xi,yi,xii,yii,zii,s1,s2 = gyro2.printHeadings()
xiii,yiii,ziii = compass.axes()
temperature = sensor.read_temperature()
pressure = sensor.read_pressure()
self.temperature = self.temperature[1:]
self.pressure = self.pressure[1:]
self.pressure.append(pressure)
self.temperature.append(temperature)
self.roll = self.roll[1:]
self.pitch = self.pitch[1:]
self.rollDrift = self.rollDrift[1:]
self.pitchDrift = self.pitchDrift[1:]
self.rollAccel = self.rollAccel[1:]
self.pitchAccel = self.pitchAccel[1:]
self.roll.append(xii)
self.rollDrift.append(s1)
self.pitch.append(yii)
self.pitchDrift.append(s2)
self.rollAccel.append(xi)
self.pitchAccel.append(yi)
这种方法读取相同功能的所有传感器。这种情况下的采样率是 9 个读数/秒。当我从此块中删除温度和压力时 采样率急剧增加到 100 个样本/秒。所以我使用了以下解决方案(目前失败)。
self.timer_2 = QtCore.QTimer()
self.timer_2.setInterval(1)
self.timer_2.timeout.connect(self.thread_2)
self.timer_2.start()
def getValues2(self):
temperature = sensor.read_temperature()
pressure = sensor.read_pressure()
self.temperature.append(temperature)
self.pressure.append(pressure)
def thread_2(self):
worker = Worker(self.getValues2)
self.threadpool.start(worker)
这使得陀螺仪、加速度计和磁力计的读数独立于温度和压力传感器。所以现在我可以更快地阅读。但是当我尝试绘制温度和压力与时间的关系时。然后它失败了,因为正如我之前所说,温度和压力以不规则的方式读取,这使得各个列表的长度不相等,因此无法绘制
【问题讨论】: