在 PyQt6 中重播动画

发布于 2025-01-10 15:45:25 字数 7487 浏览 1 评论 0原文

我有一个 QWidget(具有 QWidget 基类继承的自定义类),里面有一个图表,在 display_widget 函数内附加了动画。

它工作正常,但动画只播放一次(我第一次导航到该小部件时)。

有什么方法可以按需重播动画(将其与事件或其他东西连接)?

class History(QWidget):
    def __init__(self, db_service):
        super().__init__()
        self.db_service = db_service
        self.display_widget()

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        painter.setPen(Qt.PenStyle.NoPen)
        self.draw_widget_bg(painter)
        painter.end()

    def draw_widget_bg(self, painter):
        brush = QBrush(QColor(11, 0, 24))
        painter.setBrush(brush)
        painter.drawRect(self.rect().adjusted(-1, -1, 1, 1))

    def display_widget(self):
        header_label = QLabel("<b>HISTORY</b>")

        # From Date combobox
        default_date = QDate.currentDate()
        date_combo = common.date_picker("On Date", default_date, change_handle=self.date_changed)

        # assign timestamp variable to current date in timestamp format
        timestamp = int(datetime.datetime.timestamp(datetime.datetime.strptime(str(default_date.toPyDate()), '%Y-%m-%d')))

        detections = self.db_service.get_detection_after_timestamp(timestamp)
        items = ['Select Job']
        for item in detections:
            items.append("Job #" + str(item.id))
        self.jobs_combo = common.combo_box("Select the Job", items, self.job_changed)


        obj_detected_label = QLabel("<b>TOTAL OBJECTS<br>DETECTED</b>")
        series = QPieSeries()
        series.setPieStartAngle(0)
        series.setPieEndAngle(360)
        series.setHoleSize(0.74)
        series.setPieSize(0.8)
        slice_item = QPieSlice("", 100)
        slice_item.setBorderWidth(0)
        slice_item.setPen(QPen(Qt.PenStyle.NoPen))
        slice_item.setColor(QColor(204, 0, 102))
        series.append(slice_item)

        chart = QChart()
        chart.setMinimumWidth(200)
        chart.setMaximumWidth(250)
        chart.setMargins(QMargins(5, 5, 5, 5))
        chart.layout().setContentsMargins(5, 5, 5, 5)
        chart.setBackgroundRoundness(10)
        chart.addSeries(series)
        chart.legend().setVisible(False)
        chart.setBackgroundBrush(Qt.GlobalColor.transparent)

        self.total_chart = add_chart_captions(chart, "", "1,250")
        totals_chart = QChartView()
        totals_chart.setRenderHint(QPainter.RenderHint.Antialiasing)
        totals_chart.setChart(chart)

        totals_chart.setViewportUpdateMode(QGraphicsView.ViewportUpdateMode.FullViewportUpdate)

        series = QStackedBarSeries()
        dummy_items = [7, 3, 10]
        for index, value in enumerate(dummy_items):
            barset = QBarSet("")
            values = [0] * len(dummy_items)
            values[index] = value
            barset.append(values)
            color = QColor(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
            color2 = QColor(255, 255, 255)
            gradient = QLinearGradient(0, 0, 0, 1)
            gradient.setCoordinateMode(QGradient.CoordinateMode.ObjectMode)
            gradient.setColorAt(0.2, color)
            gradient.setColorAt(0.7, color2)
            barset.setBrush(QBrush(gradient))
            barset.setBorderColor(Qt.GlobalColor.transparent)
            barset.setPen(QPen(Qt.PenStyle.NoPen))
            series.append(barset)

        value_axis = QValueAxis()
        value_axis.setTickCount(6)

        categories = ["item 1", "item 2", "item 3"]
        category_axis = QBarCategoryAxis()
        category_axis.append(categories)
        category_axis.setLabelsAngle(-45)
        category_axis.setLabelsVisible(True)

        sel_period_label = QLabel("<b>OBJECT DETECTED DURING THE SELECTED PERIOD</b>")
        self.chart = QChart()
        self.chart.addSeries(series)
        self.chart.legend().setVisible(False)
        self.chart.addAxis(category_axis, Qt.AlignmentFlag.AlignBottom)
        self.chart.addAxis(value_axis, Qt.AlignmentFlag.AlignLeft)
        series.attachAxis(value_axis)
        self.chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)
        # self.chart.setTheme(QChart.ChartTheme.ChartThemeDark)
        self.chart.setBackgroundRoundness(10)
        self.chart.setBackgroundBrush(Qt.GlobalColor.transparent)
        

        self.chart_view = QChartView()
        self.chart_view.setRenderHint(QPainter.RenderHint.Antialiasing)
        self.chart_view.setChart(self.chart)

        series = QHorizontalStackedBarSeries()
        barset = QBarSet("dummy label")
        dummy_items = []
        for i in range(1, 5):
            dummy_items.append(i)
        barset.append(dummy_items)
        series.append(barset)
        categories = ["label1", "label2", "label3", "label4"]
        value_axis = QValueAxis()
        value_axis.setTickCount(4)
        value_axis.setLabelsVisible(True)

        chart = QChart()
        chart.setTitle("<b>LIST OF ITEMS PER LOCATION</b>")
        chart.addSeries(series)
        chart.legend().setVisible(False)
        chart.addAxis(value_axis, Qt.AlignmentFlag.AlignLeft)
        series.attachAxis(value_axis)
        chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)
        chart.setTheme(QChart.ChartTheme.ChartThemeDark)
        chart.setBackgroundRoundness(10)
        chart.setBackgroundBrush(Qt.GlobalColor.transparent)
        gradient = QLinearGradient(0, 0, 1, 0)
        gradient.setCoordinateMode(QGradient.CoordinateMode.ObjectMode)
        gradient.setColorAt(0.0, QColor(242, 242, 13))
        gradient.setColorAt(0.5, QColor(0, 204, 102))
        gradient.setColorAt(0.8, QColor(0, 179, 134))
        barset.setBrush(QBrush(gradient))
        barset.setBorderColor(Qt.GlobalColor.transparent)
        barset.setPen(QPen(Qt.PenStyle.NoPen))

        per_loc_chart_view = QChartView()
        per_loc_chart_view.setRenderHint(QPainter.RenderHint.Antialiasing)
        per_loc_chart_view.setChart(chart)

        # Data table
        dummy_headers = ["dummy","dummy","dummy","dummy",]
        dummy_data = []
        # for i in range(20):
        #     dummy_data.append(["xyds"] * 11)

        self.data_table = common.table_widget(dummy_headers, dummy_data)

        charts_layout = QHBoxLayout()
        charts_layout.addWidget(totals_chart)
        charts_layout.addWidget(self.chart_view, 0, Qt.AlignmentFlag.AlignCenter)
        charts_layout.addWidget(per_loc_chart_view, 0, Qt.AlignmentFlag.AlignRight)

        subtab_layout = QGridLayout(self)
        subtab_layout.setContentsMargins(20, 10, 30, 10)
        subtab_layout.setVerticalSpacing(5)       
        subtab_layout.addWidget(header_label, 0, 0, 1, 1, Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignBottom)
        subtab_layout.addWidget(date_combo, 1, 0, 1, 1)
        subtab_layout.addWidget(self.jobs_combo, 1, 1, 1, 1)
        subtab_layout.addWidget(obj_detected_label, 2, 0, 1, 1)
        subtab_layout.addWidget(sel_period_label, 2, 1, 1, 2)
        subtab_layout.addLayout(charts_layout, 3, 0, 1, 3)
        subtab_layout.addWidget(self.data_table, 4, 0, 1, 3)
        subtab_layout.setRowStretch(0, 0)
        subtab_layout.setRowStretch(1, 0)
        subtab_layout.setRowStretch(2, 0)
        subtab_layout.setRowStretch(3, 3)
        subtab_layout.setRowStretch(4, 2)
        subtab_layout.setColumnStretch(0, 0)
        subtab_layout.setColumnStretch(1, 5)
        self.setLayout(subtab_layout)

