_S_Q 2023-09-25 14:59 采纳率: 100%
浏览 156
已结题

Qt,C++,QCustomPlot加载大量数据点时,界面卡顿解决方法?

Qt,C++,QCustomPlot加载大量数据点时,界面卡顿解决方法?

    QCPGraph *g1 = NULL;
    QCPGraph *g2 = NULL;

    g1 = addGraph();
    g2 = addGraph(xAxis, yAxis2);
    g1->setPen(QColor(COLOR_PLOT_V));
    g2->setPen(QColor(COLOR_PLOT_I));
    g1->setName(tr("电压"));
    g2->setName(tr("电流"));

    QVector<QCPGraphData> data1;
    QVector<QCPGraphData> data2;
    // QList<CYCLE*> mCycle 该数据量约2千万个
    for(int i = 0; i < mCycle.size(); i++)
    {
        auto r = mCycle.at(i);
        double xRecord = i;
        double fv = r->fv;
        double fi = r->fi;
        data1.append(QCPGraphData(xRecord, fv));
        data2.append(QCPGraphData(xRecord, fi));   
    }
    g1->data()->set(data1, true);
    g2->data()->set(data2, true);

    replot();
  • 写回答

1条回答 默认 最新

  • 山南1109 移动开发领域新星创作者 2023-09-25 15:03
    关注

    对于加载大量数据点时界面卡顿的问题,以下是一些优化建议:

    分批加载数据点:不要一次性将所有数据点添加到图形中,而是分批加载,以减少界面卡顿。您可以使用定时器或异步加载的方式来逐步加载数据点。在每个批次中,只添加一部分数据点,并给用户展示进度。

    使用异步加载:将加载数据点的操作放在异步线程中进行,以确保界面的响应性。您可以通过使用QRunnable和QThreadPool来实现异步加载数据点的任务。加载完成后,发送信号通知主线程刷新图形。

    数据压缩和采样:如果您的数据点数量非常大,可以考虑对数据进行压缩和采样。通过降低数据点的密度,可以减少绘图时的计算量,从而提高性能。

    使用OpenGL加速:如果您的Qt应用程序支持OpenGL,可以尝试通过使用QCustomPlot的OpenGL渲染模式来加速绘图。启用OpenGL后,绘图操作将由GPU执行,可以提高绘图性能和流畅度。

    下面是一个基于上述优化建议的示例代码:

    // 首先,将加载数据点的操作放在异步线程中进行
    QThreadPool::globalInstance()->start(new LoadDataPointsTask(g1, g2, mCycle));
    
    // 在LoadDataPointsTask类中进行数据点的异步加载和添加
    class LoadDataPointsTask : public QRunnable
    {
    public:
        LoadDataPointsTask(QCPGraph *graph1, QCPGraph *graph2, const QList<CYCLE*>& cycles)
            : mGraph1(graph1), mGraph2(graph2), mCycles(cycles) {}
    
        void run() override
        {
            QVector<QCPGraphData> data1;
            QVector<QCPGraphData> data2;
            for (int i = 0; i < mCycles.size(); i++)
            {
                auto r = mCycles.at(i);
                double xRecord = i;
                double fv = r->fv;
                double fi = r->fi;
                data1.append(QCPGraphData(xRecord, fv));
                data2.append(QCPGraphData(xRecord, fi));
            }
    
            // 将数据点分批添加到图形中
            const int batchSize = 1000; // 每批加载1000个数据点
            for (int i = 0; i < data1.size(); i += batchSize)
            {
                const int endIndex = qMin(i + batchSize, data1.size());
                QVector<QCPGraphData> batchData1 = data1.mid(i, endIndex - i);
                QVector<QCPGraphData> batchData2 = data2.mid(i, endIndex - i);
    
                QMetaObject::invokeMethod(this, "addDataPoints", Qt::QueuedConnection,
                                          Q_ARG(QVector<QCPGraphData>, batchData1),
                                          Q_ARG(QVector<QCPGraphData>, batchData2));
    
                QThread::msleep(10); // 加载一批数据点后暂停10毫秒
            }
    
            emit updateUI(); // 发送信号通知主线程刷新图形
        }
    
    signals:
        void addDataPoints(QVector<QCPGraphData> data1, QVector<QCPGraphData> data2);
        void updateUI();
    
    private:
        QCPGraph *mGraph1;
        QCPGraph *mGraph2;
        QList<CYCLE*> mCycles;
    };
    
    // 然后,在主线程中接收信号并添加数据点到图形中
    QObject::connect(task, &LoadDataPointsTask::addDataPoints, [=](QVector<QCPGraphData> data1, QVector<QCPGraphData> data2) {
        g1->data()->add(data1, true);
        g2->data()->add(data2, true);
    });
    
    // 最后,刷新图形
    QObject::connect(task, &LoadDataPointsTask::updateUI, [=]() {
        replot();
    });
    

    请根据您自己的需求和具体情况进行适当调整和改进。这个示例代码能够通过分批加载数据点、异步加载和OpenGL加速来优化QCustomPlot加载大量数据点时的

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月25日
  • 已采纳回答 9月25日
  • 创建了问题 9月25日

悬赏问题

  • ¥20 校园二手交易小程序搭建
  • ¥15 请问在ubuntu用conda创建环境报错怎么能解决
  • ¥15 STM32CubeMX/proteus按键控制指示灯颜色切换
  • ¥20 python,计算区位熵和扩张指数
  • ¥15 Python环境配置
  • ¥15 大四学生的困惑,有偿提问!
  • ¥15 解决页面无法编入索引:被“noindex”标签排除的问题?
  • ¥15 arduino测量电阻
  • ¥15 快手uid转快手号谁能解决 需要开发
  • ¥15 iis部署Django时css不生效,来个真人,ai不好使