Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 动态更新QLineSeries时出现问题_Python_Qthread_Pyside2_Qchart - Fatal编程技术网

Python 动态更新QLineSeries时出现问题

Python 动态更新QLineSeries时出现问题,python,qthread,pyside2,qchart,Python,Qthread,Pyside2,Qchart,当我试图通过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,

当我试图通过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按钮,它就会失控,并始终尝试与轴原点连接。
有人知道它为什么这样做吗?

在这种情况下,我看到以下错误:

  • 不必使用线程来执行重复任务,因为QTImer就足够了,例如,对于QThread,您不能也不应该像现在这样从辅助线程更新GUI,而QTImer允许这样做
  • 我不明白为什么要从randomValuesList中删除元素,因为在某一点上,该列表将为空,从而导致问题
随机导入
从PySide2导入QtCore、QtGui、QtWidgets
从PySide2.QtCharts导入QtCharts
baseValuesList=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
随机值列表=[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)
值=随机。选择(随机值列表)
baseValuesList.append(值)
类工作者(QtCore.QObject):
定义初始值(自身、函数、间隔):
超级(工作者,自我)。\uuuu初始化
self.\u function=函数
self.\u timer=QtCore.QTimer(self,interval=interval,timeout=self.execute)
@财产
def运行(自):
返回self.\u timer.isActive()
def启动(自):
self.\u timer.start()
def停止(自):
self.\u timer.stop()
def执行(自我):
self._function()
类监视器(qtwidts.QWidget):
定义初始化(自):
qtwidts.QWidget.\uuuuu init\uuuuuuu(self)
#创建QChart
layout=qtwidts.QVBoxLayout(self)
self.chart=QtCharts.QChart()
self.chart.setAnimationOptions(QtCharts.QChart.AllAnimations)
self.series=QtCharts.QLineSeries()
self.chart.addSeries(self.series)
self.chart\u view=QtCharts.QChartView(self.chart)
self.chart\u view.setRenderInt(QtGui.qPaint.Antialiasing)
layout.addWidget(self.chart\u视图)
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)
自转轴x设定范围(0,20)
自轴y设置范围(0,300)
self.series.attachAxis(self.axis_x)
self.series.attachAxis(self.axis_y)
self.worker=worker(self.update\u图表,1000)
self.autoUpdateStart=qtwidts.QPushButton(“启动自动更新”)
self.autoUpdateStart.setCheckable(False)
self.autoUpdateStart.toggle()
self.autoUpdateStart.clicked.connect(self.worker.start)
self.autoUpdateStop=QtWidgets.QPushButton(“停止自动更新”)
self.autoUpdateStop.setCheckable(False)
self.autoUpdateStop.toggle()
self.autoUpdateStop.clicked.connect(self.worker.stop)
layout.addWidget(self.autoUpdateStart)
layout.addWidget(self.autoUpdateStop)
self.manualUpdateButton=qtwidts.QPushButton(“手动更新”)
self.manualUpdateButton.setCheckable(错误)
self.manualUpdateButton.toggle()
self.manualUpdateButton.clicked.connect(self.update\u图表)
layout.addWidget(self.manualUpdateButton)
self.update_图表()
def更新图表(自我):
ListUpdateFunction()
self.series.clear()
对于i,枚举中的值(baseValuesList):
self.series.append(i,value)
self.chart\u view.update()
如果名称=“\uuuuu main\uuuuuuuu”:
导入系统
app=qtwidts.QApplication(sys.argv)
widget=minimamonitor()
widget.show()
sys.exit(app.exec_())

为什么需要使用线程?我认为没有任何耗时的任务值得线程化。请不要删除您的帖子并创建一个新帖子,而是编辑现有的帖子,因为如果您继续此行为,那么您将无法发布帖子。此面板将嵌入到使用PySide2的应用程序中。整个想法是运行循环,直到用户在后台停止。所以我试着做一根线。很抱歉删除了这篇文章,但由于前一篇文章已经被否决,这违反了StackOverflow的礼仪,我认为最好从头开始重新发布。1)我的意思是,只有线程才能生成每T秒运行一次的循环,如果是这样的话,那么最好使用QTimer,因为正如我在您的案例中看到的那样,线程会产生比解决方案更多的问题。2) 在SO中拒绝是例行公事,所以不要太重视它,我们拒绝不好的帖子(例如,我要求你提供MRE),这样OP(我的意思是你)就可以通过编辑而不是创建新帖子来改进你的帖子。感谢QTimer提示,我会看的。别担心,这种事不会再发生了。