Не удается сделать отрисовку в процессе
Мне нужно параллельно рассчитывать данные для точек и рисовать их в двух процессах, но в одном графике. Попробовал одну коллекцию поместить в процесс, данные не рисуются, хотя считаются. Если запустить просто как обычную функцию 'print_func', то все рисуется.
import numpy as np
from PyQt5 import QtWidgets, QtChart
from PyQt5.QtCore import *
from multiprocessing import Process
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self._chart_view = QtChart.QChartView()
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(self._chart_view)
self.adjust_axes()
def print_func(self):
scatterU = QtChart.QScatterSeries()
scatterU.setColor(Qt.darkGreen)
scatterU.setMarkerSize(10.0)
U1 = np.random.random(50)
U2 = np.random.random(50)
for i in range(0, 50):
scatterU.append(U1[i], U2[i])
self.window()._chart_view.chart().addSeries(scatterU)
def adjust_axes(self):
D1 = np.random.random(50)
D2 = np.random.random(50)
chart = QtChart.QChart()
scatterD = QtChart.QScatterSeries()
scatterD.setColor(Qt.darkBlue)
scatterD.setMarkerSize(10.0)
for i in range(0, 50):
scatterD.append(D1[i], D2[i])
chart.addSeries(scatterD)
chart.createDefaultAxes()
self._chart_view.setChart(chart)
procs = []
proc = Process(target=self.print_func)
procs.append(proc)
proc.start()
procs[0].join()
#self.print_func()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Вы не можете взаимодействовать с виджетами в дополнительных потоках.
В дополнительных потоках вы оперируете только с какими-то данными,
затем посредством сигналов эти данные передаются в основной поток
и уже в основном потоке вставляете эти данные в виджеты.
Возможный вариант решения выглядит примерно так:
import numpy as np
from PyQt5 import QtCore, QtGui, QtWidgets, QtChart
from PyQt5.QtCore import *
class Thread(QtCore.QThread):
threadStart = QtCore.pyqtSignal(int)
threadData = QtCore.pyqtSignal(int, object, object)
threadFinish = QtCore.pyqtSignal(int)
def __init__(self, id):
super().__init__()
self.id = id
def run(self):
self.threadStart.emit(self.id)
self.msleep(100)
while True:
U1 = np.random.random(50)
U2 = np.random.random(50)
for i in range(0, 50):
self.threadData.emit(self.id, U1[i], U2[i])
self.msleep(10) # отрегулируйте интервал паузы в мс.
self.threadFinish.emit(self.id)
self.msleep(100) # отрегулируйте интервал паузы в мс.
self.threadStart.emit(self.id)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._chart_view = QtChart.QChartView()
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QVBoxLayout(central_widget)
lay.addWidget(self._chart_view)
self.adjust_axes()
self.thread_1 = Thread(1)
self.thread_1.threadStart.connect(self.print_start)
self.thread_1.threadData.connect(self.print_func)
self.thread_1.threadFinish.connect(self.print_finish)
self.thread_1.start()
self.thread_2 = Thread(2)
self.thread_2.threadStart.connect(self.print_start)
self.thread_2.threadData.connect(self.print_func)
self.thread_2.threadFinish.connect(self.print_finish)
self.thread_2.start()
def print_start(self, id):
if id == 1:
self.scatterU_1 = QtChart.QScatterSeries()
self.scatterU_1.setColor(Qt.darkGreen)
self.scatterU_1.setMarkerSize(10.0)
elif id == 2:
self.scatterU_2 = QtChart.QScatterSeries()
self.scatterU_2.setColor(Qt.darkRed)
self.scatterU_2.setMarkerSize(10.0)
def print_finish(self, id):
if id == 1:
self.window()._chart_view.chart().addSeries(self.scatterU_1)
elif id == 2:
self.window()._chart_view.chart().addSeries(self.scatterU_2)
def print_func(self, id, U1, U2):
if id == 1:
self.scatterU_1.append(U1, U2)
elif id == 2:
self.scatterU_2.append(U1, U2)
def adjust_axes(self):
D1 = np.random.random(50)
D2 = np.random.random(50)
chart = QtChart.QChart()
scatterD = QtChart.QScatterSeries()
scatterD.setColor(Qt.darkBlue)
scatterD.setMarkerSize(20.0)
for i in range(0, 50):
scatterD.append(D1[i], D2[i])
chart.addSeries(scatterD)
chart.createDefaultAxes()
self._chart_view.setChart(chart)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
