在我的应用程序中,我使用TLabel
对象运行时。
有一个问题:代表20个标签需要花费很多时间(大约1-2秒)。
父组件上的DoubleBuffered没有帮助。 Application.ProcessMessages
只允许观看创建过程,而不是查看frosen窗口。
// creating a labels in loop
aLabel:=TLabel.Create(scrlbx);
labels.Add(aLabel); // TList for managing.
with aLabel do begin
Left:=pointLeft;
Top:=pointTop;
Caption:='title';
parent:=scrlbx; //TScrollBox
end;
pointTop:=pointTop+20;
将父节点循环到另一个循环之后会产生一些影响,但确实无法解决问题。
for I := 0 to labels.Count-1 do begin
TLabel(labels[i]).Parent:= scrlbx;
end;
禁用并启用TScrollBox.Visible
之前和aftel循环无效。
PS: 对象的创建不需要花费时间。 瓶颈是父母分配。
upd:大量意味着大约500件..
答案 0 :(得分:3)
使用ScrollBox.DisableAlign
和.EnabledAlign
。
procedure TForm1.CreateLabels2;
var
I: Integer;
ALabel: TLabel;
ATop: Integer;
begin
ATop := 0;
ScrollBox2.DisableAlign;
for I := 0 to 2000 do
begin
ALabel := TLabel.Create(ScrollBox2);
FLabels.Add(ALabel);
with ALabel do
begin
Caption := 'Title';
SetBounds(0, ATop, Width, Height);
Parent := ScrollBox2;
end;
Inc(ATop, 20);
end;
ScrollBox2.EnableAlign;
end;
答案 1 :(得分:0)
如果您只是创建了20 TLabel
,则添加Application.Processmessages
不是一个好主意,因为它会重新绘制它以立即显示新添加的组件...
使用常规应用程序,生成2000 TLabel
只需不到1秒......
如果我设置自定义样式,则需要更长时间......也许,这是您的问题......
所以,为了快速生成,我这样做了:
uses ..., System.StrUtils, System.Diagnostics, Vcl.Themes, Vcl.Styles;
procedure TForm3.GenerateLabels(bNoStyle: Boolean);
var
iLoop, iMax: Integer;
aLabel : TLabel;
pointLeft : Integer;
pointTop : Integer;
timeSpent : TStopwatch;
begin
iMax := 2000;
pointLeft := 3;
pointTop := 3;
timeSpent := TStopwatch.StartNew; // how long does it take
if bNoStyle then
TStyleManager.TrySetStyle('Windows'); // = no style
for iLoop := 1 to iMax do
begin
Application.ProcessMessages;
// creating a labels in loop
aLabel:=TLabel.Create(Self);
labels.Add(aLabel); // TList for managing.
with aLabel do
begin
Left := pointLeft;
Top := pointTop;
Caption := 'title';
parent := scrlbx1; //TScrollBox
end;
pointTop := pointTop + 20;
end;
if bNoStyle then
TStyleManager.TrySetStyle('Carbon'); // previous style
labels[0].Caption := IfThen(bNoStyle, 'No style', 'Style');
labels[1].Caption := IntToStr(timeSpent.ElapsedMilliseconds) + 'ms'; // display the spent time
labels[2].Caption := IntToStr(labels.Count);
timeSpent.Stop;
end;