I have a QWidget (custom class with QWidget base class inheritance) with a chart inside, Animation attached to it inside display_widget function.

it works fine but the animation only plays once ( the first time I navigate to that widget).

is there any way to replay the animation on demand (connecting it with an event or something else)?

class History(QWidget):
    def __init__(self, db_service):
        super().__init__()
        self.db_service = db_service
        self.display_widget()

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        painter.setPen(Qt.PenStyle.NoPen)
        self.draw_widget_bg(painter)
        painter.end()

    def draw_widget_bg(self, painter):
        brush = QBrush(QColor(11, 0, 24))
        painter.setBrush(brush)
        painter.drawRect(self.rect().adjusted(-1, -1, 1, 1))

    def display_widget(self):
        header_label = QLabel("<b>HISTORY</b>")

        # From Date combobox
        default_date = QDate.currentDate()
        date_combo = common.date_picker("On Date", default_date, change_handle=self.date_changed)

        # assign timestamp variable to current date in timestamp format
        timestamp = int(datetime.datetime.timestamp(datetime.datetime.strptime(str(default_date.toPyDate()), '%Y-%m-%d')))

        detections = self.db_service.get_detection_after_timestamp(timestamp)
        items = ['Select Job']
        for item in detections:
            items.append("Job #" + str(item.id))
        self.jobs_combo = common.combo_box("Select the Job", items, self.job_changed)


        obj_detected_label = QLabel("<b>TOTAL OBJECTS<br>DETECTED</b>")
        series = QPieSeries()
        series.setPieStartAngle(0)
        series.setPieEndAngle(360)
        series.setHoleSize(0.74)
        series.setPieSize(0.8)
        slice_item = QPieSlice("", 100)
        slice_item.setBorderWidth(0)
        slice_item.setPen(QPen(Qt.PenStyle.NoPen))
        slice_item.setColor(QColor(204, 0, 102))
        series.append(slice_item)

        chart = QChart()
        chart.setMinimumWidth(200)
        chart.setMaximumWidth(250)
        chart.setMargins(QMargins(5, 5, 5, 5))
        chart.layout().setContentsMargins(5, 5, 5, 5)
        chart.setBackgroundRoundness(10)
        chart.addSeries(series)
        chart.legend().setVisible(False)
        chart.setBackgroundBrush(Qt.GlobalColor.transparent)

        self.total_chart = add_chart_captions(chart, "", "1,250")
        totals_chart = QChartView()
        totals_chart.setRenderHint(QPainter.RenderHint.Antialiasing)
        totals_chart.setChart(chart)

        totals_chart.setViewportUpdateMode(QGraphicsView.ViewportUpdateMode.FullViewportUpdate)

        series = QStackedBarSeries()
        dummy_items = [7, 3, 10]
        for index, value in enumerate(dummy_items):
            barset = QBarSet("")
            values = [0] * len(dummy_items)
            values[index] = value
            barset.append(values)
            color = QColor(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
            color2 = QColor(255, 255, 255)
            gradient = QLinearGradient(0, 0, 0, 1)
            gradient.setCoordinateMode(QGradient.CoordinateMode.ObjectMode)
            gradient.setColorAt(0.2, color)
            gradient.setColorAt(0.7, color2)
            barset.setBrush(QBrush(gradient))
            barset.setBorderColor(Qt.GlobalColor.transparent)
            barset.setPen(QPen(Qt.PenStyle.NoPen))
            series.append(barset)

        value_axis = QValueAxis()
        value_axis.setTickCount(6)

        categories = ["item 1", "item 2", "item 3"]
        category_axis = QBarCategoryAxis()
        category_axis.append(categories)
        category_axis.setLabelsAngle(-45)
        category_axis.setLabelsVisible(True)

        sel_period_label = QLabel("<b>OBJECT DETECTED DURING THE SELECTED PERIOD</b>")
        self.chart = QChart()
        self.chart.addSeries(series)
        self.chart.legend().setVisible(False)
        self.chart.addAxis(category_axis, Qt.AlignmentFlag.AlignBottom)
        self.chart.addAxis(value_axis, Qt.AlignmentFlag.AlignLeft)
        series.attachAxis(value_axis)
        self.chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)
        # self.chart.setTheme(QChart.ChartTheme.ChartThemeDark)
        self.chart.setBackgroundRoundness(10)
        self.chart.setBackgroundBrush(Qt.GlobalColor.transparent)
        

        self.chart_view = QChartView()
        self.chart_view.setRenderHint(QPainter.RenderHint.Antialiasing)
        self.chart_view.setChart(self.chart)

        series = QHorizontalStackedBarSeries()
        barset = QBarSet("dummy label")
        dummy_items = []
        for i in range(1, 5):
            dummy_items.append(i)
        barset.append(dummy_items)
        series.append(barset)
        categories = ["label1", "label2", "label3", "label4"]
        value_axis = QValueAxis()
        value_axis.setTickCount(4)
        value_axis.setLabelsVisible(True)

        chart = QChart()
        chart.setTitle("<b>LIST OF ITEMS PER LOCATION</b>")
        chart.addSeries(series)
        chart.legend().setVisible(False)
        chart.addAxis(value_axis, Qt.AlignmentFlag.AlignLeft)
        series.attachAxis(value_axis)
        chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)
        chart.setTheme(QChart.ChartTheme.ChartThemeDark)
        chart.setBackgroundRoundness(10)
        chart.setBackgroundBrush(Qt.GlobalColor.transparent)
        gradient = QLinearGradient(0, 0, 1, 0)
        gradient.setCoordinateMode(QGradient.CoordinateMode.ObjectMode)
        gradient.setColorAt(0.0, QColor(242, 242, 13))
        gradient.setColorAt(0.5, QColor(0, 204, 102))
        gradient.setColorAt(0.8, QColor(0, 179, 134))
        barset.setBrush(QBrush(gradient))
        barset.setBorderColor(Qt.GlobalColor.transparent)
        barset.setPen(QPen(Qt.PenStyle.NoPen))

        per_loc_chart_view = QChartView()
        per_loc_chart_view.setRenderHint(QPainter.RenderHint.Antialiasing)
        per_loc_chart_view.setChart(chart)

        # Data table
        dummy_headers = ["dummy","dummy","dummy","dummy",]
        dummy_data = []
        # for i in range(20):
        #     dummy_data.append(["xyds"] * 11)

        self.data_table = common.table_widget(dummy_headers, dummy_data)

        charts_layout = QHBoxLayout()
        charts_layout.addWidget(totals_chart)
        charts_layout.addWidget(self.chart_view, 0, Qt.AlignmentFlag.AlignCenter)
        charts_layout.addWidget(per_loc_chart_view, 0, Qt.AlignmentFlag.AlignRight)

        subtab_layout = QGridLayout(self)
        subtab_layout.setContentsMargins(20, 10, 30, 10)
        subtab_layout.setVerticalSpacing(5)       
        subtab_layout.addWidget(header_label, 0, 0, 1, 1, Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignBottom)
        subtab_layout.addWidget(date_combo, 1, 0, 1, 1)
        subtab_layout.addWidget(self.jobs_combo, 1, 1, 1, 1)
        subtab_layout.addWidget(obj_detected_label, 2, 0, 1, 1)
        subtab_layout.addWidget(sel_period_label, 2, 1, 1, 2)
        subtab_layout.addLayout(charts_layout, 3, 0, 1, 3)
        subtab_layout.addWidget(self.data_table, 4, 0, 1, 3)
        subtab_layout.setRowStretch(0, 0)
        subtab_layout.setRowStretch(1, 0)
        subtab_layout.setRowStretch(2, 0)
        subtab_layout.setRowStretch(3, 3)
        subtab_layout.setRowStretch(4, 2)
        subtab_layout.setColumnStretch(0, 0)
        subtab_layout.setColumnStretch(1, 5)
        self.setLayout(subtab_layout)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文