Вот сценарий, я использую 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]
во втором и так далее. (Я включил режим сна только для четкого чтения вывода). Но проблема в том, что когда я запускаю эту программу, она при первом запуске дает следующее.
[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_())
В последнем я должен сказать, что я использовал часть кода QThreadPool
с веб-сайта Learpyqt.com
Edit 1
Когда я отсоединяю функцию wait2
от QTimer
и привязываю ее к кнопке pushButton_2
, то каждый раз, когда я нажимаю кнопку, это дает желаемый результат. Но я хочу, чтобы он был прикреплен к QTimer
, чтобы эта функция setdata
обновлялась автоматически.
self.pushButton_2.clicked.connect(self.wait2)
Edit 2
Когда я удаляю сон из setdata функция тогда работает как я хочу. Но поскольку эта программа является частью моего большого проекта, в котором вместо time.sleep () у меня есть несколько функций чтения, которые считывают данные из других python файлов. Это вызывает задержку, которую я просто не могу устранить. Таким образом, даже если я удалю time.sleep () в этом случае, это не решит мою исходную проблему.
Edit 3
Я читаю несколько датчиков, давление , Температура, акселерометр, гироскоп, магнитометр. Время считывания разное для каждого из этих датчиков. Я отдаю предпочтение гироскопу, акселерометру и магнитометру, чтобы получить максимальную частоту дискретизации. Когда я считываю данные со всех датчиков одновременно, самым медленным из них является температура, поэтому все датчики должны ждать, пока не будет считана температура. Таким образом, это снижает частоту дискретизации других датчиков. Вот почему я ввел QThreading, чтобы я мог отделить температуру, давление от акселерометра, магнитометра и гироскопа. Теперь предположим, что я вызываю функцию (которая удерживает температуру и давление) каждые 10 мс в таком порядке, что сначала она считывает температуру, а затем давление, а затем должна поддерживать этот порядок. Но в моем случае он иногда переопределяет температуру и переходит к давлению, а иногда считывает температуру 10 раз, а затем 1 раз давление. Это нерегулярное чтение является основной проблемой c.
Редактировать 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 показаний / сек c. Когда я удаляю из этого блока температуру и давление, частота дискретизации резко увеличивается до 100 выборок в секунду c. Поэтому я использовал следующее решение (пока не удалось).
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)
Это сделало показания гироскопа, акселерометра и магнитометра независимыми от датчика температуры и давления. Так что теперь я могу читать намного быстрее. Но когда я пытаюсь построить график зависимости температуры и давления от времени. Затем он терпит неудачу, потому что, как я сказал ранее, температура и давление считываются нерегулярно, что делает длину соответствующих списков неравной, поэтому не может быть нанесен на график