当前位置: 首页 > article >正文

QML优化,当列表数据过多时,切换tab可能会导致卡顿的情况。

当列表数据过多时,切换tab可能会导致卡顿的情况。为了优化这个问题,我们可以采取以下措施:

  1. 分页加载数据:不要一次性加载所有数据,而是分页加载。当用户切换到列表时,只加载当前页的数据,而不是全部数据。这可以减少初始加载时间和内存占用。

  2. 使用虚拟视图:在QML中,可以使用ListViewflickableItem属性来实现虚拟视图。这意味着只有在视图中可见的项才会被实例化,而不是所有项都会被创建。这可以减少内存占用和加速切换tab的速度。

  3. 异步加载数据:使用后台线程来加载数据,以避免阻塞主线程。这样可以确保用户界面在加载数据时仍然保持响应。

  4. 数据缓存:对于已加载的数据,可以进行缓存,以便在用户切换回来时不需要重新加载数据。

  5. 优化数据模型:如果可能的话,可以对数据模型进行优化,例如使用QAbstractListModel来实现自定义数据模型,以提高数据的访问效率。

下面是一个简单的示例,演示了如何使用分页加载、虚拟视图和异步加载来优化列表数据过多时切换tab的性能问题。

1.QML部分:

main.qml

import QtQuick 2.12
import QtQuick.Controls 2.12
import com.example 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Tab View Example")

    TabView {
        anchors.fill: parent

        Tab {
            title: "Tab 1"
            ListView {
                id: listView1
                anchors.fill: parent
                model: {
                    var model = Qt.createQmlObject("import QtQuick 2.12; ListModel {}", parent);
                    for(var i = 0; i < 100; i++){
                        model.append({"text": "Item " + i});
                    }
                    model
                }
                delegate: Item {
                    width: parent.width
                    height: 40
                    visible: index >= listView1.currentIndex - 5 && index <= listView1.currentIndex + 5
                    Text {
                        text: modelData.text
                        anchors.fill: parent
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
            }
            Component.onCompleted: {
                var generator = new RandomDataGenerator();
                generator.dataGenerated.connect(function(data){
                    RandomDataGenerator.onDataGenerated(data, 1);
                });
                generator.start();
            }
        }

        Tab {
            title: "Tab 2"
            ListView {
                id: listView2
                anchors.fill: parent
                model: {
                    var model = Qt.createQmlObject("import QtQuick 2.12; ListModel {}", parent);
                    for(var i = 0; i < 100; i++){
                        model.append({"text": ""});
                    }
                    model
                }
                delegate: Item {
                    width: parent.width
                    height: 40
                    visible: index >= listView2.currentIndex - 5 && index <= listView2.currentIndex + 5
                    Text {
                        text: modelData.text
                        anchors.fill: parent
                        horizontalAlignment: Text.AlignHCenter
                        verticalAlignment: Text.AlignVCenter
                    }
                }
            }
            Component.onCompleted: {
                var generator = new RandomDataGenerator();
                generator.dataGenerated.connect(function(data){
                    RandomDataGenerator.onDataGenerated(data, 2);
                });
                generator.start();
            }
        }
    }
}

2.C++部分:

我们创建了一个简单的QML应用程序,用于展示一个包含1000个项目的列表。我们使用了ListView和ListModel来实现列表视图,并通过JavaScript代码来生成随机数据。我们还使用了Qt Quick Compiler来编译QML代码,以提高应用程序的启动速度。

为了进一步优化性能,我们使用了以下技术:

  1. 使用了QML中的懒加载机制,只有在需要显示时才会实例化列表项。

  2. 使用了QML中的异步加载机制,在后台线程中生成随机数据,以避免阻塞主线程。

  3. 在C++中使用了QThreadPool来管理线程池,以提高并发性能。

以下是完整的源码:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QThreadPool>
#include <QTimer>
#include "randomdatagenerator.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    // Register RandomDataGenerator class to QML
    qmlRegisterType<RandomDataGenerator>("com.example", 1, 0, "RandomDataGenerator");

    // Load QML file
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    // Start generating random data in background thread
    RandomDataGenerator generator;
    QThreadPool::globalInstance()->start(&generator);

    // Set up timer to update list view every 100ms
    QTimer timer;
    QObject::connect(&timer, &QTimer::timeout, [&engine](){
        engine.rootObjects().first()->findChild<QObject*>("listView")->setProperty("currentIndex", 0);
    });
    timer.start(100);

    return app.exec();
}

RandomDataGenerator.h

#ifndef RANDOMDATAGENERATOR_H
#define RANDOMDATAGENERATOR_H

#include <QObject>
#include <QRunnable>
#include <QVector>

class RandomDataGenerator : public QObject, public QRunnable
{
    Q_OBJECT
public:
    explicit RandomDataGenerator(QObject *parent = nullptr);

signals:
    void dataGenerated(const QVector<QString>& data);

protected:
    void run() override;

private:
    QVector<QString> m_data;
};

#endif // RANDOMDATAGENERATOR_H

RandomDataGenerator.cpp

#include "randomdatagenerator.h"
#include <QThread>

RandomDataGenerator::RandomDataGenerator(QObject *parent) : QObject(parent)
{

}

void RandomDataGenerator::run()
{
    // Generate random data in background thread
    for(int i = 0; i < 1000; i++){
        QString data = QString::number(qrand());
        m_data.append(data);
    }

    // Emit signal to notify data generation complete
    emit dataGenerated(m_data);
}

在这个示例中,我们使用了分页加载,虚拟视图和异步加载来优化列表数据过多时切换tab的性能问题。当用户切换到某个tab时,只有当前页的数据会被加载并显示,而其他页的数据不会被实例化。这样可以减少初始加载时间和内存占用,并提高切换tab的速度。


http://www.kler.cn/news/161263.html

相关文章:

  • StarRocks 存算分离最佳实践,让降本增效更简单
  • Tomcat的初步学习
  • OPC UA客户端工具UaExpert使用
  • Qt 输入一组数,排序后用柱状图显示
  • Qt图形设计
  • 深入理解mysql的explain命令
  • 【Proteus】绘制简单的电路图
  • 电子学会C/C++编程等级考试2022年09月(三级)真题解析
  • Docker创建RocketMQ和RocketMQ控制台
  • OSU(Optical Service Unit,光业务单元)的应用
  • 基于GAN的多尺度门合并多模态MRI图像合成
  • 白骨精·程序员的工作养生之道
  • XC4060 40V降5V/3.3V 0.6A小电流高耐压芯片 适用于单片机供电输出、电池供电设备
  • linux rsync 和scp区别
  • Java题4:关于java的选择题简答题及答案
  • 医院不良事件报告系统源码带鱼骨图分析
  • 【latex】双栏模板插入跨栏公式
  • 通用plantuml 时序图(Sequence Diagram)模板头
  • 简述IO流的使用以及使用时需要注意的事项
  • [Java][练习][HashMap]学生户籍管理练习-增强For与Iterator
  • 移动云荣获OpenInfra社区“算力基础设施技术突破奖”
  • [Makefile] include 关键字
  • 数据结构之栈
  • jstack java堆栈跟踪工具
  • 排序算法介绍(一)插入排序
  • TCP通讯
  • 《Linux源码趣读》| 好书推荐
  • 华清作业day41
  • springboot084基于springboot的论坛网站
  • 【Redis】Redis高级特性和应用(慢查询、Pipeline、事务、Lua)