Как сделать компонент в делфи

Добавил пользователь Алексей Ф.
Обновлено: 05.10.2024

Изучим динамический метод создания компонентов. Иногда компоненты надо создавать динамически. Например, на форме вашей программы может находится кнопка "Дополнительно. ", при нажатии на которую ваша форма должна увеличится в размерах и на ней должны появится дополнительные элементы управления. Именно такой пример мы сейчас и рассмотрим. Откройте Delphi, уменьшите форму и расположите на ней кнопку Button1 . Установите свойство Caption для кнопки в "Дополнительно. ".

Щелкните на кнопке Button1 и внесите в появившуюся заготовку следующий код.

procedure TForm1.Button1Click(Sender: TObject);

btn: TButton; //Переменная для кнопки

edt: TEdit; //Переменная для Edit'а

//Увеличиваем размер формы

//Создаем новую кнопку

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

btn.Top:=Form1.Height div 2+20;

//Создаем новый Edit

//Устанавливаем расположение нового Edit'а

edt.Top:=Form1.Height div 2+20;

Запускайте программу и нажимайте на кнопку. Форма увеличит размеры и на ней появятся два новых компонента - кнопка и Edit .

Динамическое создание компонентов, или Палитра компонентов — для ленивых!

Во всех предыдущих уроках вы создавали интерфейс пользователя вручную, размещая компоненты на форме. Но может возникнуть такая ситуация, когда при различных действиях пользователя на форме должны располагаться различные компоненты, либо на форме необходимо разместить очень много одинаковых компонентов. В этом случае будет удобно динамически создавать требуемые компоненты в режиме Runtime (в режиме работы приложения) и размещать их нужным образом.

Задачи урока

  • Динамическое создание компонент.
  • Работа с компонентом RadioGroup.

Выполнение упражнения

В этом уроке мы напишем приложение-игру (рисунок 1).

Правила игры будут следующие: на форме появляется определённое количество частиц (от 30 до 120 штук) заданных размеров и двух цветов (цвета также задаются). Эти частицы хаотически движутся внутри игрового пространства.

Цель игры: щелчком мыши убрать частицы только одного цвета (выигрышного цвета). Если мышью игрок щёлкнет на проигрышный цвет, то игра закончится.

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

Во второй части урока мы научимся работать с массивом динамически созданных компонентов и доведём до конца идею игры.

а) б)
Рисунок 1. Окно приложения

1. Дизайн приложения

  1. Поместите на форму компоненты, как показано на рисунке 2а, и установите значения их свойств согласно рисунку 2б.

а) б)
Рисунок 2

Это будет основная форма игры. На ней расположены следующие компоненты:

Компонент Shape предназначен для оформления приложения графическими примитивами и принимает разные формы: прямоугольник, прямоугольник со скруглёными углами, квадрат, эллипс, круг. Для этого у него есть одноимённое свойство Shape. Свет и стиль контура фигуры и её заливки изменяются через составные свойства Pen и Brush.

Установите свойство Visible = False у компонентов Shape и Panel3. Эти компоненты не должны быть видны при запуске приложения.

  1. Создайте вторую форму: File ? New ? Form, или кнопкой на панели инструментов.
  2. Поместите на вторую форму компоненты (рисунок 3а) и установите значения их свойств согласно рисунку 3б.

image011

а) б)
Рисунок 3

Обратите внимание на новый компонент — RadioGroup (категория Standart). Этот компонент из той же серии, что и компоненты Panel и GroupBox, т. е. контейнер. Но в него нельзя помещать компоненты непосредственно из палитры компонентов! Он предназначен для хранения списка компонентов RadioButton, которые задаются через свойство Items (представляет собой многострочный редактор). Например, для задания трёх переключателей по выбору количества частиц необходимо заполнить редактор так:

image013


Рисунок 4

Следующим, пока незнакомым нам компонентом, является ColorDialog (категория Dialog). Этот компонент предназначен для выбора цвета.

