动态更新QLineSeries时出现问题

2024-06-24 13:02:38 发布

您现在位置:Python中文网/ 问答频道 /正文

当我试图通过QThread帮助制作一个自我更新的QLineSeries时,遇到了一个问题

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_())

简而言之,如果我直接调用update函数或按manual update,QLineSeries将正确追加,但只要我使用QThread或Auto update按钮,它就会失控,并始终尝试与轴原点连接。 有人知道它为什么这样做吗


Tags: fromimportselfdefchartupdateserieslayout
1条回答
网友
1楼 · 发布于 2024-06-24 13:02:38

在本例中,我看到以下错误:

  • 不必使用线程来执行重复任务,因为QTImer就足够了,例如,对于QThread,您不能也不应该像现在这样从辅助线程更新GUI,而QTImer允许这样做
  • 我不明白为什么要从randomValuesList中删除元素,因为在某一点上,该列表将为空,从而导致问题
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_())

相关问题 更多 >