Страница 2 из 2

Re: Динамическое создание большого кол-ва контролов

Добавлено: 09.10.2014 19:33:55
qivi
Вот список. Несколько предупреждений:
1. Компонент написан для личнх целей поэтому кондовый и имеет ряд условностей
2. Это точно работает при компиляции юникодовой версией FPC для Linux GTK, в других средах могут быть незначительные нюансы по отображению и проблемы с кодировкой.
3 Я принудительно определяю кодовую страицу {$codepage UTF8} и использую строки типа UnicodeString со всеми вытекающими (мне уже рассказывали какое это страшное зло но пока не устаканится ситуация со строками в FPC+Lazarus меня устраивает только этот вариант).
По этой части вроде всё.

Ещё, в первой версии списка количество отображаемых строк определялось динамически при ресайзе, но тогда высота строки была фиксированной, когда мне потребовалось автоопределение высоты полезли глюки и я убрал код динамического расчёта количества строк, теперь количество строк фиксированно и задаётся через проперти... если не устраивает се ля ви...

Re: Динамическое создание большого кол-ва контролов

Добавлено: 09.10.2014 23:34:33
zub
>>А вот такой проект попробуйте:
Когда в руках молоток - всё кажется гвоздями. Это не тест, а не пойми что.
Простое правило - обрабатывай (в данном случае - создавай) только то что используется (в данном случае - видимо) и всё будет летать.

Re: Динамическое создание большого кол-ва контролов

Добавлено: 10.10.2014 02:04:42
Sharfik
Роняю молоток себе на ногу....

Тест: выполнение создания 800 панелей.
Алгоритм автора:
Время генерации 6225,00000000001 мс
Добавление в исходный код функции с SendMessage(c.Handle, WM_SETREDRAW, 0, 0)
Время генерации 5389,00000000053 мс
Добавление в исходный код ScrollBox1.Visible:=false/true
Время генерации 327,999999999751 мс

Вся фигня в том, что ScrollBox1 съедает 800 штук, но 1000 уже сам по себе не переваривает и виснит, даже при 327мс генерации. Точнее 820 он тянет, но не 821.
Почему так и в чем крутость ScrollBox1.Visible=false предлагаю разобраться автору тему и рассказать нам позже :roll:

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
var
  i,w : integer;
  BufPanel : TPanel;
  t1, t2 : TTime;
  kList:TList;
begin
  t1 := Time;
  w:=ScrollBox1.Width;
  ScrollBox1.Visible:=false;
  for i := 0 to CtrlsNumSpinEdit.Value - 1 do
  begin
    BufPanel := TPanel.Create(Self);
    BufPanel.SetBounds(0, i*40 + 1, w, 40);
    BufPanel.Align := alTop;
    BufPanel.Caption := 'Панель #' + IntToStr(i+1);
    ScrollBox1.InsertControl(BufPanel);
  end;
  ScrollBox1.Visible:=true;
  t2 := Time;
  Memo1.Lines.Add('Время генерации ' + FloatToStr((t2 - t1)*3600*24*1000) + ' мс');
end;

Re: Динамическое создание большого кол-ва контролов

Добавлено: 10.10.2014 06:19:40
sign
Граница - 820 элементов.
До этого - стреляет молниеносно, после - зависает.
Наверное, дело в некоторых внутренних ограничениях.
Вам 820 разом элементов хватит?

Код: Выделить всё

var BF: Array of Pointer;
    Cnt: Integer = 820;

procedure TForm1.Button3Click(Sender: TObject);
var i, aWidth: Integer;
    P: TPanel;
    t1, t2, t3, t4: TTime;
begin
  t1 := Time;
  SetLength(BF, Cnt);
  aWidth := ScrollBox1.Width;
  for i := 0 to Cnt-1 do begin
    P := TPanel.Create(Self);
    P.Visible := False;
    P.SetBounds(0, 0, aWidth, 40);
    P.Align := alTop;
    P.Caption := 'Панель #' + IntToStr(i + 1);
    ScrollBox2.InsertControl(P);
    BF[i] := P;
  end;
  ScrollBox2.Visible := False;
  for i := 0 to Cnt-1 do begin
    TPanel(BF[i]).Visible := True;
  end;
  ScrollBox2.Visible := True;
  t2 := Time;
  ShowMessage(Format('Запуск: %s.  Окончание: %s', [TimeToStr(t1), TimeToStr(t2)]));
end;
1.jpg


И разумеется!!!
Размещать при Visible = True сотни элементов - стрелять себе в ногу. Зачем?
Разместили в невидимом элементе всё что нужно, включили этот элемент на показ.

Re: Динамическое создание большого кол-ва контролов

Добавлено: 10.10.2014 11:02:30
ya_vanka
Да, про Visible я стормозил, и в случае с генерацией только панелей это выход.

Но в реальном проекте (где на панели еще 30 контролов) это, увы, не особо помогает. При том, что у ScrollBox.Visible := false и у панели на которой создаются контролы тоже Visible := false и панелей 100 штук отображение занимает секунд 10.

В целом думаю сменить концепцию на использование списка с OwnerDraw и использование контролов только для текущего редактируемого элемента.

Re: Динамическое создание большого кол-ва контролов

Добавлено: 10.10.2014 12:15:29
pupsik
qivi весьма нормальная реализация. Решил проверить: 50 к боксиков - легко рисуются. Единственная задержка - если боксы не сильно загружены строками (при 1к + начинаются глюки с движением по списку).

ya_vanka никто не знает что вы хотите реализовать. Хотя, уже более менее понятно (со второй стр....) Но то что вы начали пересматривать ваш вариант - гуд. Только вот "держать" можно около 10 -+ панелей (видимых), а остальное, показывать по мере возможности и необходимости. Своеобразный dbCtrlGrid delphi.
Но это варианты, а по сути вам писать (решать).

Re: Динамическое создание большого кол-ва контролов

Добавлено: 10.10.2014 13:20:29
MiniQ
Может обратите внимание на VirtualTreeView? там примеры и на 100 тыс. записей и все летает