我的这段代码适用于高达 1000 的数据大小。现在我用 65536 个点对其进行了测试。
\n\nseries = new QLineSeries();\n\nQList<QPointF> points;\npoints.reserve(data.size());\n\nfor(std::vector<int>::size_type i = 0; i != data.size(); i++) {\n QPointF point(i, data[i]*100/max);\n points.append(point);\n}\nseries->clear();\nseries->append(points);\nRun Code Online (Sandbox Code Playgroud)\n\n并且应用程序在 1 个核心全功率运行时冻结。几分钟后我就停下来了。
\n\n如何防止 Qt 变得无响应。这个数据大小并不特殊,我希望图表视图能够处理高达百万点的数据集。
\n\n编辑:\n我测量了时间
\n\nseries->append(points);\nRun Code Online (Sandbox Code Playgroud)\n\n2000分需要1秒。这意味着大约一分钟内 > 50.000 是无法使用的。
\n\n更糟糕的是,对数刻度图
\n\nserieslog->append(points);\nRun Code Online (Sandbox Code Playgroud)\n\n2000分需要40秒。那是完全无法使用的。原因是调试消息,几乎每个点都会打印出来。
\n\n\n\n\nQtCharts::XLogYDomain::calculateGeometryPoints(const QVector&) const>; 零和负值的对数未定义。
\n
我可以用以下方法加快线性图的速度
\n\n series->setUseOpenGL(true);\nRun Code Online (Sandbox Code Playgroud)\n\n然而,对于 65536,它仍然需要 14 秒,这意味着每个点 200 \xc2\xb5s。\n仍然太多。我想要一个最低 10 Hz 的实时视频和一个实时直方图。时间必须 << 1 秒。
\n\n编辑:\n这是一个使用我的代码的工作示例
\n\n#include <QDebug>\n#include <QTime>\n#include <cmath>\n#include <stdlib.h>\n\n#include <QtCharts/QChartView>\n#include <QtCharts/QLineSeries>\n#include <QtCharts/QLogValueAxis>\n#include <QtCharts/QValueAxis>\n#include <QtWidgets/QApplication>\n#include <QtWidgets/QMainWindow>\n\nQT_CHARTS_USE_NAMESPACE\n\nint main(int argc, char *argv[])\n{\n QApplication app(argc, argv);\n\n QLineSeries * series;\n QLineSeries * serieslog;\n QChart * chart;\n QChartView * chartView;\n QValueAxis * axisX;\n QValueAxis * axisY;\n QLogValueAxis * axisY3;\n\n\n chart = new QChart();\n chart->legend()->hide();\n chart->setTitle("Histogramm");\n\n axisX = new QValueAxis;\n chart->addAxis(axisX, Qt::AlignBottom);\n\n series = new QLineSeries;\n chart->addSeries(series);\n\n axisY = new QValueAxis;\n axisY->setTitleText("linear scale");\n axisY->setLinePenColor(series->pen().color());\n axisY->setGridLinePen((series->pen()));\n\n chart->addAxis(axisY, Qt::AlignLeft);\n series->attachAxis(axisX);\n series->attachAxis(axisY);\n\n serieslog = new QLineSeries;\n chart->addSeries(serieslog);\n\n axisY3 = new QLogValueAxis();\n axisY3->setTitleText("logarithmic scale");\n axisY3->setLabelFormat("%g");\n axisY3->setLinePenColor(serieslog->pen().color());\n axisY3->setGridLinePen((serieslog->pen()));\n axisY3->setMinorTickCount(-1);\n\n chart->addAxis(axisY3, Qt::AlignRight);\n serieslog->attachAxis(axisX);\n serieslog->attachAxis(axisY3);\n\n chartView = new QChartView(chart);\n chartView->setRenderHint(QPainter::Antialiasing);\n\n // create data\n\n std::vector<int> data;\n int N = 10000;\n data.resize(N);\n for (int i=0; i < N; ++i){\n int value = static_cast<int>(fabs((sin(static_cast<double>(i)/1000.0)+1)*1+ std::rand() % 100)+10);\n data[i] = value;\n }\n\n QList<QPointF> points;\n points.reserve(data.size());\n\n for(std::vector<int>::size_type i = 0; i != data.size(); i++) { //\n QPointF point(i, data[i]);\n points.append(point);\n }\n QTime myTimer;\n myTimer.start();\n\n series->clear();\n// series->setUseOpenGL(true);\n series->append(points);\n qDebug() << "seconds lin: " << myTimer.elapsed();\n myTimer.start();\n serieslog->clear();\n serieslog->append(points);\n qDebug() << "seconds log: " << myTimer.elapsed();\n\n chart->axisX()->setRange(0, data.size());\n chart->axisY()->setRange(-10, 250);\n\n QMainWindow window;\n window.setCentralWidget(chartView);\n window.resize(800, 600);\n window.show();\n\n return app.exec();\n}\n\n\nQT += core\nQT += widgets\nQT += gui\nQT += charts\n\nSOURCES += \\\n main.cpp\nRun Code Online (Sandbox Code Playgroud)\n\n我测量\nm秒林:1624\nm秒日志:6801
\nQXYSeries::append我可以重现该问题(具有相似的经过时间),这似乎是处理方式的问题QList。从代码...
void QXYSeries::append(const QList<QPointF> &points)
{
foreach (const QPointF &point , points)
append(point);
}
Run Code Online (Sandbox Code Playgroud)
和...
void QXYSeries::append(const QPointF &point)
{
Q_D(QXYSeries);
if (isValidValue(point)) {
d->m_points << point;
emit pointAdded(d->m_points.count() - 1);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,每个点的添加都可能导致QVector d->m_points调整大小并pointAdded发出信号。
鉴于您在调用之前清除了与该系列相关的所有数据,QXYSeries::append您可以QXYSeries::replace改为使用。
如果您必须生成初始数据,那么QList只需使用...
series->replace(points);
Run Code Online (Sandbox Code Playgroud)
但是,在内部使用QList::toVectorso 如果您可以生成数据,那么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";
Run Code Online (Sandbox Code Playgroud)
上面的代码在我自己的系统上会导致......
lin: 1 ms
log: 3 ms
Run Code Online (Sandbox Code Playgroud)
为了10k点,为了100k点......
lin: 6 ms
log: 22 ms
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3542 次 |
| 最近记录: |