gpt4 book ai didi

qt - QChart 对大数据集无响应

转载 作者:行者123 更新时间:2023-12-02 20:16:17 24 4
gpt4 key购买 nike

我有这段代码,它适用于最大 1000 的数据大小。现在我用 65536 个点对其进行了测试。

series = new QLineSeries();

QList<QPointF> points;
points.reserve(data.size());

for(std::vector<int>::size_type i = 0; i != data.size(); i++) {
QPointF point(i, data[i]*100/max);
points.append(point);
}
series->clear();
series->append(points);

应用程序在 1 个核心满功率时卡住。我在几分钟后停止了它。

如何防止 Qt 变得无响应。这个数据大小并不特殊,我希望图 TableView 能够处理高达百万点的数据集。

编辑:我测量了时间

series->append(points);

2000点需要1秒。这意味着大约一分钟 > 50.000 那是不可用的。

更糟糕的是,对数刻度图

serieslog->append(points);

2000点需要40秒。那是完全不能用的。原因是调试消息,几乎每个点都会打印出来。

QtCharts::XLogYDomain::calculateGeometryPoints(const QVector&) const>; Logarithms of zero and negative values are undefined.

我可以用

加速线性图
 series->setUseOpenGL(true);

然而,对于 65536,它仍然需要 14 秒,这意味着每个点 200 微秒。还是很多。我想要一个最低 10 Hz 的实时视频和一个实时直方图。时间必须 << 1 秒。

编辑:这是一个工作示例,使用我的代码

#include <QDebug>
#include <QTime>
#include <cmath>
#include <stdlib.h>

#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
#include <QtCharts/QLogValueAxis>
#include <QtCharts/QValueAxis>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>

QT_CHARTS_USE_NAMESPACE

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QLineSeries * series;
QLineSeries * serieslog;
QChart * chart;
QChartView * chartView;
QValueAxis * axisX;
QValueAxis * axisY;
QLogValueAxis * axisY3;


chart = new QChart();
chart->legend()->hide();
chart->setTitle("Histogramm");

axisX = new QValueAxis;
chart->addAxis(axisX, Qt::AlignBottom);

series = new QLineSeries;
chart->addSeries(series);

axisY = new QValueAxis;
axisY->setTitleText("linear scale");
axisY->setLinePenColor(series->pen().color());
axisY->setGridLinePen((series->pen()));

chart->addAxis(axisY, Qt::AlignLeft);
series->attachAxis(axisX);
series->attachAxis(axisY);

serieslog = new QLineSeries;
chart->addSeries(serieslog);

axisY3 = new QLogValueAxis();
axisY3->setTitleText("logarithmic scale");
axisY3->setLabelFormat("%g");
axisY3->setLinePenColor(serieslog->pen().color());
axisY3->setGridLinePen((serieslog->pen()));
axisY3->setMinorTickCount(-1);

chart->addAxis(axisY3, Qt::AlignRight);
serieslog->attachAxis(axisX);
serieslog->attachAxis(axisY3);

chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);

// create data

std::vector<int> data;
int N = 10000;
data.resize(N);
for (int i=0; i < N; ++i){
int value = static_cast<int>(fabs((sin(static_cast<double>(i)/1000.0)+1)*1+ std::rand() % 100)+10);
data[i] = value;
}

QList<QPointF> points;
points.reserve(data.size());

for(std::vector<int>::size_type i = 0; i != data.size(); i++) { //
QPointF point(i, data[i]);
points.append(point);
}
QTime myTimer;
myTimer.start();

series->clear();
// series->setUseOpenGL(true);
series->append(points);
qDebug() << "seconds lin: " << myTimer.elapsed();
myTimer.start();
serieslog->clear();
serieslog->append(points);
qDebug() << "seconds log: " << myTimer.elapsed();

chart->axisX()->setRange(0, data.size());
chart->axisY()->setRange(-10, 250);

QMainWindow window;
window.setCentralWidget(chartView);
window.resize(800, 600);
window.show();

return app.exec();
}


QT += core
QT += widgets
QT += gui
QT += charts

SOURCES += \
main.cpp

我测量毫秒林:1624毫秒日志:6801

最佳答案

我可以重现这个问题(经过类似的时间),这似乎是 QXYSeries::append 处理 QList 的方式的问题。从代码...

void QXYSeries::append(const QList<QPointF> &points)
{
foreach (const QPointF &point , points)
append(point);
}

和...

void QXYSeries::append(const QPointF &point)
{
Q_D(QXYSeries);

if (isValidValue(point)) {
d->m_points << point;
emit pointAdded(d->m_points.count() - 1);
}
}

因此,每次添加点都可能导致 QVector d->m_points 调整大小并发出 pointAdded 信号。

鉴于您在调用 QXYSeries::append 之前清除了与系列相关的所有数据,您可以改用 QXYSeries::replace

如果您必须将初始数据生成为QList,那么只需使用...

series->replace(points);

但是,它在内部使用 QList::toVector,所以如果您可以将数据生成为 QVector 那么就更好了...

QVector<QPointF> points(data.size());

for(std::vector<int>::size_type i = 0; i != data.size(); ++i) {
points[i] = QPointF(i, data[i]);
}

QTime myTimer;
myTimer.start();

series->replace(points);
qDebug() << "\nlin: " << myTimer.elapsed() << "ms\n";

myTimer.start();
serieslog->replace(points);
qDebug() << "\nlog: " << myTimer.elapsed() << "ms\n";

上述代码在我自己的系统上导致...

lin:  1 ms
log: 3 ms

为了 10k 点,为了 100k 点...

lin:  6 ms
log: 22 ms

关于qt - QChart 对大数据集无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52320696/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com