首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何重新绘制QChart

如何重新绘制QChart
EN

Stack Overflow用户
提问于 2016-08-06 12:12:20
回答 2查看 12.2K关注 0票数 6

我想知道在向QChart QLineSeries 添加了新的点数之后,如何重新绘制。的目标是用来显示以高速率获取的数据(每秒40万次),并在点到达数据包时更新情节。

下面是我一直在做的测试程序:

MainWindow:

代码语言:javascript
复制
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构造函数:

代码语言:javascript
复制
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事件:

代码语言:javascript
复制
void MainWindow::on_pB_Start_clicked(){
    series->append(cnt,qSin(cnt/10));
    cnt++;
    // Update plot here << ======== HOW?
}

OpenGLSeries示例以某种方式做到了这一点。我不明白怎么回事。但是这种情况有点不同,因为它用新的点代替了系列赛中的所有点,而不是附加它们。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-06 14:24:04

首先,如果您将在GUI线程中以每秒400000秒的速度接收和附加点,您的应用程序将被完全冻结。因此,您需要将另一个线程专门用于数据接收和处理,并使用(例如)与QueuedConnection连接的信号/插槽将处理过的图形数据发送到GUI线程。我所说的“处理”至少是指某种抽取(平均、下降、抽取,就像那些DSP人员理解的那样),因为每秒400000秒似乎速度很快,您将浪费内存和图形用户界面性能。但如果你不想毁灭,那就取决于你了。在这种情况下,您可以考虑一种比QueuedConnectioned信号/时隙更轻量级的数据传递机制。

第二个问题是什么时候策划?不久前,我用QCustomPlot以更低的速度实现了类似的功能。我面临的主要问题是,当我试图在接收到每个点后重新绘制时,特别是在绘制反别名图时,会出现巨大的(和变化的)滞后。在您的示例中,解决方案是子类QChartView (我想您已经这样做了),在其中重写timerEvent,并在需要启动/停止重新绘图时调用startTimer()/killTimer()。或者,您可以在拥有QChartView对象的对象中持有一个计时器,然后从那里重新绘制,但与子类QChartView相比,它看起来像是抽象泄漏。总之,这种方法允许您实现几乎恒定的框架,并使它像您想要的那样平滑,而无需冻结应用程序的界面。

最后,如何重新绘制?QChartView似乎从QWidget继承了repaint()方法,该方法可以满足您的需要。

票数 2
EN

Stack Overflow用户

发布于 2016-08-06 16:32:21

显然QCharts不需要repaint()。在这个系列中增加新的点似乎就足够了。我没有看到数据,因为我没有为字符设置轴,也因为没有正确地计算值。

修正代码:

标题:

代码语言:javascript
复制
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转换成双倍。

代码语言:javascript
复制
void MainWindow::on_pB_Start_clicked(){
    double val = 3*(qSin((double)cnt*2)+2);
    series->append(cnt,val); // Enough to trigger repaint!
    cnt++;
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38804179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档