Reputation: 11
I encounter a problem when I try to make a self updating QLineSeries through the help of QThread.
from PySide2.QtCore import *
from PySide2 import *
from PySide2.QtWidgets import *
from PySide2.QtCharts import *
from PySide2.QtGui import *
import time
baseValuesList = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
randomValuesList = [256, 14, 89, 100, 150, 500, 50, 34, 67, 90, 102, 12, 19, 89, 34, 145, 71, 4, 89, 47]
rangeList = list(range(len(baseValuesList)))
def listUpdatingFunction():
baseValuesList.pop(0)
baseValuesList.append(randomValuesList[0])
randomValuesList.pop(0)
class Worker(QObject):
def __init__(self, function, interval):
super(Worker, self).__init__()
self._step = 0
self._isRunning = True
self.function = function
self.interval = interval
def task(self):
if not self._isRunning:
self._isRunning = True
self._step = 0
while self._isRunning == True:
self.function()
time.sleep(self.interval)
def stop(self):
self._isRunning = False
class minimalMonitor(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
# Creating QChart
self.layout = QVBoxLayout()
self.setLayout(self.layout)
self.chart = QtCharts.QChart()
self.chart.setAnimationOptions(QtCharts.QChart.AllAnimations)
self.series = QtCharts.QLineSeries()
for i in rangeList:
self.series.append(i,baseValuesList[i])
self.chart.addSeries(self.series)
self.chart_view = QtCharts.QChartView(self.chart)
self.chart_view.setRenderHint(QPainter.Antialiasing)
self.layout.addWidget(self.chart_view)
self.axis_x = QtCharts.QValueAxis()
self.chart.addAxis(self.axis_x, Qt.AlignBottom)
self.axis_y = QtCharts.QValueAxis()
self.chart.addAxis(self.axis_y, Qt.AlignLeft)
self.axis_x.setRange(0, 20)
self.axis_y.setRange(0, 300)
self.series.attachAxis(self.axis_x)
self.series.attachAxis(self.axis_y)
self.thread = QThread()
self.thread.start()
self.worker = Worker(self.update, 1)
self.worker.moveToThread(self.thread)
self.autoUpdateStart = QPushButton("Start Auto-Update")
self.autoUpdateStart.setCheckable(False)
self.autoUpdateStart.toggle()
self.autoUpdateStart.clicked.connect(self.worker.task)
self.autoUpdateStop = QPushButton("Stop Auto-Update")
self.autoUpdateStop.setCheckable(False)
self.autoUpdateStop.toggle()
self.autoUpdateStop.clicked.connect(lambda: self.worker.stop())
self.layout.addWidget(self.autoUpdateStart)
self.layout.addWidget(self.autoUpdateStop)
self.manualUpdateButton = QPushButton("Manual Update")
self.manualUpdateButton.setCheckable(False)
self.manualUpdateButton.toggle()
self.manualUpdateButton.clicked.connect(self.update)
self.layout.addWidget(self.manualUpdateButton)
def update(self):
listUpdatingFunction()
self.series.clear()
for i in rangeList:
self.series.append(i,baseValuesList[i])
self.chart_view.update()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
widget = minimalMonitor()
widget.show()
sys.exit(app.exec_())
In a nutshell, if I call directly the update function or press manual update, the QLineSeries will correctly append, but as soon as I use the QThread or Auto Update button it goes haywire and will always try to join with the Axis Origin. Does any one have an idea why it is doing this?
Upvotes: 0
Views: 900
Reputation: 244003
In this case I see the following errors:
import random
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCharts import QtCharts
baseValuesList = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
randomValuesList = [256, 14, 89, 100, 150, 500, 50, 34, 67, 90, 102, 12, 19, 89, 34, 145, 71, 4, 89, 47]
def listUpdatingFunction():
baseValuesList.pop(0)
value = random.choice(randomValuesList)
baseValuesList.append(value)
class Worker(QtCore.QObject):
def __init__(self, function, interval):
super(Worker, self).__init__()
self._funcion = function
self._timer = QtCore.QTimer(self, interval=interval, timeout=self.execute)
@property
def running(self):
return self._timer.isActive()
def start(self):
self._timer.start()
def stop(self):
self._timer.stop()
def execute(self):
self._funcion()
class minimalMonitor(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
# Creating QChart
layout = QtWidgets.QVBoxLayout(self)
self.chart = QtCharts.QChart()
self.chart.setAnimationOptions(QtCharts.QChart.AllAnimations)
self.series = QtCharts.QLineSeries()
self.chart.addSeries(self.series)
self.chart_view = QtCharts.QChartView(self.chart)
self.chart_view.setRenderHint(QtGui.QPainter.Antialiasing)
layout.addWidget(self.chart_view)
self.axis_x = QtCharts.QValueAxis()
self.chart.addAxis(self.axis_x, QtCore.Qt.AlignBottom)
self.axis_y = QtCharts.QValueAxis()
self.chart.addAxis(self.axis_y, QtCore.Qt.AlignLeft)
self.axis_x.setRange(0, 20)
self.axis_y.setRange(0, 300)
self.series.attachAxis(self.axis_x)
self.series.attachAxis(self.axis_y)
self.worker = Worker(self.update_chart, 1000)
self.autoUpdateStart = QtWidgets.QPushButton("Start Auto-Update")
self.autoUpdateStart.setCheckable(False)
self.autoUpdateStart.toggle()
self.autoUpdateStart.clicked.connect(self.worker.start)
self.autoUpdateStop = QtWidgets.QPushButton("Stop Auto-Update")
self.autoUpdateStop.setCheckable(False)
self.autoUpdateStop.toggle()
self.autoUpdateStop.clicked.connect(self.worker.stop)
layout.addWidget(self.autoUpdateStart)
layout.addWidget(self.autoUpdateStop)
self.manualUpdateButton = QtWidgets.QPushButton("Manual Update")
self.manualUpdateButton.setCheckable(False)
self.manualUpdateButton.toggle()
self.manualUpdateButton.clicked.connect(self.update_chart)
layout.addWidget(self.manualUpdateButton)
self.update_chart()
def update_chart(self):
listUpdatingFunction()
self.series.clear()
for i, value in enumerate(baseValuesList):
self.series.append(i, value)
self.chart_view.update()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
widget = minimalMonitor()
widget.show()
sys.exit(app.exec_())
Upvotes: 1