Найти в Дзене
Makadoo

Delphi создание динамических компонентов и работа с ними.

В этой статье мы рассмотрим как правильно создавать динамические компоненты в среде программирования делфи, а так же рассмотрим работу с ними. Первое с чего мы начнем это создание динамического компонента запускаем Delphi (в моем случае это RAD Studio 10 Seattle) идем в пункт меню FIle > New > VCL Forms Application - Delphi. В инспекторе объектов выбираем нашу форму Form1 переходим на вкладку Events и дважды щелкаем ЛКМ по полю возле OnCreate тем самым мы создадим слушатель событий при созданий формы. В Uses подключаем модуль Vcl.StdCtrls в нем описана кнопка. Создаем глобальную переменную BTN в разделе Var с типом TButton. Слушателе событий OnCreate формы в логических блоках begin end пишем: // Создаём компонент BTN := TButton.Create(Form1); // Указываем родителя (в данном случае эту форму) BTN.Parent := Form1; // Задаём расположение кнопки BTN.Top := 30; // с верху 30 BTN.Left := 30; // слева 30 // Устанавливаем надпись на кнопку BTN.Caption := 'Кнопка'; // Даем имя кнопке BTN.Name
Оглавление

В этой статье мы рассмотрим как правильно создавать динамические компоненты в среде программирования делфи, а так же рассмотрим работу с ними.

Первое с чего мы начнем это создание динамического компонента запускаем Delphi (в моем случае это RAD Studio 10 Seattle) идем в пункт меню FIle > New > VCL Forms Application - Delphi.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

В инспекторе объектов выбираем нашу форму Form1 переходим на вкладку Events и дважды щелкаем ЛКМ по полю возле OnCreate тем самым мы создадим слушатель событий при созданий формы.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

В Uses подключаем модуль Vcl.StdCtrls в нем описана кнопка. Создаем глобальную переменную BTN в разделе Var с типом TButton.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Слушателе событий OnCreate формы в логических блоках begin end пишем:

// Создаём компонент

BTN := TButton.Create(Form1);

// Указываем родителя (в данном случае эту форму)

BTN.Parent := Form1;

// Задаём расположение кнопки

BTN.Top := 30; // с верху 30

BTN.Left := 30; // слева 30

// Устанавливаем надпись на кнопку

BTN.Caption := 'Кнопка';

// Даем имя кнопке

BTN.Name:='BTN';

// Устанавливаем размер кнопки

BTN.Width:=100; // ширина 100

BTN.Height:=30; // высота 30

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Свойство Parent устанавливает родителя вашего компонента на нем он будет создан (при удалении родителя в нашем случае это Form1 ваш компонент будет удален). Свойство Name устанавливается обязательно (индивидуальное) иначе при повторном создании компонента ваше приложение выдаст ошибку компонент с таким именем уже существует.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Теперь запускаем нашу программу например нажатием клавиши F9 и смотрим, что у нас получилось.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

А как же быть если нужно создать несколько одинаковых компонентов спросите вы? Можно конечно создавать эти компоненты прописывая одно и то же, но лучше зациклить это действие (ибо так уменьшится и оптимизируется код).

Создание динамических компонентов в цикле.

Добавим к нашему коду переменную BTN_NAME_INDEX которая будет отвечать за индивидуальное имя кнопок и так же добавим переменную btn_i, и btn_j они будут счетчиком для циклов, и добавим переменную rasstoyanie в ней будет храниться расстояние между кнопками. Все эти переменные типа integer.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Немного изменим наш код:

rasstoyanie:=5; // Устанавливаем расстояние между кнопками

BTN_NAME_INDEX:=1; // Устанавливаем значение для первой кнопки

for btn_i := 1 to 8 do // повторяем цикл 8 раз

begin

// Создаём компонент

BTN := TButton.Create(Form1);

// Указываем родителя (в данном случае эту форму)

BTN.Parent := Form1;

// Задаём расположение кнопки

BTN.Top := 30*btn_i+rasstoyanie-30; // с верху 30

BTN.Left := 30; // слева 30

// Устанавливаем надпись на кнопку

BTN.Caption := 'Кнопка';

// Даем имя кнопке

BTN.Name:='BTN'+IntToStr(BTN_NAME_INDEX);;

// Устанавливаем размер кнопки

BTN.Width:=100; // ширина 100

BTN.Height:=30; // высота 30

inc(BTN_NAME_INDEX); // прибавляем к переменной BTN_NAME_INDEX единицу

end;

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Запускаем программу и смотрим что получилось

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

А что же делать если нам нужно расположить компоненты таблицей скажем так как выглядит игра пятнашки. Для этого нам нужно создать вложенный цикл для этого нам и понадобится переменная btn_j она будет считать количество кнопок по горизонтали, а btn_i считает количество кнопок по вертикали. Изменим еще немного наш код:

