9

我正在生成一些我想使用QChart和朋友绘制图表的数据。这是我第一次使用QChart,所以基本上我所做的就是复制QLineSeries 示例并根据我的需要进行修改。我当前的代码如下所示:

    quint64 last=0;
    quint64 *lastp=&last;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , series( nullptr )
{
    ui->setupUi(this);
    QChart *chart = new QChart();
    series=new QLineSeries(chart);
    chart->legend()->hide();
    chart->addSeries(series);
    chart->createDefaultAxes();
    chart->setTitle("Simple line chart example");
    QChartView *chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);
    setCentralWidget(chartView);
    GeneticTask *gTask = new GeneticTask();
    connect(gTask, &GeneticTask::point, this, [=](QPointF pt) {
        // New point added to series
        *series<<pt;
        // Limit updates to once per second
        quint64 now=QDateTime::currentMSecsSinceEpoch();
        if(now-(*lastp)>1000) {
            qDebug()<<"UPDATE";
            // [A] WHAT TO PUT HERE TO HAVE CHART REDRAW WITH NEW DATA?
            *lastp=now;
        }
    }
    );
    QThreadPool::globalInstance()->start(gTask);
}

当我运行此代码时,我希望我的新数据会显示在图表中,但事实并非如此,所以我的问题是:如何让图表更新以显示新数据?换句话说,我应该在注释读取的代码中放入什么[A]

4

2 回答 2

7

QLineSeries使用运算符<<或方法附加一个值append应该重新绘制图形。如果由于某种原因没有发生,您可以尝试repaintQChartView.

这是一些代码,一旦添加数据,它将以每秒最多一次的上限为中心:

// Global or class scope or
qreal max=-10000000000;
qreal min=-max;
qreal *maxp=&max;
qreal *minp=&min;

// Same scope as before
connect(gTask, &GeneticTask::point, this, [=](QPointF pt) {
        if(pt.y()>*maxp) {
            *maxp=pt.y();
        }
        if(pt.y()<*minp) {
            *minp=pt.y();
        }
        *series<<pt;
        quint64 now=QDateTime::currentMSecsSinceEpoch();
        if(now-(*lastp)>1000) {
            qDebug()<<"UPDATE";
            chart->axisX()->setRange(0,series->count());
            chart->axisY()->setRange(*minp,*maxp);

            *lastp=now;
        }
    }
);
于 2017-03-24T23:29:19.743 回答
1

对上面的答案稍加修正。Qt 文档说:

void QWidget::repaint() 通过立即调用paintEvent() 直接重绘小部件,除非更新被禁用或小部件被隐藏。我们建议仅在需要立即重新绘制时才使用 repaint(),例如在动画期间。在几乎所有情况下 update() 更好,因为它允许 Qt 优化速度并最小化闪烁。
警告:如果您在一个本身可能从paintEvent() 调用的函数中调用repaint(),您可能会得到无限递归。update() 函数永远不会导致递归。

结果,QChartView::update()对我有用。

于 2020-08-28T10:33:58.143 回答