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

QT调用QChart::createDefaultAxes()后仅显示单值X/Y坐标轴问题

问题原因

  1. 核心错误:同一个QLineSeries实例被反复调用addSeries添加到图表。你当前逻辑是每次追加数据时都执行qChart.addSeries(),同一个序列会被QChart反复移除、重新添加,导致内部状态异常,createDefaultAxes生成坐标轴时无法正确读取序列的全量数据,最终出现仅显示单值、坐标轴适配错误的问题。
  2. createDefaultAxes仅会在调用时刻基于当前图表内的序列计算坐标轴范围,后续修改序列数据时不会自动同步缩放。

解决方法

1. 调整序列添加逻辑,仅初始化时一次性添加所有序列

修改create_new_series方法,初始化完所有序列后直接全部添加到图表,所有序列添加完成后统一调用一次createDefaultAxes:

void Easy_chart::create_new_series(){
    qChart.removeAllSeries();
    pwm_serie.clear();
    ao_serie.clear();
    ai_serie.clear();
    dai_serie.clear();
    encoder_serie.clear();
    input_capture_serie.clear();

    for(int i = 0; i < PWM_SERIES_LENGTH; i++){
        pwm_serie.append(new QLineSeries());
        qChart.addSeries(pwm_serie.last());
    }
    for(int i = 0; i < AO_SERIES_LENGTH; i++){
        ao_serie.append(new QLineSeries());
        qChart.addSeries(ao_serie.last());
    }
    for(int i = 0; i < AI_SERIES_LENGTH; i++){
        ai_serie.append(new QLineSeries());
        qChart.addSeries(ai_serie.last());
    }
    for(int i = 0; i < DAI_SERIES_LENGTH; i++){
        dai_serie.append(new QLineSeries());
        qChart.addSeries(dai_serie.last());
    }
    for(int i = 0; i < ENCODER_SERIES_LENGTH; i++){
        encoder_serie.append(new QLineSeries());
        qChart.addSeries(encoder_serie.last());
    }
    for(int i = 0; i < INPUT_CAPTURE_SERIES_LENGTH; i++){
        input_capture_serie.append(new QLineSeries());
        qChart.addSeries(input_capture_serie.last());
    }

    // 所有序列添加完成后统一生成默认坐标轴
    qChart.createDefaultAxes();
}

2. 删除数据更新时的addSeries调用

后续更新序列数据时,直接调用append_to_series修改序列内容即可,不需要重复添加到图表:

// 原代码 qChart.addSeries(append_to_series("PWM", pwm_serie.at(index), index, value));
// 改为:
append_to_series("PWM", pwm_serie.at(index), index, value);

3. 新增坐标轴范围刷新逻辑(按需使用)

如果需要每次更新数据后坐标轴自动适配数据范围,可新增刷新方法,每次更新完所有数据后调用即可:

#include <limits>

void Easy_chart::refresh_axis_range(){
    float min_y = std::numeric_limits<float>::max();
    float max_y = std::numeric_limits<float>::min();

    // 遍历所有有数据的序列计算Y轴最值
    auto calc_series_range = [&](QList<QLineSeries*>& series_list){
        for(auto serie : series_list){
            if(serie->count() == 0) continue;
            for(int i=0; i<serie->count(); i++){
                min_y = qMin(min_y, serie->at(i).y());
                max_y = qMax(max_y, serie->at(i).y());
            }
        }
    };

    calc_series_range(pwm_serie);
    calc_series_range(ao_serie);
    calc_series_range(ai_serie);
    calc_series_range(dai_serie);
    calc_series_range(encoder_serie);
    calc_series_range(input_capture_serie);

    // X轴固定显示show_samples个点的范围,Y轴留边距
    qChart.axisX()->setRange(0, show_samples - 1);
    qChart.axisY()->setRange(min_y - 1, max_y + 1);
}

4. 优化滚动更新逻辑(可选)

原滚动更新逻辑遍历所有点执行replace性能较低,可改用移除首点+追加新点的方式实现,性能更高:

QLineSeries* Easy_chart::append_to_series(const QString& label, QLineSeries* serie, int index, float value){
    serie->setName(label + QString::number(index) + "(" + QString::number(value) + ")");
    int count = serie->count();
    if(count >= show_samples){
        serie->remove(0);
        serie->append(show_samples - 1, value);
    }else{
        serie->append(count, value);
    }
    return serie;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 23:42:03