首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态更新QChart

动态更新QChart
EN

Stack Overflow用户
提问于 2020-07-08 17:01:41
回答 1查看 2K关注 0票数 4

我有一个为给定数据绘制烛台的类。一旦收到新的数据,我正在尝试动态地更新这个情节。数据以不规则的间隔接收。

我可以使用什么机制来让类知道是时候更新这个情节,并在用新接收的数据点更新这个图时采取行动?

类函数append_data_and_plot()附加数据,但情节从未更新。有人能好心地解释一下这个问题是什么吗?

代码语言:javascript
复制
import sys
from PyQt5.QtChart import QCandlestickSeries, QChart, QChartView, QCandlestickSet
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import Qt, QPointF
from PyQt5 import QtChart as qc
import time

class myCandlestick():
    def __init__(self, data):
        self.data = data
        self.app = QApplication(sys.argv)

        self.series = QCandlestickSeries()
        self.series.setDecreasingColor(Qt.red)
        self.series.setIncreasingColor(Qt.green)

        self.ma5 = qc.QLineSeries() 
        self.tm = []

        for num, o, h, l, c, m in self.data:
            self.series.append(QCandlestickSet(o, h, l, c))
            self.ma5.append(QPointF(num, m))
            self.tm.append(str(num))

        self.chart = QChart()

        self.chart.addSeries(self.series)  # candle
        self.chart.addSeries(self.ma5)  # ma5 line

        self.chart.createDefaultAxes()
        self.chart.legend().hide()

        self.chart.axisX(self.series).setCategories(self.tm)
        self.chart.axisX(self.ma5).setVisible(False)

        self.chartview = QChartView(self.chart)
        self.ui = QMainWindow()
        self.ui.setGeometry(50, 50, 500, 300)
        self.ui.setCentralWidget(self.chartview)
        self.ui.show()
        sys.exit(self.app.exec_())

    def append_data_and_plot(self, d):
        '''Append and update the plot'''
        num, o, h, l, c, m = d
        self.series.append(QCandlestickSet(o, h, l, c))
        self.ui.show()
        #sys.exit(self.app.exec_())


data = ((1, 7380, 7520, 7380, 7510, 7324),
        (2, 7520, 7580, 7410, 7440, 7372),
        (3, 7440, 7650, 7310, 7520, 7434),
        (4, 7450, 7640, 7450, 7550, 7480),
        (5, 7510, 7590, 7460, 7490, 7502),
        (6, 7500, 7590, 7480, 7560, 7512),
        (7, 7560, 7830, 7540, 7800, 7584))

m = myCandlestick(data)

# Data is received at irregular intervals
time.sleep(1)
m.append_data_and_plot((8, 7560, 7830, 7540, 7800, 7584))

# Data is received at irregular intervals
time.sleep(0.1)
m.append_data_and_plot((9, 7450, 7640, 7450, 7550, 7480))

# Data is received at irregular intervals
time.sleep(2.5)
m.append_data_and_plot((10, 7380, 7520, 7380, 7510, 7324))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-08 18:43:37

Qt使用一个事件循环来处理gui的事件和任务,即代码"app.exec_ ()“,因此该行之后的所有代码都不会被执行,如果添加了它,sys.exit ()将使应用程序在Qt事件循环结束时终止。

解决方案是使用事件循环更新gui,例如使用QTimer:

代码语言:javascript
复制
import sys
from PyQt5.QtChart import QCandlestickSeries, QChart, QChartView, QCandlestickSet
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import Qt, QPointF, QObject, pyqtSignal, QTimer
from PyQt5 import QtChart as qc

import random


class MainWindow(QMainWindow):
    def __init__(self, data, parent=None):
        super().__init__(parent)
        self.data = data

        self.series = QCandlestickSeries()
        self.series.setDecreasingColor(Qt.red)
        self.series.setIncreasingColor(Qt.green)

        self.ma5 = qc.QLineSeries()
        self.tm = []

        self.chart = QChart()

        self.chart.addSeries(self.series)  # candle
        self.chart.addSeries(self.ma5)  # ma5 line

        self.chart.createDefaultAxes()
        self.chart.legend().hide()

        self.chart.axisX(self.series).setCategories(self.tm)
        self.chart.axisX(self.ma5).setVisible(False)

        self.chartview = QChartView(self.chart)
        self.setGeometry(50, 50, 500, 300)
        self.setCentralWidget(self.chartview)

    def append_data_and_plot(self, d):
        """Append and update the plot"""
        num, o, h, l, c, m = d

        ax1 = self.chart.axisX(self.ma5)
        ay1 = self.chart.axisY(self.ma5)

        xmin = xmax = num
        ymin = ymax = m

        step = 10
        offset = 100

        for p in self.ma5.pointsVector()[-step:]:
            xmin = min(p.x(), xmin)
            xmax = max(p.x(), xmax)

            ymin = min(p.y(), ymin) - offset
            ymax = max(p.y(), ymax) + offset

        xmin = max(0, xmax - step)

        ax1.setMin(xmin)
        ax1.setMax(xmax)
        ay1.setMin(ymin)
        ay1.setMax(ymax)

        self.ma5.append(QPointF(num, m))
        self.tm.append(str(num))

        self.series.append(QCandlestickSet(o, h, l, c))
        ax2 = self.chart.axisX(self.series)
        ax2.setCategories(self.tm)
        ax2.setMin(str(xmin))
        ax2.setMax(str(xmax))

        ay2 = self.chart.axisY(self.series)
        ay2.setMin(ymin)
        ay2.setMax(ymax)


def create_data():


    i = 1
    while True:
        i += 1
        yield (
            i,
            random.randint(7000, 8000),
            random.randint(7000, 8000),
            random.randint(7000, 8000),
            random.randint(7000, 8000),
            random.randint(7000, 8000),
        )


class Producer(QObject):
    dataChanged = pyqtSignal(list)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.iter = create_data()
        QTimer.singleShot(random.randint(0, 1500), self.send_data)

    def send_data(self):
        d = list(next(self.iter))
        self.dataChanged.emit(d)
        QTimer.singleShot(random.randint(0, 1500), self.send_data)


def main():
    app = QApplication(sys.argv)

    data = ((1, 7380, 7520, 7380, 7510, 7324),)
    w = MainWindow(data)
    w.show()

    p = Producer()
    p.dataChanged.connect(w.append_data_and_plot)

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62799886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档