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

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

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

Сообщение ya_vanka » 08.10.2014 18:49:55

В приложении есть диалог. В нем динамически создается много контролов.

Фактически "список" свойств некоего объекта. На 1 объект генерится около 30 контролов. Объектов может быть до 100.
Список обновляется (и соот. контролы пересоздаются) при показе окна диалога.

При этом прога скомпилированная в Lazarus генерит контролы на порядок (а то и больше) медленнее, чем та же прога скомпилированная в Delphi. Задержка появления окна - несколько секунд.

Почему так?
Можно ли ускорить создание контролов (это TPanel, TLabel, TEdit, TMaskEdit, TComboBox, TCheckBox, TButton, TSpeedButton)?

Когда элементов в списке больше 30, то даже Delphi вариант подтормаживает.
ya_vanka
новенький
 
Сообщения: 89
Зарегистрирован: 07.08.2013 14:28:41

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

Сообщение pupsik » 08.10.2014 19:14:30

а если использовать чет более проще. К примеру: пересмотреть вариант отображения. К примеру, виртул тревью прикрутить, или в гриде?
А то чет оно, даже читая, страшненькое получается.
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

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

Сообщение zub » 08.10.2014 20:04:28

Зачем всё генерить? пользователи пока не многоядерные, и одновременно работать могут только с 1 контролом ввода))
Предлагаю элементы ввода просто рисовать, генерить их при необходимости - по клику, по наведению мышки и т.п, после необходимости (по ентеру, потере фокуса, уходу мышки) уничтожать и снова просто рисовать.
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

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

Сообщение ya_vanka » 08.10.2014 20:24:34

1. Даже если отбросить текущий вариант все равно хотелось бы понять почему Lazarus настолько медленнее.
2. Разве в гриде будет быстрее?
3. А есть простой способ отрисовки контрола один в один с системным видом?
ya_vanka
новенький
 
Сообщения: 89
Зарегистрирован: 07.08.2013 14:28:41

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

Сообщение alexs » 08.10.2014 21:29:59

ya_vanka писал(а):Фактически "список" свойств некоего объекта.

Если это реальный объёект FPC - то можно RTTI грид использовать. Всё будет просто.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

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

Сообщение Sharfik » 08.10.2014 21:35:48

ya_vanka писал(а):Когда элементов в списке больше 30, то даже Delphi вариант подтормаживает.

Надо отключать отрисовку окна или владельца контролов в момент их создания. Поскольку при добавлении каждого идет отдельно из-за него перерисовка и тормоза. Как - хз, я не смог и не выдержал, был у меня редактор свойств с динамическим созданием контролов, переписал его на рисование канвы и создание контролов только единично для редактирования.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 766
Зарегистрирован: 20.07.2013 01:04:30

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

Сообщение ya_vanka » 08.10.2014 21:43:23

Если это реальный объёект FPC - то можно RTTI грид использовать


Нет, не объект FPC.


переписал его на рисование канвы


А как контролы рисовали?
Чтоб похоже на реальные контролы было?
ya_vanka
новенький
 
Сообщения: 89
Зарегистрирован: 07.08.2013 14:28:41

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

Сообщение Sharfik » 08.10.2014 21:51:00

ya_vanka писал(а):А как контролы рисовали?
Чтоб похоже на реальные контролы было?

Я имел ввиду, что я рисую не контролы, а просто отрисовываю на канве сетку, надписи и кнопки. Потом обрабатываю положение и клики мышки с клавой, и если надо добавляю уже привычный тебе контрол по координатам. Долго и нудно такое делать. Попробуй сначала поискать как через winapi блокировать отрисовку. Типа методов beginupdate/endupdate. Может поможет.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 766
Зарегистрирован: 20.07.2013 01:04:30

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

Сообщение zub » 08.10.2014 22:46:00

>>3. А есть простой способ отрисовки контрола один в один с системным видом?
Да - модуль Themes. В gtk и qt могут быть небольшие отличия от системных контролов, емнип стрелка на комбобоксе рисуется несовсем так (или ее нет и приходится рисовать стрелку с скроллбара, непомню), наверно это зависит от используемой темы оформления. Но думаю мелочевку можно поправить багрепортами.
Как вариант - не рисовать контролы, рисовать значения - получится чтото вроде инспектора объектов
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

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

Сообщение sign » 09.10.2014 06:27:35

ya_vanka писал(а):В приложении есть диалог. В нем динамически создается много контролов.

Фактически "список" свойств некоего объекта. На 1 объект генерится около 30 контролов. Объектов может быть до 100.
Список обновляется (и соот. контролы пересоздаются) при показе окна диалога.

При этом прога скомпилированная в Lazarus генерит контролы на порядок (а то и больше) медленнее, чем та же прога скомпилированная в Delphi. Задержка появления окна - несколько секунд.

Почему так?
Можно ли ускорить создание контролов (это TPanel, TLabel, TEdit, TMaskEdit, TComboBox, TCheckBox, TButton, TSpeedButton)?