rasstoyanie:=5; // Устанавливаем расстояние между кнопками

BTN_NAME_INDEX:=1; // Устанавливаем значение для первой кнопки

for btn_i := 1 to 8 do // повторяем цикл 8 раз

begin

for btn_j:=1 to 3 do // повторим цикл горизонтали 3 раза

begin

// Создаём компонент

BTN := TButton.Create(Form1);

// Указываем родителя (в данном случае эту форму)

BTN.Parent := Form1;

// Задаём расположение кнопки

BTN.Top := 30*btn_i+rasstoyanie-30; // с верху 30

BTN.Left := 100*btn_j+rasstoyanie-100; // слева 100

// Устанавливаем надпись на кнопку

BTN.Caption := 'Кнопка';

// Даем имя кнопке

BTN.Name:='BTN'+IntToStr(BTN_NAME_INDEX);;

// Устанавливаем размер кнопки

BTN.Width:=100; // ширина 100

BTN.Height:=30; // высота 30

inc(BTN_NAME_INDEX); // прибавляем к переменной BTN_NAME_INDEX единицу

end;

end;

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Запускаем нашу программу и смотрим что у нас получилось.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Кнопки появились. Все бы хорошо но вот не задача при нажатии на кнопки ничего не происходит, что же делать? Нужно создать слушатель событий.

Обработчик (слушатель) событий для динамических компонентов.

Для начала нужно создать обработчик событий в разделе private назовем его BTNClick с параметром Sender . Sender имеет тип TObject, и имеет значение объекта - источника событий, в обработчике которого он используется.

procedure BTNClick(Sender: TObject); //1 клик

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Теперь напишем содержимое нашего обработчика то есть опишем инструкции которые он будет выполнять. например после

implementation

{$R *.dfm}

Пишем следующий код:

procedure TForm1.BTNClick(Sender: TObject);

begin

if (Sender is TButton) then // Если объект кнопка то

begin

ShowMessage('Кнопка нажата'); // Выводим сообщение на экран

end;

end;

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Теперь нам осталось только добавить наш слушатель событий к создаваемому компоненту в нашем случае это кнопки. Для этого немного изменим наш код дописав в него.

BTN.OnClick := BTNClick; // подключаем обработчик

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Запускаем программу и жмем на любую кнопку смотрим что получилось.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Все работает как нам нужно. Теперь нам надо как то обратиться к динамическим компонентам например узнать его имя. Это нужно для того что бы в дальнейшем можно было получить значение какого либо свойства компонента либо изменить какое то значение.

Получение значений свойств динамического компонента.

Для того что бы получить какое-либо значение свойства компонента нужно воспользоваться (Sender as TComponent).свойство компонента в моем случае это name. Изменим немного код нашего обработчика.

if (Sender is TButton) then // Если объект кнопка то

begin

ShowMessage('Кнопка '+ (Sender as TComponent).Name+' нажата'); // Выводим сообщение на экран

end;

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Запускаем программу смотрим, что получилось.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

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

Поиск динамических компонентов.

Для поиска и работы с компонентами есть функция FindComponent в модуле Classes Немного изменим наш обработчик.

if (Sender is TButton) then // Если объект кнопка то

begin

//ShowMessage('Кнопка '+ (Sender as TComponent).Name+' нажата'); // Выводим сообщение на экран

if FindComponent('BTN11')<>nil then // если компонент BTN11 найден то

ShowMessage('Кнопка BTN11 найдена');

end;

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Запускаем нажимаем на любую кнопку и смотрим что получилось.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Теперь заменим надпись на кнопке.

Изменение свойств динамического компонента.

Снова меняем наш обработчик событий добавим в него (FindComponent('BTN11') as TButton).Caption:='Кнопка 11';.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Запускаем жмем любую кнопку и смотрим что получилось.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

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

Удаление динамических компонентов.

Обычно динамические компоненты очищаются при закрытии основной формы но мы сделаем это при клике по форме. В инспекторе объекта выбираем форму переходим на вкладку Events и двойным щелчком возле OnClick создаем слушатель событий при нажатии на форму.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Пишем код

var

i:integer;

begin

for i:= 13 to Form1.ComponentCount-1 do

begin

Form1.Components[0].Free;

end;

Здесь мы удаляем с первого по тринадцатый компонент на форме в цикле.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Запускаем жмем на форму смотрим что получилось.

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Дополнение.

Создание компонентов

procedure TForm1.Button1Click(Sender: TObject);

var

memo:Tmemo;

begin

memo := Tmemo.Create(form1);

with memo do

begin

parent:=form1;

text:='1232';

width:=150;

height:=300;

top:=300;

left:=30;

name:='memo';

end;

end;

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен

Уничтожение компонента

Component.Free;

либо

FreeAndNil(Component);

Makadoo Яндекс Дзен
Makadoo Яндекс Дзен