【问题标题】:QChart slows down in QT applicationQChart 在 QT 应用程序中变慢
【发布时间】:2019-08-29 01:00:52
【问题描述】:

所以我正在编写一个 QT 应用程序,该应用程序将从串行端口读取值并在运行时将它们显示在图表中。我设法在运行时使用随机生成的值更新了我的 QChart,以尝试实时更新,一切正常。

但是我的应用程序会越来越慢,直到它完全无法使用为止。

我确实知道包含我的积分的列表会增加,但是在 100 点左右之后它真的真的变慢了,真的很快,感觉就像我有某种内存泄漏?

我知道通常的答案是“不要使用 QCharts”,但我是 C++ 和 QT 的初学者,所以这就是我为简单起见而使用的。

MainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
#include <QGridLayout>

#include <QLabel>
#include <QDebug>

QT_CHARTS_USE_NAMESPACE
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    series = new QLineSeries();

    chart = new QChart();
    chart->legend()->hide();
    chart->addSeries(series);
    chart->createDefaultAxes();
    chart->axes(Qt::Vertical).back()->setRange(-10, 10);
    chart->axes(Qt::Horizontal).back()->setRange(0, 100);

    chart->setContentsMargins(0, 0, 0, 0);
    chart->setBackgroundRoundness(0);

    QChartView *chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);
    ui->setupUi(this);

    QLabel *label = new QLabel();
    label->setText("Hello World");

    QGridLayout *layout = new QGridLayout;
    QWidget * central = new QWidget();
    setCentralWidget(central);
    centralWidget()->setLayout(layout);

    layout->addWidget(chartView, 0, 0);

    clock = 0;

    SerialPortReader *reader = new SerialPortReader(this);

    connect(reader, SIGNAL(onReadValue(int)), this, SLOT(onReadValue(int)));

    reader->run();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onReadValue(int value){
    ++clock;    
    series->append(clock + 30, value);
    chart->axes(Qt::Horizontal).back()->setRange(0 + clock, 100 + clock);    
}

SerialPortReader.cpp

#include "serialportreader.h"
#include "mainwindow.h"
#include <QtCore>
#include <QRandomGenerator>
#include <QDebug>

SerialPortReader::SerialPortReader(QObject *parent) : QThread(parent)
{
    this->parent = parent;
    this->randomGenerator = QRandomGenerator::global();
}

void SerialPortReader::run() {

    QTimer *timer = new QTimer(this);
    timer->start(100);
    connect(timer, SIGNAL(timeout()), this, SLOT(readValue()));
}

void SerialPortReader::readValue() {
    int value = randomGenerator->bounded(-10, 10);
    emit onReadValue(value);
}

我只是想知道是否有人对可能出现的问题有任何建议?或者如果有什么我可以做的,除了改变图表库。

【问题讨论】:

  • 是否可以选择批量更新并每秒执行一次?目前您每秒重绘图表 20 次(append 和 setRange 都会触发重绘)。要执行此更改 MainWindow::onReadValue 并将其附加到内部向量。如果内部向量达到一定大小(1x/s 为 10),则将点添加到系列并重置范围。
  • 这也可能有助于删除不再显示的点。
  • 我一直在考虑批量更新。但我不想删除未显示的点,因为最终我希望能够向后滚动并查看之前的内容。我收集的是来自 arduino 的陀螺仪数据,我想将陀螺仪数据“记录”到文件中,并在写入文件时实时查看数据。
  • 实际上我发现的一件事是抗锯齿的开启使它的性能好很多!这是完全有道理的,这会减慢很多。

标签: c++ qt qchart


【解决方案1】:

在修补之后,我发现罪魁祸首实际上并不是内存泄漏,而是:

chartView->setRenderHint(QPainter::Antialiasing);

随着呈现的数据越来越多,执行所有抗锯齿的速度就越慢。

当我删除它时,一切突然变得非常顺利。

【讨论】:

  • 进一步阅读,似乎使用 OpenGL 也应该有所帮助:“使用 OpenGL 加速系列绘图所获得的性能取决于底层硬件,但在大多数情况下,它很重要。例如,在标准台式计算机,为系列启用 OpenGL 加速通常允许渲染至少一百倍以上的点,而不会降低帧速率。”见QAbstractSeries::useOpenGL(默认为假)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-21
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多