簡體   English   中英

如何重繪QChart

[英]How to repaint a QChart

我想知道如何重繪一個QChart后我追加新的點到QLineSeries添加到它。 目的是將其用於顯示以高速率(高達40萬pts /秒)采集的數據,並在點到達數據包時更新繪圖。

這是我一直在努力的測試程序:

主窗口:

class MainWindow : public QMainWindow{
    Q_OBJECT

    QLineSeries *series;
    QChart *chart;
    QChartView *chartView;

    int cnt=0;


public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_pB_Start_clicked();

private:
    Ui::MainWindow *ui;
};

MainWindow構造函數:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){
    ui->setupUi(this);

    series = new QLineSeries();

    chart = new QChart();
    chart->setBackgroundRoundness(0);

    chart->addSeries(series);

 // A bunch of 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);

}

還有一個pushButton clicked事件,可以向系列添加點:

void MainWindow::on_pB_Start_clicked(){
    series->append(cnt,qSin(cnt/10));
    cnt++;
    // Update plot here << ======== HOW?
}

OpenGLSeries示例以某種方式做到了。 我不明白 但是這種情況有些不同,因為它用新的替換了系列中的所有點,而不是附加它們。

顯然,QCharts不需要repaint() 為該系列增加新的觀點似乎就足夠了。 我沒有看到數據,因為我沒有設置char的軸,也沒有正確計算值。

更正的代碼:

標頭:

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);
}

還有pushButton代碼,在計算前將cnt為double。

void MainWindow::on_pB_Start_clicked(){
    double val = 3*(qSin((double)cnt*2)+2);
    series->append(cnt,val); // Enough to trigger repaint!
    cnt++;
}

首先,如果您在GUI線程中以400000 pts / sec的速度接收和附加點,則您的應用程序將被完全凍結。 因此,您需要將另一個線程專用於數據接收和處理,並使用(例如)與QueuedConnection連接的信號/插槽將處理后的圖形數據發送到GUI線程。 “處理”是指至少某種程度的抽取(平均,下降,抽取,這是DSP專家所理解的),因為400000 pts / sec的速度似乎很快,所以您會浪費內存和GUI性能。 但是,如果您不想抽取,則取決於您。 在這種情況下,您可以考慮使用比QueuedConnection ed信號/插槽更輕巧的數據傳遞機制。

第二個問題是何時繪制? 不久前,我以較低的速率實現了QCustomPlot類似功能。 我遇到的主要問題是在接收到每個點后嘗試重新繪制時的巨大(且變化不定)的滯后,尤其是在繪制抗鋸齒圖時。 在您的情況下,解決方案是將QChartView子類QChartView (我想您已經完成了它),在其中重寫timerEvent並在需要啟動/停止重新killTimer()時調用startTimer() / killTimer() 或者,您可以在擁有QChartView對象的對象中保留一個計時器,然后從那里進行重新QChartView ,但是與子類化QChartView相比,它看起來像是抽象泄漏。 總而言之,這種方法可以使您獲得幾乎恆定的幀速率,並在不凍結應用程序界面的情況下使其盡可能平滑。

最后,如何重新繪制? QChartView似乎具有從QWidget繼承的repaint()方法,該方法可以完成您需要的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM