Search code examples
c++qtqt5qchart

Qt setUseOpenGL(true) and removeSeries() do not update QChart


The Problem

I'm using a Qt LineChart, this QLineChart can load and remove data without a problem on CPU rendering. However, QChart removeSeries() does not update my QLineChart properly when using setUseOpenGL(true). The removed data is still visible on the QChart. Strangely, when hovering the mouse over the QChart, the QChart is updated and data is removed.

Expected Result

Update QChart after calling removeSeries().

Observed Result

QChart is not updated.

What I've tried

  1. Call ChartView repaint() -- no effect
  2. Emit custom QEvent to simulate mouse hover over QChart -- no effect
  3. Set Widget which contains QChartView to FullViewportUpdate -- no effect

I'm all out of ideas. All suggestions are welcome. Relevant code:

QLineSeries *series3= data->getScanLineSeries();
series3->setUseOpenGL(true);
if(data->getLineSeriesOnChart() == false)
...
{
    chart->addSeries(series3);
    data->setLineSeriesOnChart(true);
    std::cout << "Series added to chart.";
    qDebug() << QString("Series added to chart");
}
else
{
    chart->removeSeries(series3);
    data->setLineSeriesOnChart(false);
    qDebug() << QString("ERROR: this series was already on the chart, removing QLineSeries");
    return chart;
}
...
(axes handling)
return chart;

Solution

  • I have checked the problem, and now I have a temporary solution and not very elegant, it may serve to advance, I have noticed that the chart is updated when you resize the chart, then this is a code that can help you:

    chartView->resize(chartView->size() + QSize(1, 1)); 
    chartView->resize(chartView->size() - QSize(1, 1));
    

    I'll keep on looking for a better solution

    Example:

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QLineSeries *series = new QLineSeries();
    
        series->append(0, 6);
        series->append(2, 4);
        series->append(3, 8);
        series->append(7, 4);
        series->append(10, 5);
        *series << QPointF(11, 1) << QPointF(13, 3) << QPointF(17, 6) << QPointF(18, 3) << QPointF(20, 2);
    
        series->setUseOpenGL(true);
    
        QChart *chart = new QChart();
        chart->legend()->hide();
        chart->addSeries(series);
        chart->createDefaultAxes();
        chart->setTitle("Simple line chart example");
    
        QChartView *chartView = new QChartView(chart);
        chartView->setRenderHint(QPainter::Antialiasing);
    
        QTimer timer;
        QObject::connect(&timer, &QTimer::timeout, [chart, series, chartView](){
            qDebug()<<chart->series();
            if(!chart->series().isEmpty())
                chart->removeSeries(series);
            else
                chart->addSeries(series);
            chartView->resize(chartView->size()+QSize(1, 1));
            chartView->resize(chartView->size()-QSize(1, 1));
        });
    
        timer.start(1000);
    
        QMainWindow window;
        window.setCentralWidget(chartView);
        window.resize(400, 300);
        window.show();
    
        return a.exec();
    }