How to repaint a QChart

后端 未结 2 862
离开以前
离开以前 2021-02-10 01:46

I\'d like to know how to repaint a QChart after I append new points to the QLineSeries added to it. The goal is to use this for displa

相关标签:
2条回答
  • 2021-02-10 02:15

    Apparently QCharts doesn't need repaint(). Appending new points to the series seems to be enough. I wasn't seeing the data because I hadn't set the axis for the char and also because values weren't properly calculated.

    Corrected code:

    Header:

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){
        ui->setupUi(this);
    
        series = new QLineSeries();
    
        chart = new QChart();    
        chart->addSeries(series);
    
        chart->createDefaultAxes(); // Preparing the axis
        chart->axisX()->setRange(0,10); 
        chart->axisY()->setRange(0,10); 
    
        // Same formatting
        chart->setBackgroundVisible(false);
        chart->setMargins(QMargins(0,0,0,0));
        chart->layout()->setContentsMargins(0,0,0,0);
        chart->legend()->hide();
        chart->setPlotAreaBackgroundBrush(QBrush(Qt::black));
        chart->setPlotAreaBackgroundVisible(true);
        chartView = new QChartView(chart);
        ui->gridLayout->addWidget(chartView);
    }
    

    And the pushButton code, casting cnt to double before calculation.

    void MainWindow::on_pB_Start_clicked(){
        double val = 3*(qSin((double)cnt*2)+2);
        series->append(cnt,val); // Enough to trigger repaint!
        cnt++;
    }
    
    0 讨论(0)
  • 2021-02-10 02:24

    First, if your will receive and append points at 400000 pts/sec in GUI thread, your application will get absolutely freezed. So you need to dedicate another thread to data receiving and processing, and send processed graphics data to the GUI thread using (for example) signals/slots connected with QueuedConnection. By "processing" I mean at least some sort of decimation (averaging, dropping, decimation as those DSP guys understand it), because 400000 pts/sec seems to fast, you'll waste your memory and GUI performance. But if you do not want to decimate, it's up to you. In this case you may consider a more lightweight data delivery mechanism than QueuedConnectioned signals/slots.

    The second question is when to plot? Not so long ago I implemented similar functionality with QCustomPlot at much lower rates. The main problem I faced was a huge (and varying) lag when I tried to replot after receiving each point, especially while plotting antialiased graph. In your case the solution is to subclass QChartView (I suppose you have already done it), override timerEvent in it and call startTimer()/killTimer() when you need to start/stop replotting. Alternatively, you may hold a timer in an object which owns the QChartView object and issue replotting from there, but it looks like abstraction leakage in comparison to subclassing QChartView. All in all, this approach allows you to achieve almost constant framerate and make it as smooth as you want without freezing application's interface.

    And finally, how to replot? QChartView seems to have repaint() method inherited from QWidget which does what you need.

    0 讨论(0)
提交回复
热议问题