导航:
论坛 -> DELPHI技术
斑竹:liumazi,sephil
作者:
2021/10/22 15:05:00
标题:
ListView 显示1000行内容为什么如此卡?
浏览:3118
加入我的收藏
楼主:
操作点击, 换行, 滚动. 根本就卡得要哭. 这是怎么回事? unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ComCtrls,qjson; type TForm1 = class(TForm) ListView1: TListView; BitBtn1: TBitBtn; BitBtn2: TBitBtn; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure ListView1Data(Sender: TObject; Item: TListItem); procedure BitBtn1Click(Sender: TObject); procedure BitBtn2Click(Sender: TObject); private { Private declarations } public Djson: Tqjson; { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.BitBtn1Click(Sender: TObject); begin ListView1.OwnerData := true; ListView1.Items.Count := Djson.Count; ListView1.Update; end; procedure TForm1.BitBtn2Click(Sender: TObject); var I:Integer; begin ListView1.OwnerData := false; for I := 0 to 1000 do begin with ListView1.Items.Add do begin Caption := IntToStr(I); SubItems.Add('asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'); SubItems.Add('asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'); SubItems.Add('asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'); SubItems.Add( 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'); SubItems.Add('asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'); SubItems.Add( 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'); SubItems.Add( 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'); SubItems.Add('asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'); SubItems.Add('asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'); SubItems.Add( 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'); end; end; end; procedure TForm1.FormCreate(Sender: TObject); var I:Integer; begin Djson := TQJson.Create; for I := 0 to 1000 do begin with Djson.Add(IntToStr(i)) do begin Add('test1').AsString := 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'; Add('test2').AsString := 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'; Add('test3').AsString := 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'; Add('test4').AsString := 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'; Add('test5').AsString := 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'; Add('test6').AsString := 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'; Add('test7').AsString := 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'; Add('test8').AsString := 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'; Add('test9').AsString := 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'; Add('test0').AsString := 'asfasd好像不是 BUG.fasd好像不是 BUG.好像不是 BUG.好像不是 BUG.好像不是 BUG.'; end; end; end; procedure TForm1.FormDestroy(Sender: TObject); begin FreeAndNil(Djson); end; procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem); var Dq:Tqjson; begin Dq := Djson.Items[Item.Index]; Item.Caption := Dq.Name; Item.SubItems.Add(Dq.ValueByName('test1','')); Item.SubItems.Add(Dq.ValueByName('test2','')); Item.SubItems.Add(Dq.ValueByName('test3','')); Item.SubItems.Add(Dq.ValueByName('test4','')); Item.SubItems.Add(Dq.ValueByName('test5','')); Item.SubItems.Add(Dq.ValueByName('test6','')); Item.SubItems.Add(Dq.ValueByName('test7','')); Item.SubItems.Add(Dq.ValueByName('test8','')); end; end.
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
2021/10/22 15:42:12
1楼:
list view, tree view要想显示大量数据, 可以用 VirtualTreeView, 1000条毫无压力
----------------------------------------------
UniKeeper V10.40 -- 您最贴心的个人数据管理助手
作者:
oyefer (oyefer)
★☆☆☆☆
-
盒子活跃会员
2021/10/22 15:48:04
2楼:
试试beginupdate,endupdate
----------------------------------------------
-
作者:
2021/10/22 15:56:40
3楼:
Berg Next里的控件性能也很好,1秒钟可以显示10万行 追求极致性能或者多功能,不要使用官方控件!
----------------------------------------------
只有偏执狂才能生存!
作者:
2021/10/22 16:08:33
4楼:
@oyefer 跟beginupdate,endupdate没关系, 已经显示完成了, 后续操作卡.
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
2021/10/22 16:12:09
4楼:
试了一下,直接加入的感觉还可以,用OwnerData的的确卡顿, 如果非要找个瓶颈,LISTVIEW本身是一方面,Djson可能性能也 是一方面。
----------------------------------------------
简单做人,认真做事。
作者:
2021/10/22 16:12:57
5楼:
@nevergrief 控件哪里下载?
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
2021/10/22 16:14:04
6楼:
@jackalan 不用json, 一样也是卡的... 主要还是listview卡. 不知道怎么解决.
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
vga (vga)
★☆☆☆☆
-
盒子活跃会员
2021/10/22 16:40:28
7楼:
VirtualTreeView, 10W 条毫无压力!
----------------------------------------------
-
作者:
2021/10/22 16:54:16
8楼:
VirtualTreeView 不是树型吗? 我要的是表格行..
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
vga (vga)
★☆☆☆☆
-
盒子活跃会员
2021/10/22 17:05:07
9楼:
可以作为grid用,自带Demo示例
此帖子包含附件: 大小: 18.4K
----------------------------------------------
-
作者:
2021/10/22 17:09:51
10楼:
@nevergrief Berg 虽然各项操作都顺了, 但数据更新好像没有OwnerData 隔一秒刷新一次数据, 仍然卡很久才显示出来.. 这才3000条. procedure TForm1.FormCreate(Sender: TObject); var i: Integer; begin for i := 1 to 3000 do begin with NextGrid61.AddRow do begin Cells[0].AsString := Planets[Random(9) + 1]; Cells[1].AsString := Planets[Random(9) + 1]+'中国'; Cells[2].AsString := Planets[Random(9) + 1]; Cells[3].AsString := Planets[Random(9) + 1]; Cells[4].AsString := 'A中国'+Planets[Random(9) + 1]; Cells[5].AsString := Planets[Random(9) + 1]; Cells[6].AsString := Planets[Random(9) + 1]; end; end; end;
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
2021/10/22 17:16:33
11楼:
@hardnut 没办法选中一行吧, treeview 应该不好弄. 图片是Berg
此帖子包含附件: 大小: 49.5K
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
vga (vga)
★☆☆☆☆
-
盒子活跃会员
2021/10/22 17:22:39
11楼:
这是官方的Demo,
此帖子包含附件: 大小: 163.9K
----------------------------------------------
-
作者:
2021/10/22 17:23:55
12楼:
@vga 我不是要树, 我是要行.
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
vga (vga)
★☆☆☆☆
-
盒子活跃会员
2021/10/22 17:27:36
13楼:
@tuesdays (Tuesday) VirtualTreeView 什么都有,就是麻烦!
----------------------------------------------
-
作者:
2021/10/22 17:34:34
14楼:
@vga 解决不了 TListView? 连1000行都支撑不了, 那也太弱了!! https://download.csdn.net/download/hksoobe/5627963 ListView快速显示100万条数据用时1秒 谁能够分享一下这个源码, 我要涨涨见识.
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
vga (vga)
★☆☆☆☆
-
盒子活跃会员
2021/10/22 20:12:30
15楼:
从VirtualTreeView官方的Demo 来看,就算要显示100万,也只要 150ms, 600万也只要 0.9秒,而且所用的机器为 i3 4代,集成显卡,太强了!!!
----------------------------------------------
-
作者:
2021/10/22 21:20:53
16楼:
@vga VirtualTreeView 有安装包没?
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
lsuper (lsuper)
★☆☆☆☆
-
盒子活跃会员
2021/10/23 0:21:08
17楼:
你使用 TListView 的姿势错了,基于 OwnerData 模式是你自己管理数据容器,通过 OnData 事件赋值(而不是 ListView1.Items.Add 这种);任意行如 1000w 行也秒出啊 ~
----------------------------------------------
-
作者:
2021/10/23 0:57:48
18楼:
@lsuper 先不管显示速度吧, 就是显示完成了, 滚动, 选择都很卡.
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
2021/10/23 9:03:04
19楼:
你这种,直接一个DBGrid/其它表格控件,无非连一个ClientDataset,自己插数据进去显示了,不分分钟比ListView快么,
----------------------------------------------
delphi|vue|golang hnysoft|hnyerp+mes+srm
作者:
2021/10/23 9:37:22
20楼:
@doersoft 这不是逃避是什么? 难道ListView控件是拿来挂墙上的吗? 一点用处没有?
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
2021/10/23 12:06:00
22楼:
标准ListView用虚方式在onData里面处理,几百万数据都没问题
----------------------------------------------
武稀松http://www.raysoftware.cn
作者:
2021/10/23 12:37:46
23楼:
TO: tuesdays 楼主这种展示内容的样式,就是个表格吧,咱只是给出解决问题折另一种思考。 单纯要用ListView达到快速响应,楼上的几位已经有答案了。
----------------------------------------------
delphi|vue|golang hnysoft|hnyerp+mes+srm
作者:
2021/10/23 15:38:20
24楼:
@wr960204 (武稀松) 附件里面就有用onData, 你可以看看, 的确很卡.. 武稀松大哥, 你能写个百万的示例不? 我要学习.
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
2021/10/23 15:49:38
25楼:
跟listview无关 虚方式再多显示也没事
----------------------------------------------
-
作者:
2021/10/23 15:50:33
26楼:
求代码.. @user2ccc (零度)
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
2021/10/23 19:51:11
27楼:
刚好手机上显示了企鹅空间许多年前的关于 listview的日志: https://user.qzone.qq.com/7998329/blog/1507261017?_t_=0.7203949675216126 你看看 我估计你是处理数据花了时间 而不是listview的显示花了时间
----------------------------------------------
-
作者:
2021/10/29 19:25:10
29楼:
listview显示行数据,就好比滤波中的箱式过滤。listview能显示的行数,就是箱子的长度。listview中的滚动条滚动时,其实滚动的是数据的offset+行数。 绘图用的invalidRect也是类似道理,只刷新需要刷新的。 写过一个C#版本的类似机制的textbox和grid。滚动多少行数据都跟飞似的。因为实际更新的就界面那几行数据。
----------------------------------------------
-
作者:
2021/10/29 20:55:45
30楼:
我专门 / 做 /了一个 / 测 / 试,在 ListView 里面放 100000 条,瞬-间完成 procedure TForm1.Button1Click(Sender: TObject); var D: Cardinal; begin D := GetTickCount; ListView1.Items.Count := 100000; ListView1.OwnerData := True; ListView1.Update; end; procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem); begin //在这里-输-入-数-据 Inc(FMyCount); Item.Caption := FMyCount.ToString; Item.SubItems.Add('MyName - ' + FMyCount.ToString); Item.SubItems.Add('描-述 - ' + FMyCount.ToString); end;
----------------------------------------------
-
作者:
2021/10/29 21:04:08
31楼:
我大概知道楼主的问题了,使用这个 ListView1.OwnerData := True; 它是不停地触发 TForm1.ListView1Data,也就是它一直在跑。假设我在这个方法里面加一个判断:if FMyCount > 100 then Exit,它就啥都不显示了,而不是只显示 100 条。 因此,估计是楼主的用法有问题。
----------------------------------------------
-
作者:
2021/10/29 21:22:58
32楼:
以前没用过 VCL 的 TListView 这/个/控/件。刚/才/再/次/测/试,知道了它的/正/确/用/法,因此也就大概能猜到它背后的工作原理。 ---------- 自己定义一个数据: TMyRecord = record MyIndex: Integer; MyName: string; MyDesc: string; end; 一个存放 N 条数据的数组: FMyData: TArray<TMyRecord>; 用一个循环产生十万条数据,测/试结果,完成时间肯定不到 1 秒。 procedure TForm1.Button2Click(Sender: TObject); var i: Integer; D: Cardinal; begin D := GetTickCount; FMyCount := 100000; SetLength(FMyData, FMyCount); for I := 0 to FMyCount -1 do begin FMyData[i].MyIndex := i; FMyData[i].MyName := 'MyName - ' + i.ToString; FMyData[i].MyDesc := '描述 - ' + i.ToString; end; D := GetTickCount - D; D := Trunc(D / 1000); Label1.Caption := D.ToString; end; 数据有了,来十万条进 ListView: procedure TForm1.Button1Click(Sender: TObject); var D: Cardinal; begin D := GetTickCount; ListView1.Items.Count := 10000; // 十万条;瞬间完成。 ListView1.OwnerData := True; ListView1.Update; D := GetTickCount - D; D := Trunc(D / 1000); Label1.Caption := D.ToString; end; procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem); begin Item.Caption := FMyData[Item.Index].MyIndex.ToString; Item.SubItems.Add(FMyData[Item.Index].MyName); Item.SubItems.Add(FMyData[Item.Index].MyDesc); end; 实际测/试结果,瞬/间出来。根据 OnData 事件方法,我大概猜到,它其实只是在画 ListView 的窗口内显示的那几条。并不是把十万条都画出来。窗口滚动到哪里,它就画哪条,是在不停地画,也就是不停地更新窗口内的数据。 我这里直接把 Item.Index 对应到数组的 Index,当然就很快。假设知道 Item.Index 但对应的数据需要一个比较耗时的搜索,那可能就慢了。但是,再慢,也不会很慢,因为它只对付窗口里面出现的那几条,而窗口不可能很大,要处理的条数并不多。
----------------------------------------------
-
作者:
2021/10/29 21:23:39
33楼:
测/试 -- 非法词汇。
----------------------------------------------
-
作者:
dalas (dalas)
★☆☆☆☆
-
普通会员
2021/10/30 0:02:10
34楼:
牛掰,百万数据也是秒加载
此帖子包含附件: 大小: 25.2K
----------------------------------------------
-
作者:
2021/10/30 8:26:51
35楼:
@dalas zip丢上来吧.
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
2021/10/30 9:39:17
36楼:
@pcplayer 牛 百万数据也是秒杀 原理解析也很清晰
----------------------------------------------
SPAM
作者:
dalas (dalas)
★☆☆☆☆
-
普通会员
2021/10/30 10:30:21
37楼:
试了下1千万数据,时间都花在生成数据的循环中了,装载1千万数据,时间也不到1秒,显示花费的时间跟1千还是1万或1千万没啥差别,只跟窗口大小有关,窗口大显示数据多,花费时间多些,但也几乎可以忽略。 另外,32位装载1千万会 out memory,64位装载1亿,也会 out memory。 附件例子,32位是1百万,64位是1千万数据。
----------------------------------------------
-
作者:
2021/11/1 10:33:09
38楼:
@dalas 你们说是数据处理的事. 我写个更简单的, 不用任何数据结构.. 一样卡得飞起.. ide是delphi 11
----------------------------------------------
delphi界写python最强, python界写delphi最强. 写自己的代码, 让别人去运行.
作者:
dalas (dalas)
★☆☆☆☆
-
普通会员
2021/11/3 15:01:42
39楼:
@tuesdays (Tuesday) 1、对于你38楼这个例子,我是很无语的,用不用数据结构,有区别吗?用数据结构是模拟实际应用场景。如果这样你还卡,那我真不知道是什么原因,反正我这破电脑,一点不卡。 2、我也只是现学现用,根据32楼pcplayer的代码,写成一个例子而已,在此之前,我也不知道还有这样用法。 3、刚刚我这个方法用到我现项目中,发现卡不卡跟数据行数关系不大,但跟列数关系很大。我项目中数据有40列,118行,上下滚动不卡,但左右拉滚动条或调整列宽,就有一点卡了。 4、我的电脑硬件配置很差,7年前老笔记本。
----------------------------------------------
-
作者:
2021/11/3 17:59:58
39楼:
ondata 完事啊
----------------------------------------------
delphi加油!!