Имя, которое было

2. Начальные параметры игры

  1. Прежде всего, объявите глобальные переменные, которые будут использованы в игре (выделено жёлтым цветом):

Для чего нужна каждая переменная, понятно из комментариев.

  1. Создайте обработчик события OnCreate для главной формы и запишите в него следующие строки:

Поясним, что делает код:

  • активирует генератор случайных чисел;
  • задаёт количество частиц в игре и их размер;
  • задаёт цвета выигрышных и проигрышных частиц.
  1. Теперь пришло время динамического создания компонентов Shape — будущих частиц. Напишите обработчик события OnClick для кнопки ButtonCreate:

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

Напишите обработчик события FormClose для главной формы:

Это событие возникает в момент закрытия формы.

Здесь организован цикл поиска по имени динамически созданных компонентов, при помощи свойства FindComponent(‘sh’+IntToStr(f)), с последующим удалением их из оперативной памяти компьютера – free.

image020


Рисунок 5

Теперь вы научились динамически создавать компоненты в режиме RunTime.

3. Коротко о главном

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

Создание нового компонента происходит с помощью вызова метода Create (Конструктор). В качестве параметра конструктору необходимо передать имя формы.

Динамически созданный объект имеет нулевую ширину, высоту и координаты: [0,0].

Отображение созданного компонента происходит через вызов свойства Parent и присвоение ему имени контейнера, на котором компонент будет размещён (например, форма). Для отображения динамически созданной формы необходимо вызвать метод Show (либоShowModal).

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

Компонент RadioGroup (категория Standart) представляет собой контейнер. Но только в него нельзя помещать компоненты непосредственно из палитры компонентов. Он предназначен для хранения списка компонентов RadioButton, которые задаются через свойствоItems этого компонента.

Динамическое создание компонентов, или Как с ними работать?

Задачи урока

  • Работа с массивом динамически созданных компонентов.
  • Работа с компонентом RadioGroup.
  • Работа с компонентом ColorDialog.

Выполнение упражнения

а) б)
Рисунок 1. Окно приложения

1. События динамически созданных компонентов

1. Загрузите проект, созданный в первом разделе урока.

Напишите следующий обработчик события OnMouseDown для единственного расположенного на форме компонента ShapeStar:

Поясним написанный код:

Эта строка означает, что событие OnMouseDown динамически созданного компонента будет ссылатся на реально существующую процедуру ShapeStarMouseDown.

2. Как начать игру заново?

Введём в игру возможность пользователю выбирать цвет частиц, их размер и количество. Как раз для этого мы и разработали вторую форму — FormNew.

1. Но для начала создайте обработчик события OnClick для кнопки ButtonNew главной формы:

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

2. Перейдите на форму FormNew (рисунок 2). Создайте обработчик события OnCreate для формы FormNew и запишите в нём следующий код:

image013


Рисунок 2

3. Для того чтобы их поменять, напишите обработчики события OnClick для этих кнопок:


Рисунок 3

3. Движущиеся частицы

1. Но как бы ни была хороша игрушка, её всегда можно сделать ещё лучше! Этим мы сейчас и займёмся. Добавим к нашим частицам элемент движения. Так, чтобы они случайным образом перемещались по игровому полю, не выходя за его границы. Для этого обработаем событие таймера OnTimer следующим образом:

  • Задаём цикл поиска по имени.
  • Для упрощения работы был использован оператор with. Упомянув в нём компонент всего один раз, мы можем обращаться к любому его свойству, методу или событию.
  • В теле оператора with, случайным образом меняем расположение компонентов Shape на игровом поле. Причём положение каждой из частиц меняется на величину от -2 до 2 по каждой из координат (выделено жёлтым). Это создаёт эффект броуновского движения частиц.
  • Чтобы частицы в процессе движения не вышли за границы игрового поля, их положение необходимо постоянно контролировать. Для этого введены четыре условия для каждой из границ поля. Частица, решившая выйти за границы, будет отталкиваться от них.

