Динамическое обновление диаграммы PyQt5
Я строю диаграмму в PyQt5, код приведен ниже.
Главное окно связано с другой программой через TCP/IP протокол, данные "ловятся" с помощью функции add_table. Данная функция связана с другим классом, из которого приходит сигнал, о том что поступили новые данные с помощью аттрибута parser.data_signal = 1.
Я пытаюсь добавить новые данные на диграмму с помощью
self.series.append('New data', 5), но диаграмма не обновляется.
Подскажите пожалуйста, что мне делать. Извиняюсь за не совсем репрезентативный пример кода)
from PyQt5 import QtChart
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
from PyQt5.QtChart import QChart, QChartView
from PyQt5.QtGui import QPainter
from PyQt5.QtCore import Qt
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("PyQtChart Pie Chart")
self.setGeometry(100, 100, 1280, 600)
self.show()
self.create_piechart()
add_data_thread = threading.Thread(target = self.add_table)
add_data_thread.start()
def create_piechart(self):
series = QtChart.QPieSeries()
series.append("Python", 80)
series.append("C++", 70)
series.append("Java", 50)
series.append("C#", 40)
series.append("PHP", 30)
series.setLabelsVisible(True)
series.setLabelsPosition(QtChart.QPieSlice.LabelInsideHorizontal)
for slice in series.slices():
slice.setLabel("{:.2f}%".format(100 * slice.percentage()))
chart = QChart()
chart.addSeries(series)
chart.createDefaultAxes()
chart.setAnimationOptions(QChart.SeriesAnimations)
chart.setTitle("Pie Chart Example")
chart.legend().setVisible(True)
chart.legend().setAlignment(Qt.AlignBottom)
chart.legend().markers(series)[0].setLabel("Python")
chart.legend().markers(series)[1].setLabel("C++")
chart.legend().markers(series)[2].setLabel("Java")
chart.legend().markers(series)[3].setLabel("C#")
chart.legend().markers(series)[4].setLabel("PHP")
chartview = QChartView(chart)
chartview.setRenderHint(QPainter.Antialiasing)
self.setCentralWidget(chartview)
def add_table(self):
while True:
if parser.data_signal == 1:
self.add_to_table(self.parser.data)
parser.data_signal = 0
self.series.append('New data', 5)
if __name__ == "__main__":
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec_())
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Попробуйте так:
import sys
import random
#import threading
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtChart import QChart, QChartView, QPieSeries, QPieSlice
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtCore import Qt, QThread, pyqtSignal
class MyThread(QThread): # +++
mysignal = pyqtSignal(int)
def __init__(self, parent=None):
QThread.__init__(self, parent)
def run(self):
while True:
# где-то тут ваша функция, из которого приходит сигнал, # !!1
i = random.randint(0, 1)
self.mysignal.emit(i)
self.msleep(2000)
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("PyQtChart Pie Chart")
self.create_piechart()
# add_data_thread = threading.Thread(target = self.add_table)
# add_data_thread.start()
self.mythread = MyThread() # +++
self.mythread.mysignal.connect(self.add_table) # +++
self.mythread.start() # +++
def create_piechart(self):
self.series = QPieSeries()
self.series.append("Python", 80)
self.series.append("C++", 70)
self.series.append("Java", 50)
self.series.append("C#", 40)
self.series.append("PHP", 30)
self.series.setLabelsVisible(True)
self.series.setLabelsPosition(QPieSlice.LabelInsideHorizontal)
for slice in self.series.slices():
slice.setLabel("{:.2f}%".format(100 * slice.percentage()))
self.chart = QChart()
self.chart.addSeries(self.series)
self.chart.createDefaultAxes()
self.chart.setAnimationOptions(QChart.SeriesAnimations)
self.chart.setTitle("Pie Chart Example")
self.chart.legend().setVisible(True)
self.chart.legend().setAlignment(Qt.AlignBottom)
self.chart.legend().markers(self.series)[0].setLabel("Python")
self.chart.legend().markers(self.series)[1].setLabel("C++")
self.chart.legend().markers(self.series)[2].setLabel("Java")
self.chart.legend().markers(self.series)[3].setLabel("C#")
self.chart.legend().markers(self.series)[4].setLabel("PHP")
self.num_data = 5 # +++
self.chartview = QChartView(self.chart)
self.chartview.setRenderHint(QPainter.Antialiasing)
self.setCentralWidget(self.chartview)
def add_table(self, value):
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
if value:
self.series.remove(self.series.slices()[0])
_slice = QPieSlice(f'New data {self.num_data}', random.randint(5, 30), self.series)
_slice.setBrush(QColor(*[random.randint(0, 255) for _ in range(3)]) )
_slice.setLabelVisible(True)
self.series.append(_slice)
for slice in self.series.slices():
slice.setLabel("{:.2f}%".format(100 * slice.percentage()))
self.series.setLabelsPosition(QPieSlice.LabelInsideNormal)
self.chart.legend().markers(self.series)[4].setLabel(f'New_data: {self.num_data}')
self.num_data += 1
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.resize(500, 500)
window.show()
sys.exit(app.exec_())
