QListWidget 加载大量数据时造成了页面的卡顿,通过分页的方式先加载一页数据,然后之后的数据通过滚动方式去加载剩余的数据量,此方法可以在大量数据插入时提高数据显示的时间
mainWindow.h
loading
变量,用于标记当前是否正在加载数据。
在加载数据之前,将 loading
设置为 true
,加载完成后将其设置为 false
。
在 scrollBarValueChanged()
函数中,只有当 loading
为 false
且下一页的起始索引小于总数据条数时,才执行加载下一页数据的操作,避免了重复加载的问题
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
//计算下一页的起始索引
int startIndexForNextPage() const {
return (currentPage + 1) * pageSize;
}
private slots:
void scrollValueChanged(int value);
void loadItems(int startIndex, int endIndex);
private:
Ui::MainWindow *ui;
QListWidget *listWidget;
int currentPage = 0; //起始页当前页数
int pageSize = 10;//每页显示的数据条数
int totalRowCount = 50000; //总数据量
bool loading = false; // 是否正在加载数据
};
mainWindow.cpp
#include <QScrollBar>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
listWidget = new QListWidget(this);
setCentralWidget(listWidget);
connect(listWidget->verticalScrollBar(), &QScrollBar::valueChanged, this, &MainWindow::scrollValueChanged);
loadItems(0,pageSize - 1); // 加载第一页数据
this->resize(QSize(200,200));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::scrollValueChanged(int value)
{
int maxScrollValue = listWidget->verticalScrollBar()->maximum(); // 获取滚动条的最大值
// 当滚动条的值达到最大值,且下一页的起始索引小于总数据条数,且当前没有正在加载数据时执行
if (value == maxScrollValue && startIndexForNextPage() < totalRowCount && !loading) {
loading = true; // 开始加载数据
int nextPageStartIndex = startIndexForNextPage(); // 下一页的起始索引
int nextPageEndIndex = nextPageStartIndex + pageSize - 1; // 下一页的结束索引
loadItems(nextPageStartIndex, nextPageEndIndex);
currentPage++; // 当前页数加1
loading = false; // 加载数据完成
}
}
void MainWindow::loadItems(int startIndex, int endIndex)
{
endIndex = qMin(endIndex, totalRowCount - 1); //结束索引不能超过总数据条数-1
for (int i = startIndex; i <= endIndex; ++i) {
QListWidgetItem *item = new QListWidgetItem(QString("Data %1").arg(i));
listWidget->addItem(item);
}
}