Когда элементов в списке больше 30, то даже Delphi вариант подтормаживает.

Создать массив с контролами заранее и выставлять их оттуда, по мере надобности.
Т.е. вместо создания каждый раз нужного контрола, просто переписываем ему свойства и показываем, где нужно.

Создание 10 тыс. панелей.
Win XP SP3
AMD Fx(tm)-4100 Quad-Core
3.61 ГГц. 3.25 ГБ ОЗУ
1.jpg


Добавлено спустя 8 минут 12 секунд:
Размещение одной тысячи панелей:

1.jpg
sign
энтузиаст
 
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

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

Сообщение pupsik » 09.10.2014 11:10:33

:D

и показываем, где нужно
вот вопрошающий и говорит что при показе где нужно лагает.

п.с.
Создание в памяти - это не отображение. Или я ошибаюсь?

кстати: х.з. как пытаются отобразить (нет примерного кода), или что хотят сделать.
Из вопроса я, к примеру, понял: необходимо вывести диалог на котором динамически размещены контролы (судя по вопросу - до 3к). А теперь итнересный момент: за сколько времени отрисует лазарь такое кол-во компонентов. Учитывая что потом надо форму перемещать или ресайзить.
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

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

Сообщение ya_vanka » 09.10.2014 17:21:47

sign писал(а):Создать массив с контролами заранее и выставлять их оттуда, по мере надобности.

Да, так можно, но проблема в том, что кол-во элементов списка меняется в процессе работы. Генерить сразу все (макс. кол-во) вроде как лишняя работа в большинстве случаев...

sign писал(а):Размещение одной тысячи панелей:


А вот такой проект попробуйте:

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

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, Spin;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    ScrollBox1: TScrollBox;
    CtrlsNumSpinEdit: TSpinEdit;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  i : integer;
  BufPanel : TPanel;
  t1, t2 : TTime;
begin
  t1 := Time;

  for i := 0 to CtrlsNumSpinEdit.Value - 1 do
  begin
    BufPanel := TPanel.Create(Self);
    BufPanel.SetBounds(0, i*40 + 1, ScrollBox1.Width, 40);
    BufPanel.Align := alTop;
    BufPanel.Caption := 'Панель #' + IntToStr(i + 1);
    BufPanel.Parent := ScrollBox1;
  end;

  t2 := Time;

  Caption := 'Время генерации ' + FloatToStr((t2 - t1)*3600*24*1000) + ' мс';
end;

end.


800 панелей генерит 3 секунды, а на 1000 уже просто подвисает. Я так и не дождался.

Win7 Pro
Intel Core i5-4570 3.2 ГГц
8 Гб ОЗУ
ya_vanka
новенький
 
Сообщения: 89
Зарегистрирован: 07.08.2013 14:28:41

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

Сообщение qivi » 09.10.2014 17:55:34

Практиковал подобное велосипедостроение - создание списка методом динамического создания контролов в скролбоксе, порождает порядочные тормоза, прищёл к тому что создал динамичную структуру данных отделив её от контролов, а контролов вывожу заданное количество + скролбар. Наверное и это ещё то извращение, ну уж как умею.

И ещё, зачем столько панелей? В Лазарусе есть привязки.

Кстати, свой список я создал как самостоятельный компонент, если хочеш могу его вечерком выложить.
Последний раз редактировалось qivi 09.10.2014 19:41:09, всего редактировалось 1 раз.
Аватара пользователя
qivi
энтузиаст
 
Сообщения: 703
Зарегистрирован: 19.01.2009 13:45:54
Откуда: Россия

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

Сообщение Sharfik » 09.10.2014 17:57:47

Нет среды проверить, попробуй так.
Код: Выделить всё
begin
  t1 := Time;
  ScrollBox1.BeginUpdateBounds;
  for i := 0 to CtrlsNumSpinEdit.Value - 1 do
  begin
    BufPanel := TPanel.Create(Self);
    BufPanel.SetBounds(0, i*40 + 1, ScrollBox1.Width, 40);
    BufPanel.Align := alTop;
    BufPanel.Caption := 'Панель #' + IntToStr(i + 1);
    BufPanel.Parent := ScrollBox1;
  end;
  ScrollBox1.EndUpdateBounds;
  t2 := Time;
  Caption := 'Время генерации ' + FloatToStr((t2 - t1)*3600*24*1000) + ' мс';
end;
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 766
Зарегистрирован: 20.07.2013 01:04:30

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

Сообщение ya_vanka » 09.10.2014 18:09:09

qivi писал(а): могу его вечерком выложить

Давай, интересно посмотреть.


Sharfik писал(а):Нет среды проверить, попробуй так.

Ничего не изменилось.
ya_vanka
новенький
 
Сообщения: 89
Зарегистрирован: 07.08.2013 14:28:41

След.

Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10

Рейтинг@Mail.ru