如何刷新PyQt5 QtChart中的数据?

how to refresh data in PyQt5 QtChart?

我试图在更改包含年份的组合框时使 QtChart 可更新。出于这个问题的目的,我制作了一个包含随机数据的列表和我的项目的简短版本。 这是我的 chart_ui.py 来自 QtDesigner

 from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.year_ccb = QtWidgets.QComboBox(self.centralwidget)
        self.year_ccb.setGeometry(QtCore.QRect(10, 10, 111, 22))
        self.year_ccb.setObjectName("year_ccb")
        self.chart_fm = QtWidgets.QFrame(self.centralwidget)
        self.chart_fm.setGeometry(QtCore.QRect(20, 60, 741, 391))
        self.chart_fm.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.chart_fm.setFrameShadow(QtWidgets.QFrame.Raised)
        self.chart_fm.setObjectName("chart_fm")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))

这是我的 main.py 文件和示例代码:

import datetime
import sys

from PyQt5.QtChart import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt, QRect, QPropertyAnimation, QParallelAnimationGroup, QDate
from chart_ui import Ui_MainWindow


class LoginWindow(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        global widgets
        widgets = self.ui
        self.chart_one_create()
        ####################################################
        years = ('2019', '2020', '2021')
        widgets.year_ccb.addItems(years)
        widgets.year_ccb.currentIndexChanged.connect(self.chart_one_create)
        ####################################################
        self.show()

    def chart_one_create(self):
        self.series = QBarSeries()
        self.set_tkf = QBarSet("TAEKWON-DO")
        self.set_fenc = QBarSet("ΞΙΦΑΣΚΙΑ")
        self.set_oplo = QBarSet("ΟΠΛΟΜΑΧΙΑ")
        self.set_spends = QBarSet("ΕΞΟΔΑ")

        if widgets.year_ccb.currentText() == '2019':
            list_of_data = [["1", "2", "3", "4", "5"], [(45, 637, 12, 43), (12, 154, 132, 454),
                                                        (435, 117, 212, 453), (45, 657, 112, 455),
                                                        (451, 667, 12, 475)]]  # manual add data
        elif widgets.year_ccb.currentText() == '2020':
            list_of_data = [["5", "6", "7", "8", "9"], [(425, 67, 172, 43), (192, 584, 132, 454),
                                                        (435, 167, 212, 453), (45, 657, 12, 455),
                                                        (453, 667, 162, 475)]]  # manual add data
        else:
            list_of_data = [["10", "11", "12", "13", "14"], [(45, 67, 12, 43), (127, 54, 132, 454),
                                                             (435, 187, 212, 453), (45, 657, 152, 455),
                                                             (45, 667, 122, 475)]]  # manual add data
        for i in range(len(list_of_data[0])):  # για καθε μηνα που εχει στην πρωτη εσωτερικη λιστα
            if list_of_data[1][i][0] is None:
                tkd = 0
            else:
                tkd = list_of_data[1][i][0]
            self.set_tkf.append(tkd)
            if list_of_data[1][i][1] is None:
                fenc = 0
            else:
                fenc = list_of_data[1][i][1]
            self.set_fenc.append(fenc)
            if list_of_data[1][i][2] is None:
                oplo = 0
            else:
                oplo = list_of_data[1][i][2]
            self.set_oplo.append(oplo)
            if list_of_data[1][i][3] is None:
                spen = 0
            else:
                spen = list_of_data[1][i][3]
            self.set_spends.append(spen)

        self.series.append(self.set_tkf)
        self.series.append(self.set_fenc)
        self.series.append(self.set_oplo)
        self.series.append(self.set_spends)

        ##############################################################
        self.chart = QChart()
        self.chart.addSeries(self.series)
        self.chart.setTitle("Monthly Stats per Year")
        self.chart.setAnimationOptions(QChart.AllAnimations)
        self.chart.setTheme(QChart.ChartThemeBrownSand)
        self.chart.setBackgroundBrush(QBrush(QColor("transparent")))
        self.chart.legend().setVisible(True)
        self.chart.legend().setAlignment(Qt.AlignBottom)
        ##############################################################
        self.axisX = QBarCategoryAxis()
        self.axisY = QValueAxis()
        self.axisY.setRange(0, 3000)
        ##############################################################
        self.categories_months=list_of_data[0]
        self.axisX.append(self.categories_months)
        self.chart.addAxis(self.axisX, Qt.AlignBottom)
        self.chart.addAxis(self.axisY, Qt.AlignLeft)

        self.series.attachAxis(self.axisX)
        self.series.attachAxis(self.axisY)
        ##############################################################
        self.chartview = QChartView(self.chart)
        vbox = QGridLayout(widgets.chart_fm)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.addWidget(self.chartview)
        self.update_chart_one()

    def update_chart_one(self):
        pass


# Create the application object
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = LoginWindow()
    sys.exit(app.exec_())

所以请帮助我理解我必须在 def update_chart_one(self) 中写的内容:当我从组合框更改年份时让我的图表刷新它的数据。 可能是这样的:

def update_chart_one(self):
    self.series.clear()
    self.categories_months.clear()

然后以某种方式刷新图表中的数据。

图表:Y 轴显示金额,X 轴显示月份(数据中的第一个列表 list_of_data[0])

您必须通过删除以前的数据来重新使用该系列:

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QBrush, QColor
from PyQt5.QtWidgets import QApplication, QGridLayout, QMainWindow
from PyQt5.QtChart import (
    QBarCategoryAxis,
    QBarSeries,
    QBarSet,
    QChart,
    QChartView,
    QValueAxis,
)

from chart_ui import Ui_MainWindow


class LoginWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.build_chart()

        years = ("2019", "2020", "2021")
        self.ui.year_ccb.currentIndexChanged.connect(self.handle_index_changed)
        self.ui.year_ccb.addItems(years)

    def build_chart(self):
        self.series = QBarSeries()
        self.set_tkf = QBarSet("TAEKWON-DO")
        self.set_fenc = QBarSet("ΞΙΦΑΣΚΙΑ")
        self.set_oplo = QBarSet("ΟΠΛΟΜΑΧΙΑ")
        self.set_spends = QBarSet("ΕΞΟΔΑ")
        self.series.append(self.set_tkf)
        self.series.append(self.set_fenc)
        self.series.append(self.set_oplo)
        self.series.append(self.set_spends)

        self.chart = QChart()
        self.chart.addSeries(self.series)
        self.chart.setTitle("Monthly Stats per Year")
        self.chart.setAnimationOptions(QChart.AllAnimations)
        self.chart.setTheme(QChart.ChartThemeBrownSand)
        self.chart.setBackgroundBrush(QBrush(QColor("transparent")))
        self.chart.legend().setVisible(True)
        self.chart.legend().setAlignment(Qt.AlignBottom)

        self.axisX = QBarCategoryAxis()
        self.axisY = QValueAxis()
        self.axisY.setRange(0, 3000)

        self.chart.addAxis(self.axisX, Qt.AlignBottom)
        self.chart.addAxis(self.axisY, Qt.AlignLeft)

        self.series.attachAxis(self.axisX)
        self.series.attachAxis(self.axisY)

        self.chartview = QChartView(self.chart)
        vbox = QGridLayout(self.ui.chart_fm)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.addWidget(self.chartview)

    def handle_index_changed(self):
        default = [
            ["10", "11", "12", "13", "14"],
            [
                (45, 67, 12, 43),
                (127, 54, 132, 454),
                (435, 187, 212, 453),
                (45, 657, 152, 455),
                (45, 667, 122, 475),
            ],
        ]
        data = {
            "2019": [
                ["1", "2", "3", "4", "5"],
                [
                    (45, 637, 12, 43),
                    (12, 154, 132, 454),
                    (435, 117, 212, 453),
                    (45, 657, 112, 455),
                    (451, 667, 12, 475),
                ],
            ],
            "2020": [
                ["5", "6", "7", "8", "9"],
                [
                    (425, 67, 172, 43),
                    (192, 584, 132, 454),
                    (435, 167, 212, 453),
                    (45, 657, 12, 455),
                    (453, 667, 162, 475),
                ],
            ],
        }
        values = data.get(self.ui.year_ccb.currentText(), default)
        self.update_chart_one(values)

    def update_chart_one(self, datas):
        self.axisX.clear()
        self.set_tkf.remove(0, self.set_tkf.count())
        self.set_fenc.remove(0, self.set_fenc.count())
        self.set_oplo.remove(0, self.set_oplo.count())
        self.set_spends.remove(0, self.set_spends.count())
        categories, data = datas
        self.axisX.append(categories)
        for tkf, fenc, oplo, spends in data:
            self.set_tkf.append(tkf)
            self.set_fenc.append(fenc)
            self.set_oplo.append(oplo)
            self.set_spends.append(spends)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = LoginWindow()
    window.show()
    sys.exit(app.exec_())