Неопределенное количество форм в рантайме.
Модератор: Модераторы
Неопределенное количество форм в рантайме.
Привет всем!
Толком никогда не сталкивался до этого с созданием компонент в рантайме. Суть вопроса вот в чем.
Пишу клиента к БД. Есть таблица ЛИЦА - в ней кроме всего прочего есть ссылки на справочники (страна рождения, нас. пункт рождения), ссылки на таблицу адреса (а вней тоже ссылки на страну, город, район) и т.п. В общем довольно сложная БД. Таблиц предвидится довольно много (100 или более). К каждой таблице (по необходимости) делаю свою форму просмотра/редактирования/добавления. Соответственно форм тоже будет много, а кроме них же еще куча вспомогательных... Возникли вопросы:
Поначалу планировал все эти формы в дизайн-тайме создавать, а потом экземпляры форм по необходимости. Но большое количество форм будет сразу загружено в память, что не есть гуд (ведь я
только потом буду создавать и уничтожать экземпляры форм, а начальные так и будут висеть в памяти) - как создать саму изначальную форму в рантайме именно такой, какой я ее могу нарисовать в дизайнере форм. И вообще правильный, пример создания компонент в рантайм, причем необходимо будет наверное каждому создавемому компоненту формы присваивать индек через глобальные переменные например, оформленные в отдельном модуле, который буду подключать к каждой форме.
Поясню: открываем в таблице ЛИЦА запись в предназначенной для этого форме. Кроме всего прочего, в этой форме (записи) есть поле НАС. ПУНКТ РОЖДЕНИЯ , открываем соответствующую запись в таблице СПИСОК НАСЕЛЕННЫХ ПУНКТОВ (тоже своя форма), в этой записи есть раздел ЛИЦА - открываем его, открывается форма-просмотрщик таблиц (постараюсь сделать 1 - универсальную на все таблицы) - это список лиц, у которых указан этот нас. пункт. Выбираем из этого списка другое лицо, и уже в нем просматриваем нас. пункт (или другое поле - аналогично).
Вероятно "уровень вложенности" форм я потом ограничю.
Как все это можно правильно реализовать. Хотя бы небольшие примеры. Просто кое-чего знаю, но пробелов в знаниях хватает.
Если кто видел ПО "Меридиан", "Пилигрим", "Легенда", "Орбита" (sonarplus.ru)и подобное им - хочу сделать как у них - довольно удобно получается.
Толком никогда не сталкивался до этого с созданием компонент в рантайме. Суть вопроса вот в чем.
Пишу клиента к БД. Есть таблица ЛИЦА - в ней кроме всего прочего есть ссылки на справочники (страна рождения, нас. пункт рождения), ссылки на таблицу адреса (а вней тоже ссылки на страну, город, район) и т.п. В общем довольно сложная БД. Таблиц предвидится довольно много (100 или более). К каждой таблице (по необходимости) делаю свою форму просмотра/редактирования/добавления. Соответственно форм тоже будет много, а кроме них же еще куча вспомогательных... Возникли вопросы:
Поначалу планировал все эти формы в дизайн-тайме создавать, а потом экземпляры форм по необходимости. Но большое количество форм будет сразу загружено в память, что не есть гуд (ведь я
только потом буду создавать и уничтожать экземпляры форм, а начальные так и будут висеть в памяти) - как создать саму изначальную форму в рантайме именно такой, какой я ее могу нарисовать в дизайнере форм. И вообще правильный, пример создания компонент в рантайм, причем необходимо будет наверное каждому создавемому компоненту формы присваивать индек через глобальные переменные например, оформленные в отдельном модуле, который буду подключать к каждой форме.
Поясню: открываем в таблице ЛИЦА запись в предназначенной для этого форме. Кроме всего прочего, в этой форме (записи) есть поле НАС. ПУНКТ РОЖДЕНИЯ , открываем соответствующую запись в таблице СПИСОК НАСЕЛЕННЫХ ПУНКТОВ (тоже своя форма), в этой записи есть раздел ЛИЦА - открываем его, открывается форма-просмотрщик таблиц (постараюсь сделать 1 - универсальную на все таблицы) - это список лиц, у которых указан этот нас. пункт. Выбираем из этого списка другое лицо, и уже в нем просматриваем нас. пункт (или другое поле - аналогично).
Вероятно "уровень вложенности" форм я потом ограничю.
Как все это можно правильно реализовать. Хотя бы небольшие примеры. Просто кое-чего знаю, но пробелов в знаниях хватает.
Если кто видел ПО "Меридиан", "Пилигрим", "Легенда", "Орбита" (sonarplus.ru)и подобное им - хочу сделать как у них - довольно удобно получается.
В таких вопросах лучше ориентироваться на существующие статьи/блоги/документацию по Delphi, потому что в Lazarus это делается почти так же. Например:OberonAR писал(а):И вообще правильный, пример создания компонент в рантайм
Динамическое создание компонентов: http://www.delphikingdom.ru/asp/viewite ... alogid=342
Динамическое создание форм: http://delphiexpert.ru/view_lesson.php?id=42
Запрос "Delphi динамическое создание компонентов" в любом поисковике выдаст ещё много интересного.
Совершенно не обязательно. К компонентам формы можно обращаться через переменную формы. Например, можно создать в дизайн-тайме форму типа TForm2, объявить две переменные Form2Instance1: TForm2 и Form2Instance2: TForm2. И тогда, если на форме лежит кнопка Button1, то Form2Instance1.Button1 - это кнопка на форме Form2Instance1, а Form2Instance2.Button1 - кнопка на форме Form2Instance2.OberonAR писал(а):причем необходимо будет наверное каждому создавемому компоненту формы присваивать индек через глобальные переменные например, оформленные в отдельном модуле, который буду подключать к каждой форме.
Odyssey писал(а):Совершенно не обязательно. К компонентам формы можно обращаться через переменную формы. Например, можно создать в дизайн-тайме форму типа TForm2, объявить две переменные Form2Instance1: TForm2 и Form2Instance2: TForm2. И тогда, если на форме лежит кнопка Button1, то Form2Instance1.Button1 - это кнопка на форме Form2Instance1, а Form2Instance2.Button1 - кнопка на форме Form2Instance2.
А если заранее неизвестно количество этих форм? Надо же как то заранее опредилиться с именами форм ( Form2Instance1: TForm2, Form2Instance2: TForm2....Form2InstanceX: TForm2)
Да и наверное неправильно будет создавать ВСЕ (100 например) изначальные формы во время запуска приложения, правильнее наверное по мере надобности. Отсюда и один из моих первых вопросов: как правильно это оформить в программе? "Создать форму" из меню Лазаруса? А потом что сделать с юнитом? Наверное как-то отредактировать, чтобы создавался только класс формы, но не экземпляр? В общем плаваю я
- leo_bsv
- постоялец
- Сообщения: 276
- Зарегистрирован: 04.08.2010 16:26:10
- Откуда: Йошкар-Ола
- Контактная информация:
я делаю вот как:
Добавлено спустя 12 минут 42 секунды:
осмелюсь высказать мысль что кучу форм определить можно как-то так:
кроме обычного массива есть специальные массивы для объектов, на этом форуме обсуждалось...
После чего создавать и работать с ними по индексу... также формам можно присваивать различные значения поля Tag... после чего управлять ими отслеживая это поле...
Добавлено спустя 2 минуты 48 секунд:
естественно сама форма рисуется в дизайнере, а её модуль и строка вида
удаляются из файла проекта. После чего модуль формы, в моём случае это AttrForm, подключается к модулю формы, непосредственно управляющей этими формами... после чего если нужно показать форму выводим её как я показал выше... в этом случае формы не создаются во время запуска приложения, а создаются в нужный момент.
Код: Выделить всё
// вызовем окно для редактирования
AttrForm := TAttrForm.Create(nil);
try
AttrForm.ShowModal;
finally
AttrForm.Free; // освобождаем место в памяти
end;
Добавлено спустя 12 минут 42 секунды:
осмелюсь высказать мысль что кучу форм определить можно как-то так:
Код: Выделить всё
var
AttrFormArr: array of TAttrForm;
кроме обычного массива есть специальные массивы для объектов, на этом форуме обсуждалось...
После чего создавать и работать с ними по индексу... также формам можно присваивать различные значения поля Tag... после чего управлять ими отслеживая это поле...
Добавлено спустя 2 минуты 48 секунд:
естественно сама форма рисуется в дизайнере, а её модуль и строка вида
Код: Выделить всё
Application.CreateForm(TAttrForm, AttrForm);
удаляются из файла проекта. После чего модуль формы, в моём случае это AttrForm, подключается к модулю формы, непосредственно управляющей этими формами... после чего если нужно показать форму выводим её как я показал выше... в этом случае формы не создаются во время запуска приложения, а создаются в нужный момент.
Последний раз редактировалось leo_bsv 10.02.2012 17:49:35, всего редактировалось 1 раз.
С созданием форм вроде разобрался, всем спасибо, но получается, что в моем проекте из этих разных 100 форм нужно создавать любую другую форму. Вот поэтому и хочу прописать в отдельном общем модуле все эти формы и подключать его к ним же... фигня какаято получается...
Кроме всего прочего надо будет от каждого родителя передавать нек-е параметры в создаваемую форму и назад в родитель при закрытии дочерней. Это наверное будет отдельная песня...
Кроме всего прочего надо будет от каждого родителя передавать нек-е параметры в создаваемую форму и назад в родитель при закрытии дочерней. Это наверное будет отдельная песня...
Последний раз редактировалось OberonAR 10.02.2012 17:54:32, всего редактировалось 1 раз.
- Brainenjii
- энтузиаст
- Сообщения: 1351
- Зарегистрирован: 10.05.2007 00:04:46
Напишите генератор форм
- leo_bsv
- постоялец
- Сообщения: 276
- Зарегистрирован: 04.08.2010 16:26:10
- Откуда: Йошкар-Ола
- Контактная информация:
OberonAR писал(а):100 форм нужно создавать любую другую форму
как вариант можно сделать форму со сложной таблицей (в каждой ячейке динамически цеплять нужный редакор - Edit, ListBox и т.д., в зависимости от типа поля), и загружать нужные поля в неё... не придётся создавать для каждой таблицы БД свою форму...
Добавлено спустя 1 минуту 47 секунд:
Brainenjii писал(а):Напишите генератор форм
офигеть =) а если полей в таблице штук 100 )))
- Brainenjii
- энтузиаст
- Сообщения: 1351
- Зарегистрирован: 10.05.2007 00:04:46
тем более генератор форм ^_^
- leo_bsv
- постоялец
- Сообщения: 276
- Зарегистрирован: 04.08.2010 16:26:10
- Откуда: Йошкар-Ола
- Контактная информация:
OberonAR писал(а):Кроме всего прочего надо будет от каждого родителя передавать нек-е параметры в создаваемую форму и назад в родитель при закрытии дочерней. Это наверное будет отдельная песня...
Добавьте к вызываемой форме новое свойство типа TStringList и пихайте в него параметры ) а перед закрытием считывайте его...
Добавлено спустя 2 минуты 26 секунд:
Brainenjii писал(а):тем более генератор форм ^_^
пошариться если в интернетах, можно наверно и готовое чё-нить найти...
Добавлено спустя 2 минуты 21 секунду:
ИМХО генератор форм писать к программе-морде к БД... это жесть =)
но то что это круто - без сомнения !
Ну хорошо... С передачей параметров я определился - будут глобальные переменные разных типов в в отдельном модуле, этот модуль будет подключен к каждой форме. Но все таки не понял - как все эти формы смогут создавать друг - друга, возможно даже саму себя (в смысле такой же экземпляр), может их как то тоже запихать в общий модуль-в котором уже есть глобальные пепременные? Тогда вопрос - как это сделать?
- leo_bsv
- постоялец
- Сообщения: 276
- Зарегистрирован: 04.08.2010 16:26:10
- Откуда: Йошкар-Ола
- Контактная информация:
ну фиг знает,.. как-то так:
пример рабочий
Код: Выделить всё
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
FormsArr: array of TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
SetLength(FormsArr,Length(FormsArr)+1);
FormsArr[high(FormsArr)] := TForm1.Create(nil);
try
FormsArr[high(FormsArr)].ShowModal;
finally
FormsArr[high(FormsArr)].Free;
SetLength(FormsArr,Length(FormsArr)-1);
end;
end;
end.
пример рабочий
Глобальные переменные не нужны.
В модуле, содержащем класс формы, нужно прописать процедуру вроде:
Когда понадобиться создать экземпляр, просто вызвать:
с нужными параметрами.
Так можно создать сколько угодно экземпляров формы, лишь бы памяти хватило...
В модуле, содержащем класс формы, нужно прописать процедуру вроде:
Код: Выделить всё
procedure GetThisform(Param..Param..);
var ThisForm:TThisForm;
begin
Application.CreateForm(TThisForm,ThisForm);
with ThisForm do
begin
...
...
end;
end;
Когда понадобиться создать экземпляр, просто вызвать:
Код: Выделить всё
GetThisform(Param..Param..);с нужными параметрами.
Так можно создать сколько угодно экземпляров формы, лишь бы памяти хватило...
OberonAR
Постарайтесь, как можно более унифицировать вид форм, чтобы избежать создания большого количества классов форм.
Постарайтесь, как можно более унифицировать вид форм, чтобы избежать создания большого количества классов форм.
А если сделать все таки 1 форму, а на ней pagecontrol с вкладками под каждую таблицу и при вызове делать visible:=true только нужной вкладке?
Добавлено спустя 1 час 23 минуты 46 секунд:
Посмотрите пожалуйста получившийся проект. Примерно так буду делать вызов этих форм. Может будут какие ни будь замечания. Утечки памяти или еще что ни будь...
Не могу добавить вложения, говорит достигнут максимальный общий размер вложений, а в моем профиле список вложений пуст... Куда можно выложить?
Добавлено спустя 25 минут 56 секунд:
http://narod.ru/disk/40355706001/formi.7z.html
Добавлено спустя 1 час 23 минуты 46 секунд:
Посмотрите пожалуйста получившийся проект. Примерно так буду делать вызов этих форм. Может будут какие ни будь замечания. Утечки памяти или еще что ни будь...
Не могу добавить вложения, говорит достигнут максимальный общий размер вложений, а в моем профиле список вложений пуст... Куда можно выложить?
Добавлено спустя 25 минут 56 секунд:
http://narod.ru/disk/40355706001/formi.7z.html