image025


Рисунок 4

Да потому, что мы обращаемся к массиву объектов для изменения координат частиц, а при первом запуске приложения он ещё пуст. Как же быть? Да просто необходимо переписать строчки обработчика события OnCreate главной формы следующим образом (выделено жёлтым):

Есть ещё один способ решения этой проблемы. При запуске приложения выключить таймер (Timer.Enabled := False). Включаться он должен только в момент начала игры, а после окончания снова выключаться.

3. Всё! Запустите уже полностью готовое приложение и играйте на здоровье.

4. Коротко о главном

  • События динамически созданных компонентов лучше связывать с одним аналогичным компонентом (на этапе RunTime невидимым), помещённым на форму. А через параметр Sender определять, от какого динамически созданного компонента пришло событие.
  • Для назначения динамически созданному компоненту события необходимо записать:
    . := ;
  • Компонент ColorDialog (категория Dialog) представляет собой стандартный диалог по выбору пользователем цвета.

Задания I уровня сложности

2. Модифицируйте созданное приложение так, чтобы можно было менять количество частиц с помощью компонентов Edit и UpDown.

3. Модифицируйте созданное приложение так, чтобы частицы не отталкивались от границ игрового поля. Поле должно быть замкнуто по горизонтали и вертикали. Т. е., когда частица пропадает за какой-то стороной игровой области, то она появляется с другой его стороны.

5. Модифицируйте созданное приложение так, чтобы частицы перемещались только по горизонтали слева направо. Причём, когда частица исчезает с правой стороны игрового поля, она появляется с левой его стороны (т. е. происходит зацикливание по горизонтали).

8. Создайте приложение с компонентом RadioGroup, в котором будут перечислены следующие названия: кнопка, метка и однострочный редактор. Если пользователь щёлкнет мышью по свободной форме, то в месте щелчка динамически создаётся тот компонент, который указан в списке. Заголовок появившегося компонента должен соответствовать общепринятым. Например: Button1, Button2, Edit1 и т. д.

Примечание: Для отображения формы необходимо применить уже известный нам метод Show, вместо свойства Parent.

Задания II уровня сложности

1. Создайте игру, аналогичную той, что вы делали в упражнении. Только игровым полем будет весь экран, а частицами будут компоненты Form без строки заголовка (свойство BorderStyle = bsNone). Примерный результат приведён на рисунке:

Я разрабатываю приложение Delphi 10.1 VCL для Windows.

для ввода integer или float мне нужно поле ввода номера, которое связано с ползунком. Когда пользователь изменяет номер в поле ввода, позиция ползунка изменяется соответствующим образом. Когда пользователь изменяет положение ползунка, номер в поле Номер обновляется.

Я могу решить эту проблему с помощью TEdit и TTrackBar и добавить необходимую функциональность обновления в событие OnChange дрессировщики.

enter image description here

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

является ли создание нового компонента лучшей стратегией для многократного использования такого слайдера?

каков наилучший способ создать такой новый компонент?

является ли создание нового компонента лучшей стратегией для нескольких использование такого слайдера?

не обязательно все время. (по крайней мере, по моим меркам).

каков наилучший способ создания такого нового компонента?

Я знаю три способа решить вашу проблему.

путь номер 1:

создать компонент с помощью мастера создания компонентов, где вы создаете динамически Tedit и Ttrackbar субкомпоненты в Tgroupbox потомок.

вот как я бы это сделал.

путь номер 2:

используйте такие кадры (я на delphi 10 seattle).

1) File-->New-->Other-->(поиск кадров в файлах delphi).

2) Теперь добавьте редактирование и панель треков и установите их события Onchange.

3) сохранить блок.

4) на панели инструментов (в разделе стандартный компонент) нажмите на компонент рамки.

5) выберите рамку, которую вы только что создали.

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

путь номер 3:

используйте шаблон компонента, как это (снова я на delphi 10 seattle)

