это немного длиннее, первая часть - просто описание проблемы, вторая - вопрос, правильно ли мое "исправление".
Я начал с программирования на Python.Я создал программу, которая связывается с Arduino, которая читает температуру печи нашей плавильной лаборатории.Затем температура используется в алгоритме PID, а выход устанавливается на Arduino.Связь осуществляется через pyserial.Пока что все работает, включая отображение температурных сигналов в реальном времени, ПИД-переменных и так далее.Сценарий включает в себя основной цикл и 3 потока (последовательное соединение, преобразователь данных, считывающий данные из последовательного порта, установленную температуру из QWidget и выходные данные алгоритма PID. Эти значения используются для создания массива для отображения в pyqtgraph. Наконец,третий поток переносит данные из преобразователя данных в QWidget.
При использовании моего Linux-ноутбука все работает нормально, и графический интерфейс никогда не перестает обновляться. Напротив, при использовании любого Windows-хоста у меня естьПроблема в том, что некоторые pyqtgraphs перестают обновляться. Поведение странное, потому что я установил все данные более или менее в одно и то же время, с одним и тем же массивом (только разные столбцы) - некоторые графики обновляются дольше (часы), некоторые останавливаются раньше (минутыПосле поиска более или менее дырки в интернете ;-) Я думаю, что нашел проблему: это передача данных из потока в GUI.Некоторый фиктивный код, объясняющий, что происходит:
DataUpdaterToGUI(QThread):
#sets the QWidget from main loop
def setGUI(self, gui):
self.gui = gui
def run()
while True:
with lock(): # RLock() Instance
copyArray = self.dataArray[:] # copy the array from the shifter
self.gui.plot1.copyArray(dataArray[:, 0], copyArray[:, 1])
self.gui.plot2.copyArray(dataArray[:, 0], copyArray[:, 2])
# self.gui.update()
# QApplication.instance().processEvents()
Ни вызовы self.gui.update (), ни processEvents () не влияют на результат: графики через некоторое время перестают перерисовываться (в окнах).
Теперь у меня есть очень простой пример, и я просто хочу убедиться, правильно ли я использую потоки.Он работает нормально, но у меня есть несколько вопросов:
- Подход с использованием сигнального слота копирует переданные данные?
- Почему нет необходимости вызывать метод update () QWidget?
- Нужно ли использовать какие-либо блокировки при использовании сигналов?
class Main(QWidget):
def __init__(self):
super().__init__()
self.layout = QGridLayout(self)
self.graph = pg.PlotWidget()
self.graph.setYRange(0,1000)
self.plot = self.graph.plot()
self.layout.addWidget(self.graph,0,0)
self.show()
def make_connection(self, data_object):
data_object.signal.connect(self.grab_data)
@pyqtSlot(object)
def grab_data(self, data):
print(data)
self.plot.setData(data)
class Worker(QThread):
signal = pyqtSignal(object)
def __init__(self):
super().__init__()
def run(self):
self.data = [0, 1]
i = 2
while True:
self.data[1] = i
self.signal.emit(self.data)
time.sleep(0.01)
i += 1
if __name__ == "__main__":
app = QApplication(sys.argv)
widget = Main()
worker = Worker()
widget.make_connection(worker)
worker.start()
sys.exit(app.exec_())