You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QChart时序图开发仅PySide6报OverflowError的问题问询

QChartView时间序列在PySide6下触发整型溢出报错问题

问题复现

在QChartView中创建时间序列图表时,报错发生在设置X轴(axis_x)的流程中,复现代码如下:

#!/usr/bin/env python3

import sys
import collections

# PySide6
from PySide6.QtGui import QPainter
from PySide6.QtWidgets import QWidget, QApplication, QMainWindow
from PySide6.QtCore import QPointF, QDateTime, QPoint
from PySide6.QtCharts import (QChartView, QLineSeries, QValueAxis,
                              QChart, QDateTimeAxis)

# PyQt5
# from PyQt5.QtGui import QPainter
# from PyQt5.QtWidgets import QWidget, QApplication, QMainWindow
# from PyQt5.QtCore import QPointF, QDateTime, QPoint
# from PyQt5.QtChart import QChartView, QLineSeries, QValueAxis, QChart, QDateTimeAxis


class VisibilityView(QChartView):

    def __init__(self, parent: QWidget, maxlen: int):
        super().__init__(parent)
        self.setMinimumSize(200, 200)
        self.setMaximumSize(600, 400)

        self.maxlen = maxlen

        self.setRenderHint(QPainter.Antialiasing)
        self.setMouseTracking(True)

        chart = QChart()
        chart.legend().setVisible(False)

        self.setChart(chart)
        self.chart().setTheme(QChart.ChartThemeDark)
        self.series = QLineSeries(name='Prevailing Visibility')
        chart.addSeries(self.series)

        axis_x = QDateTimeAxis()
        axis_x.setFormat('yy/MM/dd hh:mm')
        axis_x.setTitleText('Time')

        epoch = [1655168220000, 1655168230000, 1655168881000, 1655169840000,
                 1655169900000, 1655169960000, 1655170020000, 1655170080000,
                 1655170140000, 1655170200000, 1655170260000, 1655170320000,
                 1655170380000, 1655170500000, 1655170560000]
        vis_list = [20.0, 17.0, 20.0, 20.0,
                    19.0, 20.0, 15.0, 20.0,
                    20.0, 20.0, 20.0, 20.0,
                    17.0, 20.0, 20.0]

        data = []

        for i in range(len(epoch)):
            data.append((epoch[i], vis_list[i]))
        self.data = collections.deque(data, maxlen=1440)

        left = QDateTime.fromMSecsSinceEpoch(self.data[0][0])
        right = QDateTime.fromMSecsSinceEpoch(self.data[-1][0])
        axis_x.setRange(left, right)
        chart.setAxisX(axis_x, self.series)

        axis_y = QValueAxis()
        axis_y.setRange(0, 20)
        axis_y.setLabelFormat('%d km')
        axis_y.setTitleText('Distance (km)')
        chart.setAxisY(axis_y, self.series)

        data_point = [QPointF(t, v) for t, v in self.data]
        self.series.append(data_point)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = QMainWindow()
    graph = VisibilityView(window, 1440)
    window.setCentralWidget(graph)
    window.resize(graph.maximumSize())
    window.show()
    sys.exit(app.exec())

运行时抛出如下报错:

...
  File "D:\Workspace\convert_pyside\src\visibility_view.py", line 94, in __init__
    data_point = [QPointF(t, v) for t, v in self.data]
  File "D:\Workspace\convert_pyside\src\visibility_view.py", line 94, in <listcomp>
    data_point = [QPointF(t, v) for t, v in self.data]
OverflowError: Python int too large to convert to C long

完全相同的代码切换到PyQt5环境运行时不会触发该报错,两个运行环境的sys.maxsize取值均为9223372036854775807,完全一致。

原因说明

PySide和PyQt确实存在Qt绑定层面的内部实现差异:

  • PyQt5的类型转换逻辑更宽松,构造QPointF传入整型参数时,会直接将数值隐式转换为C++层的qreal(双精度浮点型),不会做32位长整型的长度校验,因此不会触发溢出。
  • PySide6的类型绑定校验更严格,在Windows平台下,构造QPointF传入整型参数时,会先尝试将Python整型转换为C long类型(Windows平台C long为32位,最大值仅2147483647),示例中使用的毫秒级时间戳数值量级为10^12,远大于32位long的上限,因此触发溢出报错。sys.maxsize反映的是平台指针宽度,和C long的长度在Windows 64位平台下并不一致,因此两个环境取值相同也会出现表现差异。

解决方法

最简便的修复方式是构造QPointF时,主动将毫秒时间戳转换为浮点型,绕过PySide6的整型转C long的校验逻辑,毫秒级时间戳在双精度浮点的精确整数表示范围内,不会出现精度丢失问题。
将原报错行修改为:

data_point = [QPointF(float(t), v) for t, v in self.data]

修改后代码在PySide6环境下可正常运行,时间轴显示、曲线绘制效果与PyQt5环境完全一致。


内容的提问来源于stack exchange,提问作者Oh Jongjin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 11:36:22