Как создать компонент во время выполнения, а затем работать с ним (изменение свойств и т. Д.)?Создание компонентов во время выполнения - Delphi
ответ
Это зависит от того, является ли это визуальным или не визуальным компонентом. Принцип тот же, но есть некоторые дополнительные соображения для каждого вида компонента.
Для невизуальных компонентов
var
C: TMyComponent;
begin
C := TMyComponent.Create(nil);
try
C.MyProperty := MyValue;
//...
finally
C.Free;
end;
end;
Для визуальных компонентов:
В сущности визуальные компоненты созданы в том же образом, как и не-визуальных компонентов. Но вы должны установить некоторые дополнительные свойства, чтобы сделать их видимыми.
var
C: TMyVisualComponent;
begin
C := TMyVisualComponent.Create(Self);
C.Left := 100;
C.Top := 100;
C.Width := 400;
C.Height := 300;
C.Visible := True;
C.Parent := Self; //Any container: form, panel, ...
C.MyProperty := MyValue,
//...
end;
Несколько объяснений кода выше:
- путем установки владельца компонента (параметр конструктора) компонент разрушается, когда форма владеющее разрушается.
- Установка свойства
Parent
делает компонент видимым. Если вы забудете, ваш компонент не будет отображаться. (Это легко пропустить что один :))
Если вы хотите много компонентов вы можете сделать то же самое, что и выше, но в цикле:
var
B: TButton;
i: Integer;
begin
for i := 0 to 9 do
begin
B := TButton.Create(Self);
B.Caption := Format('Button %d', [i]);
B.Parent := Self;
B.Height := 23;
B.Width := 100;
B.Left := 10;
B.Top := 10 + i * 25;
end;
end;
Это добавит 10 кнопок слева границы формы. Если вы хотите изменить кнопки позже, вы можете сохранить их в списке. (TComponentList IST лучше всего подходит, но и взглянуть на предложения, от комментариев к этому ответу)
Как назначить обработчики событий:
Вы должны создать метод обработчика событий и назначить его на свойство события.
procedure TForm1.MyButtonClick(Sender: TObject);
var
Button: TButton;
begin
Button := Sender as TButton;
ShowMessage(Button.Caption + ' clicked');
end;
B := TButton.Create;
//...
B.OnClick := MyButtonClick;
Очень легко. Вызовите Создать. Пример:
procedure test
var
b : TButton;
begin
b:=TButton.Create(nil);
b.visible:=false;
end;
Это создает компонент (TButton является компонентом) во время выполнения и отображает свойство.
Для конструктора: передайте nil, если вы хотите самостоятельно управлять памятью. Передайте указатель другому компоненту, если вы хотите его уничтожить, когда другой компонент будет уничтожен.
Необходимо передать указатель владельцу элемента. TButton.Create (владелец); –
Этот код не компилируется –
> необходимо владельцу Не обязательно. TButton.Create (ноль); действительный код. но теперь вам нужно явно уничтожить его. Создание визуальных компонентов с владельцем nil иногда полезно. – Despatcher
Чтобы упростить процесс создания компонента времени выполнения, вы можете использовать GExperts.
- Визуально создайте компонент (или несколько компонентов) и задайте его свойства.
- Выберите один или несколько компонентов и выполните команду GExperts, Components to Code.
- Вставьте сгенерированный код в ваше приложение.
- Удалить компонент (ы) из конструктора визуальной формы.
Пример (TButton-создание кода, генерируемого таким образом):
var
btnTest: TButton;
btnTest := TButton.Create(Self);
with btnTest do
begin
Name := 'btnTest';
Parent := Self;
Left := 272;
Top := 120;
Width := 161;
Height := 41;
Caption := 'Component creation test';
Default := True;
ParentFont := False;
TabOrder := 0;
end;
Отличный совет! Это именно то, что я бы предложил. GExperts - отличный инструмент для работы с Delphi. –
... или вы можете создать его в визуальном редакторе, а затем взять пик в файл .dfm. В основном то же самое есть в тексте – Earlz
Gracias. Я предпочитаю писать все сам по себе (я знаю, что это, может быть, изобретать колесо, но я чувствую больше контроля над ним), так или иначе, похоже, что инструмент GExpert не изменяется в чистом коде, и это звучит хорошо. Еще раз спасибо за консультацию. – QMaster
Но если я не знаю, конечно, сколько компонентов я хочу создать, например, если это зависит от решения пользователя. Итак, как я могу объявить компоненты динамически?
Ответ был предложен - самым простым способом является Список объектов (компонентов). TObjectList является самым простым в использовании (в условных обозначениях). Списки великолепны!
In Form1 Public
MyList: TObjectList;
procedure AnyButtonClick(Sender: TObject);
// Вы можете получить более изощренными и объявить // TNotifyevents и назначить их, но позволяет сохранить его простым :) . . .
procedure Tform1.AnyButtonClick(Sender: TObject);
begin
If Sender is TButton then
begin
Case Tbutton(Sender).Tag of
.
.
.
// Or You can use the index in the list or some other property
// you have to decide what to do
// Or similar :)
end;
end;
procedure TForm1.BtnAddComponent(Sender: TObJect)
var
AButton: TButton;
begin
AButton := TButton.Create(self);
Abutton. Parent := [Self], [Panel1] [AnOther Visual Control];
AButton.OnClick := AnyButtonClick;
// Set Height and width and caption ect.
.
.
.
AButton.Tag := MyList.Add(AButton);
end;
список объектов может содержать любой объект, визуальный или нет, но это дает дополнительную нагрузку сортировки, какие элементы которых - лучше иметь связанные списки, если вы хотите использовать несколько динамических элементов управления на подобных панелей, например.
Примечание: как и другие комментаторы, я, возможно, слишком упрощен для краткости, но надеюсь, что вы идете. Вам нужен механизм для управления объектами, когда они созданы, и списки отлично подходят для этого материала.
Некоторые компоненты переопределяют метод «Loaded». Этот метод не будет вызываться автоматически, если вы создадите экземпляр во время выполнения. Он будет вызываться Delphi при загрузке из файла формы (DFM).
Если метод содержит код инициализации, ваше приложение может проявлять неожиданное поведение при создании во время выполнения. В этом случае проверьте, использовал ли этот компонент этот метод.
Если вы устанавливаете элементы управления победой в групповых ящиках/элементах управления страницами/Etc ..., я думаю, что поле родительской группы также является владельцем. Я заметил резкое уменьшение времени закрытия окна при выполнении этого, в отличие от того, что владелец всегда был основной формой.
Во время исследования «создание формы delphi с использованием шаблона на основе xml» я нахожу что-то полезное, указывающее RTTI и использующее открытые инструменты api (ToolsApi.pas, я думаю). Посмотрите на интерфейсы в блоке.
Я хотел бы добавить, что при динамическом добавлении элементов управления ... это хорошая идея добавить их в список объектов (TObjectList), как предложено в < 1> by @Despatcher.
procedure Tform1.AnyButtonClick(Sender: TObject);
begin
If Sender is TButton then
begin
Case Tbutton(Sender).Tag of
.
.
.
// Or You can use the index in the list or some other property
// you have to decide what to do
// Or similar :)
end;
end;
procedure TForm1.BtnAddComponent(Sender: TObJect)
var
AButton: TButton;
begin
AButton := TButton.Create(self);
Abutton. Parent := [Self], [Panel1] [AnOther Visual Control];
AButton.OnClick := AnyButtonClick;
// Set Height and width and caption ect.
.
.
.
AButton.Tag := MyList.Add(AButton);
end;
Вы должны добавить блок 'Contnrs' в список Uses. I.e System.Contnrs.pas базовый блок контейнеров И у вас может быть много списков объектов. Я предлагаю использовать TObjectList для каждого типа управления, который вы используете , например.
Interface
Uses Contnrs;
Type
TMyForm = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
Var
MyForm: TMyForm;
checkBoxCntrlsList: TObjectList; //a list for the checkBoxes I will createin a TPanel
comboboxCntrlsList: TObjectList; //a list of comboBoxes that I will create in some Form Container
Это позволяет легко манипулировать и управлять каждым элементом управления, так как вы будете знать, какой тип управления он, например.
Var comboBox: TComboBox;
I: Integer;
begin
For I = 0 to comboboxCntrlsList.Count -1 do // or however you like to identify the control you are accessing such as using the tag property as @Despatcher said
Begin
comboBox := comboboxCntrlsList.Items[I] as TComboBox;
...... your code here
End;
end;
Это позволяет затем использовать методы и свойства этого элемента управления Не забудьте создать TObjectLists, возможно, в форме создания события ...
checkBoxCntrlsList := TObjectList.Create;
comboboxCntrlsList := TObjectList.Create;
Это пример как эмулировать тег кнопки на Evernote
unit Unit7;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, CHButton, Vcl.ExtCtrls, RzPanel, CHPanel, RzCommon,RzBmpBtn, Vcl.StdCtrls;
type
// This is panel Button
TButtonClose = class (TRzPanel)
CloseButton : TRzBmpButton;
procedure CloseButtonClick(Sender: TObject);
procedure CloseButtonMouseEnter(Sender: TObject);
procedure MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
TForm7 = class(TForm)
CHButton1: TCHButton;
RzPanel1: TRzPanel;
RzBmpButton1: TRzBmpButton;
procedure CHButton1Click(Sender: TObject);
procedure RzBmpButton1Click(Sender: TObject);
procedure RzPanel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure RzPanel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure RzPanel1MouseEnter(Sender: TObject);
procedure RzBmpButton1MouseEnter(Sender: TObject);
procedure FormMouseEnter(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form7: TForm7;
MyCloseButton : TButtonClose;
implementation
{$R *.dfm}
// constructor for on the fly component created
constructor TButtonClose.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// Set Events for the component
Self.OnMouseEnter := Self.CloseButtonMouseEnter;
Self.OnMouseDown := Self.MouseDown;
Self.OnMouseUp := Self.MouseUp;
Self.Height := 25;
// Close button on top panel Button
// Inherited from Raize Bitmap Button
CloseButton := TRzBmpButton.Create(self);
// Set On Click Event for Close Button
CloseButton.OnClick := Self.CloseButtonClick;
// Place Close Button on Panel Button
CloseButton.Parent := self;
CloseButton.Left := 10;
CloseButton.Top := 5;
CloseButton.Visible := False;
// Setting the image for the button
CloseButton.Bitmaps.Up.LoadFromFile(ExtractFilePath(Application.ExeName)+'\close.bmp');
end;
procedure TButtonClose.CloseButtonClick(Sender: TObject);
begin
// Free the parent (Panel Button)
TControl(Sender).Parent.Free;
end;
procedure TButtonClose.CloseButtonMouseEnter(Sender: TObject);
begin
// Show the Close button
CloseButton.Visible := True;
end;
procedure TButtonClose.MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
// Emulate Button down state, since it is panel
TRzPanel(Sender).BorderOuter := fsLowered;
end;
procedure TButtonClose.MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
// Emulate Button up state, since it is panel
TRzPanel(Sender).BorderOuter := fsRaised;
end;
destructor TButtonClose.Destroy;
begin
inherited Destroy;
end;
procedure TForm7.FormCreate(Sender: TObject);
begin
// Create Panel Button on the fly
MyCloseButton := TButtonClose.Create(self);
MyCloseButton.Caption := 'My Button';
MyCloseButton.Left := 10;
MyCloseButton.Top := 10;
// Don't forget to place component on the form
MyCloseButton.Parent := self;
end;
procedure TForm7.FormMouseEnter(Sender: TObject);
begin
if Assigned(RzBmpButton1) then
RzBmpButton1.Visible := False;
// Hide when mouse leave the button
// Check first if myCloseButton Assigned or not before set visible property
if Assigned(MyCloseButton.CloseButton) then
MyCloseButton.CloseButton.Visible := False;
end;
procedure TForm7.RzBmpButton1Click(Sender: TObject);
begin
TControl(Sender).Parent.Free;
end;
procedure TForm7.RzBmpButton1MouseEnter(Sender: TObject);
begin
RzBmpButton1.Visible := True;
end;
procedure TForm7.RzPanel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
TRzPanel(Sender).BorderOuter := fsLowered;
end;
procedure TForm7.RzPanel1MouseEnter(Sender: TObject);
begin
RzBmpButton1.Visible := True;
end;
procedure TForm7.RzPanel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
TRzPanel(Sender).BorderOuter := fsRaised;
end;
procedure TForm7.CHButton1Click(Sender: TObject);
begin
FreeAndNil(Sender);
end;
end.
- 1. Delphi - Создание компонента во время выполнения
- 2. Дублирование компонентов во время выполнения
- 3. Создание компонентов с прослушивателем во время выполнения в java
- 4. Создание времени выполнения компонентов Delphi Firemonkey из строки
- 5. создание DELPHI таймеров динамически во время выполнения (производительность, CPU потребляющий)
- 6. Delphi - Создание базы данных MySQL во время выполнения
- 7. Создание объектов Delphi во время выполнения на основе типа класса
- 8. Delphi: Создание TComboBox в динамически созданной форме во время выполнения
- 9. Устранение компонентов facelets во время выполнения
- 10. Получение компонентов jpanel во время выполнения
- 11. Связывание компонентов JSF2.0 во время выполнения
- 12. создание столбца во время выполнения во время выполнения sql-запроса
- 13. Создание JComboBoxes во время выполнения
- 14. Создание объектов во время выполнения
- 15. Создание DataGridView во время выполнения
- 16. Создание столбца во время выполнения
- 17. Создание объектов во время выполнения
- 18. Создание БД во время выполнения
- 19. Создание таблицы во время выполнения
- 20. Создание объектов во время выполнения
- 21. Delphi - TSplitter выравнивать во время выполнения
- 22. Delphi: освобождение динамического контроля во время выполнения
- 23. Delphi Firemonkey - стиль загрузки во время выполнения
- 24. Загрузка DLL во время выполнения - Delphi
- 25. delphi изменить pchar во время выполнения
- 26. Android: изменение видимости компонентов во фрагменте во время выполнения
- 27. Изменение класса компонентов во время выполнения по запросу
- 28. отключить исключения delphi во время выполнения в delphi
- 29. Delphi: определение того, какой компонент необходимо создать во время выполнения
- 30. Предотвращение создания компонентов - Delphi
Но если я не знаю, сколько компонентов я хочу создать, например. если это зависит от решения пользователя. Итак, как я могу объявить компоненты динамически? –
Различие в том, следует ли передавать ниль или другой компонент в качестве владельца, не имеет ничего общего с видимым компонентом или только с временем жизни объекта. Невидимый компонент, который не освобождается в том же методе, может быть создан так же, как и во втором фрагменте, и автоматически освобождается владельцем. – mghie
s/visible/visual/g – mghie