问题概述
本人在使用QListView插入大量数据时,界面卡顿十分严重。数据量大概只有上千左右,但是每个Item的内容比较多。当数据不停地插入一段时间后,卡顿到鼠标的移动都有点困难。
解决思路
QListView是典型的MVC思想的产物。界面呈现出来的数据其实就是model里面的数据,所以,要解决卡顿问题,就得从model下手。
首先,我们都知道,一个界面展示的数据是有限的,无论再多数据,人眼看到的一定是可视高度内的那几条。所以,我们可以假设表格的item固定高度为H
,表格的高度为S
,那么展示出来的数量就是 C = S H C=\frac {S}{H} C=HS,我们就称该数量为C
吧。
这样,我们的表格只需要插入C
数量的Item就行了。当用户要查看其它数据,拉动滚动条的时候,我们只需要计算当前用户滚动条的位置,所对应的数据的索引,然后再重复利用刚才已经插入的Item,将Item的内容更新就能解决问题了。
代码思路
- 数据到来的时候,不直接插入model,而是先缓存到一个队列里,称之为
Buffer
。后面根据计算,再插入/刷新到model。 - 每次表格大小变化的时候,都需要计算一次当前界面可展示的数据量,称为
ShowCount
。 - 表格的Item高度固定,展示的数量等于 S h o w C o u n t = 表格高度 I t e m 高度 ShowCount=\frac {表格高度}{Item高度} ShowCount=Item高度表格高度(动态高度很麻烦,没特殊需求直接固定一个合理高度即可)。
- 滚动条需要自定义,不使用QListView自带的滚动条(需要隐藏)。滚动条高度为
Item高度 * 数据总量
。 - 滚动条对应的数据索引假设为
Index
,那么 I n d e x = c e i l ( 当前滚动条位置 I t e m 高度 ) Index=ceil(\frac {当前滚动条位置}{Item高度}) Index=ceil(Item高度当前滚动条位置)。 - 每次拉动滚动条时,Model内部的Item不删除,而是直接把新数据刷新到原本的item上。
最终效果
代码传送门
gitee代码
其它
- 滚动条自定义的原因:在不往表格插入大量数据的情况下,我不知道怎么撑起Qt的列表滚动条,知道的请务必告诉我下~
- 上面的阐述中,可能由于我表达比较匮乏,导致部分人无法GET到我的思路。其实这个就是
虚拟化列表
的一种实现方法。大家可以去搜搜虚拟化列表
,网上有非常多更细致的讲解以及现成稳定的代码。