1) Выберите уже созданный и измененный tedit и ttrackbar .

2) на на панели инструментов" компонент "нажмите" Создать шаблон компонента".

3) Назовите свой шаблон и нажмите OK.

4) Выберите палитру, шаблон и шаблон.

теперь обратите внимание, что даже ваш код (события) добавляются также в ваш проект.

наконец-то

С уровнем, который у меня есть на delphi и IDE, я действительно не могу дать вам четкий ответ, который является лучшим способом, но тем не менее я поделился всем, что Я знаю, что это может тебе помочь.

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

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

1. простота изменения комбинированного управления(ов), если вы этого хотите (по моему опыту вы будете).

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

3. общая читаемость исходного кода.

4. полезности для будущего ваших проектов.

теперь начнем критиковать три метода, основанные на этих критериях.

путь номер 1:

C1(Критерий № 1): всего измените исходную реализацию компонента, и каждая реплика / использование будет иметь одинаковые эффекты и свойства. Однако это не относится к способу № 3.

C3: их нет реализации в исходном коде вашей формы(ов) для вашего компонента, просто добавьте его в свою форму, и все будет скрыто (например, добавьте tedit и перейдите, чтобы увидеть реализацию в источнике форм).

C4: вы создаете компонент после того, как все это откроет вам дверь для создания собственного набора компонентов, таких как компоненты Flatstyle или Indy с открытым исходным кодом. так что в следующий раз тебе понадобится что-то вроде этого. вы просто бросаете его в свой конструктор форм, и все готово.

путь номер 2: кадры

C1: это похоже на Способ № 1, потому что вы создаете компонент, но на этот раз визуально. изменение исходного фрейма изменит эффекты и свойства реплик, также вы можете добавить дополнительную обработку к репликам.

обработчик событий События onChange реплики выглядит следующим образом

C2: то же время и, возможно, быстрее, чем путь номер 1.

C3: более того, он имеет то же самое, что и путь номер 1.

C4: в отличие от способа № 1 Вы не можете использовать фреймы, созданные в проекте A в проекте B. Поэтому ваше кодирование и отладка останутся в проекте A.

путь номер 3: шаблон компонента.

C1: вы не создаете компонент вы создаете repleca / макрос точных шагов, которые вы сделали в вашем последнем проекте. изменение одного не изменит других, они разделены.

C2: то же время и, возможно, быстрее, чем путь номер 1.

C3: каждый раз, когда вы добавляете шаблон в форму, будет добавлен код событий (не очень хороший вид, если это длинный код Onchange).

C4: вы можете использовать шаблоны, созданные в проекте A в проекте B. Однако то, что вы написали в проекте A, будет в проекте B (см. c1) даже ссылки на переменные, которые не существуют в проекте B (это может быть трудно отладить и ввести в заблуждение, учитывая период времени между каждым использованием шаблона).

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

хорошая вещь также о способе № 1 заключается в том, что через некоторое время, когда вы забудете реализацию и как все работает внутри. Единственное, что следует иметь в виду, это цель компонента, потому что он станет одним из различных компонентов, которые вы используете (вы не знаете, как Tedit реализован, и вам не нужно, но все же вы используете его в каждом отдельном проекте создавать.)

на основе критериев, заданных способом номер 1 является лучшим.

возможно, использование контейнерного элемента управления, содержащего оба элемента управления, является более простой альтернативой. Для этого я использую ccpack.

Custom Containers Pack (CCPack) - это интегрированный инструмент и компонент mini- библиотека для создания и обслуживания составных элементов управления (или просто " композиты") и другие контейнеры (формы, модули данных и фреймы). Процесс построение составных компонентов выглядит так ActiveForm и создание кадров, но результатом является собственный компонент VCL. Вы можете создавать новые композиты просто как обычно.

вы можете создать фрейм, а затем зарегистрировать этот фрейм как компонент. Конечный результат очень похож на создание компонента только кода, где субкомпоненты создаются в конструкторе (опция Nasreddine № 1). Однако этот метод позволяет визуально проектировать компонент и в инспекторе объектов для создания обработчиков событий.

