[英]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.