Создание и медленное представление большого количества среды выполнения TLabel

В моем приложении я работаю со средой выполнения TLabel объектов.

Есть проблема: представление 20 меток занимает много времени (около 1-2 секунд).

DoubleBuffered для родительского компонента не помогает. Application.ProcessMessages позволяет только наблюдать за процессом создания, а не смотреть в замороженное окно.

// 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 циклов до и после не влияет.

PS: Создание объектов не занимает много времени. Узким местом является родительское назначение.

upd: большое количество означает около 500 штук..


person yujin1st    schedule 02.05.2012    source источник
comment
Не могу подтвердить проблему; протестировано и 1000 меток были созданы в скроллбоксе в одно мгновение.   -  person kludg    schedule 02.05.2012
comment
Я также тестировал с 2000... менее одной секунды... но... если я активирую пользовательский стиль, затраченное время увеличивается...   -  person Whiler    schedule 02.05.2012
comment
У вас есть условная точка останова и компиляция для 64 бит? Я заметил, что этого следует избегать, если это возможно.   -  person Sertac Akyuz    schedule 02.05.2012
comment
У меня нет условной точки останова, и я компилирую для 32. Я не менял никаких настроек проекта, кроме значка.   -  person yujin1st    schedule 02.05.2012


Ответы (2)


Используйте 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;

введите здесь описание изображения

person NGLN    schedule 02.05.2012
comment
Причина в том, что при включенном выравнивании новая метка вызывает реальный метод для любых ранее созданных, не так ли? - person yujin1st; 02.05.2012
comment
@ yujin1st Да, просто сказал, что это правда. Но не существует такой вещи, как метод Reallign, а скорее полная среда Reallign. - person NGLN; 02.05.2012

Если вы просто создаете 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;

Со стилемЕсли я деактивирую стиль

person Whiler    schedule 02.05.2012
comment
Да, я использую собственный стиль для меток. А Enable/Disable Align быстро решает проблему. Ваш вариант тоже решает проблему, но требует чуть больше времени на применение - person yujin1st; 02.05.2012