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

QChart实时绘制正弦波滚动速度异常问题求助

问题分析与解决方案

核心问题根源

你的滚动速度忽快忽慢、数据最终移出屏幕的问题,完全来自这行滚动逻辑:

chart->scroll(chart->plotArea().width() / m_x, 0);

因为m_x持续递增,每次计算的滚动距离会越来越小——前期m_x值小,滚动幅度大;后期m_x值变大,滚动幅度趋近于0,最终完全跟不上数据新增的速度,导致数据跑出屏幕。

具体修正方案

方案1:直接控制X轴范围(推荐,最稳定)

放弃使用scroll()方法,改为固定X轴的显示区间,同时保留尾部留白。比如始终显示最近的50个数据点,加上10个单位的尾部留白:

void MyChartView::handleTimeout() {
    m_x += 1;
    m_y = (amplitude * sin(period * (m_x + horizontalShift)) + verticalShift);
    m_series->append(m_x, m_y);

    // 控制X轴范围,保持尾部留白
    const int displayCount = 50; // 显示最近50个点
    const int padding = 10;      // 尾部留白的X单位数
    if (m_x > displayCount) {
        m_axisX->setRange(m_x - displayCount, m_x + padding);
    } else {
        // 初始阶段还没填满显示区域时,设置初始范围
        m_axisX->setRange(0, displayCount + padding);
    }

    this->update();
}

这种方式完全避免滚动的累积误差,能精准保持数据在可视区域内,且滚动速度均匀。

方案2:修正滚动步长

如果坚持用scroll(),需要让每次滚动的距离匹配X轴上1个单位的像素宽度,保证滚动速度和数据新增速度一致:

void MyChartView::handleTimeout() {
    m_x += 1;
    m_y = (amplitude * sin(period * (m_x + horizontalShift)) + verticalShift);
    m_series->append(m_x, m_y);

    if (m_x > 10) {
        // 计算X轴每个单位对应的像素宽度
        qreal xTotalRange = m_axisX->max() - m_axisX->min();
        qreal pixelsPerXUnit = chart->plotArea().width() / xTotalRange;
        // 每次滚动1个X单位对应的像素距离
        chart->scroll(pixelsPerXUnit, 0);
    }

    this->update();
}

额外优化建议

  • 限制序列点数:如果持续添加数据,序列会越来越大,导致渲染卡顿。可以定期移除旧点:
    const int maxPointCount = 100;
    if (m_series->count() > maxPointCount) {
        m_series->remove(0); // 移除最早的点
    }
    
  • 提高定时器精度:如果定时器触发间隔不稳定,也会导致滚动速度波动,初始化定时器时设置高精度模式:
    QTimer *timer = new QTimer(this);
    timer->setTimerType(Qt::PreciseTimer);
    timer->start(100); // 根据你的需求调整间隔
    

内容的提问来源于stack exchange,提问作者Hakan Kaya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 12:36:18