вот вопрос переполнения стека, который показывает, как зарегистрировать кадр: как улучшить использование Delphi Кадры

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

Процесс создания компонента может быть представлен как последовательность следующих этапов:

  1. Выбор базового класса.
  2. Создание модуля компонента.
  3. Тестирование компонента.
  4. Добавление компонента в пакет компонентов.

Рассмотрим процесс создания компонента программиста на примере разработки компонента NkEdit, предназначенного для ввода и редактирования дробного числа.

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

Создание модуля компонента

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

Для того чтобы создать модуль компонента, необходимо из меню Component выбрать команду New Component и в поля открывшегося диалогового окна New Component (рис. 16.1) ввести информацию о создаваемом компоненте.


Рис. 16.1. Диалоговое окно New Component

Поле Ancestor type должно содержать базовый тип для создаваемого компонента. Базовый тип компонента можно задать непосредственным вводом имени типа или выбором из раскрывающегося списка. Для разрабатываемого компонента базовым компонентом является стандартный компонент Edit (поле ввода-редактирования). Поэтому базовым типом для типа разрабатываемого компонента является тип TEdit.

В поле Class Name необходимо ввести имя класса разрабатываемого компонента, например TNkEdit. Вспомните, что в Delphi имена типов должны начинаться буквой т.

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

В поле Unit, file name находится автоматически сформированное имя файла модуля создаваемого компонента. Delphi присваивает модулю компонента имя, которое совпадает с именем типа компонента, но без буквы T. Щелкнув на кнопке с тремя точками, можно выбрать каталог, в котором должен быть сохранен модуль компонента.

Любой программист рано или поздно сталкивается с задачей динамического создания объектов. В этой статье я расскажу о том, как создать визуальный компонент во время выполнения программы. Упомяну о том, как настроить его свойства. И в конце концов мы уничтожим созданный объект. Разбираться мы будем на примере простой кнопки (TButton).

Для того, чтобы при создании компонента не получить ошибку нам первым делом нужно подключить модуль, в котором описан интересующий нас класс. Для кнопки это модуль StdCtrls. Пропишем его в разделе uses. Если Вы не знаете в каком модуле описан компонент - не страшно. Есть простое решение. Нужно перенести интересующий объект на форму и тут же удалить его, в разделе uses автоматически пропишется необходимый модуль.

Следующее, что от нас требуется - объявить переменную соответствующего типа, в нашем случае это button:TButton. Я объявил переменную в разделе implementation. Это можно было бы сделать и внутри функции, но тогда мы не имели бы доступ к переменной из других мест, а нам это необходимо для уничтожения. Также можно было определить как переменную класса формы (TForm1).

Можно приступать непосредственно к созданию кнопки. Создаваться она будет по клику на другую кнопку.

1. Создаем объект, в скобочках указан владелец объекта. В данном случае это Form1 - это значит, что при уничтожении этой формы объект также уничтожается. Владелец должен был класса TComponent.

2. Указываем родителя, родитель должен быть класса TWinControl, потому что в границах этого компонента будет отрисованна наша кнопка.

3. Задаем положение кнопки относительно левого края.

4. Задаем положение кнопки относительно верхнего края.

5. Редактируем надпись

6. Устанавливаем высоту

7. Присваиваем процедуру Clicks событию OnClick

Процедуру Clicks я определил в разделе public класса TForm1 - procedure Clicks (Sender: TObject); Самое главное, чтобы параметры процедуры совпадали с параметрами процедуры OnClick компонента класса Tbutton.

Компонент создан и готов к использованию, давайте теперь посмотрим как его уничтожить. Уничтожать его я буду по событию двойного клики по форме проекта (OnDblClick). Всё, что нужно сделать - вызвать процедуру FreeAndNil и в качастве параметра указать наш компонент FreeAndNil(Button);

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

Читайте также: