Динамическое создание компонентов

Вопросы программирования и использования среды Lazarus.

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

Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

1 Уже работает ...
2 Копипаста мной же написанных "костылей" явление временное . (А если это про "код на форуме" то смотри объяснение ниже )
3 Некоторые вещи бесполезно имитировать "в простом примере" просто потому, что для того что-бы добиться доверенного повторения ситуации иногда нужно "имитировать" ( да еще и довольно криво ) половину функционала программы.
4 К самой описываемой ситуации все лишение отношения не имеет ( а процедура ClearTabList; приводится полностью просто для достоверности )
Ps
Суть задачи :
1 Нужно сохранить состояние PageControl
2 ...и через некоторое время вернуть обрано.
3 Сохранять полное состояние всех страниц в данном случае не нужно ( но ClearTabList; намекает об этом нужно подумать )
4 Если перенести код "в чистый пример" то ничего кроме ClearTabList; в части где я "прячу вкладку" не изменится.
Кстати "прятать" можно и так :

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

For I:=0 to  MForm.PageControl1.PageCount-1 do
If  MForm.PageControl1.Pages[i].ControlCount>1 then
{ Именно ">1"  это не ошибка, а "фича" моей программы где первый раз добавляется заставка, но дальше она неважна   }
begin
// Неразрушающие удаление элементов конкретной страницы .
For j:=MForm.PageControl1.Pages[i].ControlCount-1 DownTo 0 do
MForm.PageControl1.Pages[i].RemoveControl(MForm.PageControl1.Pages[i].Controls[J]);
end;

Но наглядность этого кода еще меньше чем в случае "прямых ссылок".
Ps Ps
Извиняюсь за косноязычие, но если одновременно править код и писать на форум это слегка сбивает с мысли. :idea:
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

Ты понимаешь что такое минимальный пример?

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

Твои.охренеть[какие].длинные22.конструкции^
- это твои интимные проблемы, обитателям форума они не интересны
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

По обнаруженной "загадке " ее суть в том, что похоже есть возможность автоматического создания (и удаления) закладок при прямом задании списка заголовков. (Но "это неточно" ... :idea: )

Добавлено спустя 33 минуты:
zub писал(а):Ты понимаешь что такое минимальный пример?

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

Твои.охренеть[какие].длинные22.конструкции^
- это твои проблемы, обитателям форума они не интересны

Учту ! Но по моему добавление одного "колена" с именем формы больших проблем не вызывает. :roll:
(Просто процедура находится не в модуле основной формы но принципе согласен удобства для понимания это не добавляет )
Ну ладно попробую упростить ....

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

procedure  TForm1.Button1Click(Sender: TObject); 
//===============
procedure ClearTabList; // Очистка PageControl
Var i,j:Integer; T:TTabSheet;
Begin
// Убираю не пустые вкладки перед очисткой
For I:=0 to  PageControl1.PageCount-1 do begin
T:=PageControl1.Pages[i];
If T.ControlCount>0 then
// Неразрушающие удаление элементов конкретной страницы .
For j:=T.ControlCount-1 DownTo 0 do
T.RemoveControl(T.Controls[J]);
end
end;
// Очистка списка страниц.
For I:=PageControl1.PageCount-1  DownTo 0 do
if  PageControl1.ActivePageIndex<>I then PageControl1.Pages[I].Free;
PageControl1.ActivePage.Free;
end;
//===============================
Const
STab:String='';
 F_Script_Ctrl:boolean=true;
Var
i:Integer;
ST:TStringList;
TS:TTabSheet;


begin
 If F_Script_Ctrl Then begin // F_Script_Ctrl - Некий произвольный флаг .
 F_Script_Ctrl:= not F_Script_Ctrl;
// Сохраняю  заголовки закладок
Stab:=TCustomTabControl( PageControl1).Pages.Text;
// дальше или "неправильная строка"
//TCustomTabControl( PageControl1).Pages.Clear;
// или очистка "по учебнику "  .
 
ClearTabList;//Очистка

/Тут идет код создания закладок PageControl для  работы в другом режиме работы ...
//...

 end else begin
 F_Script_Ctrl:= not F_Script_Ctrl;
//Восстановление списка страниц.

// или пишем
//TCustomTabControl( PageControl1).Pages.Text :=STab;
// или "по учебнику "  код  ниже .(Оба варианта работают )

  ClearTabList;//Очистка

  ST:= TStringList.Create;  ST.Text:=Stab;
  For I:=0 To st.Count-1 do
  begin
    TS:= TTabSheet.Create(PageControl1);
    TS.PageControl:=PageControl1;
    TS.Caption:= ST[I];
    TS.Align:=alClient;
   end;
 ST.Free;
 end;

"Неразрушающие удаление элементов конкретной страницы ." Подразумевает что списки ссылок Controls для каждой станицы где-то сохраняются и воспроизводятся отдельно ли же программа перемещает базовое содержимое одной единственной страницы при их переключении. (В моей программе работает именно второй сценарий )
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

)) если ты думаешь что этим

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

T:=PageControl1.Pages[i];
If T.ControlCount>0 then

ты чтото упростил - ошибаешся, ты просто из однй строчки

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

Твои.охренеть[какие].длинные22.конструкции^

сделал две таких строчки

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

Твои.охренеть[какие].длинные22.конструкции^
Твои.охренеть[какие].длинные22.конструкции^


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

вообще, сам подход по сохранению где-то каких-то контролов - зачем? сохранять надо данные
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Уф!
zub писал(а):вообще, сам подход по сохранению где-то каких-то контролов - зачем? сохранять надо данные

Кратко:Сейчас в программе есть два режима "Статический" и "Динамический" . Но пока нужны оба."подход по сохранению" нужен именно для их поддержки.
.
В будущем будет один "Динамический", а "Статический" или исчезнет или будет эмулирован данными "по умолчанию"
.
(Чуть подобнее : данные программа качает из интернета и не всегда можно понять где именно сбой на сайте или в программе, а тут еще и динамическая модель обработки "подкралась незаметно", вообщем на текущем этапе нужно что-бы "старый код" переключения станиц не смешивался с новым и гарантировано оставался не изменным, а для этого нужно сохранять и восстанавливать состояние при переключении режимов )

ИзображениеИзображение
если ты думаешь что этим
T:=PageControl1.Pages[i];
ты что-то упростил - ошибаешься.

Ничего подобного я не думаю вот лишний для примера MForm. я действительно убрал а дополнительная переменная это просто мелкий чит для себя ленивого ... Дальше идёт четырех кратный вызов этого "коленчатого вала" и with только все запутает, а так все гарантировано пучком .

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

If T.ControlCount>0 then
For j:=T.ControlCount-1 DownTo 0 do
T.RemoveControl(T.Controls[J]);

Если думаешь, что всюду и все нужно писать через with то это "гнусный ревизионизм". :wink:
Прямо в этом коде столкнулся с тем что "изящный финт ушами "

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

 With TStringList.Create do 
begin
Text:=Stab;
For I:=0 To Count-1 do
     with  TTabSheet.Create( PageControl1 ) do
        Caption:= Strings[I];
  Free;
 end;

...не сработал! Если конкретно то Text:=Stab; не работает от слова совсем и шут его знает почему!
И уж тем более я не собираюсь без нужды тревожить не известно за что так любимый на этом форуме префикс "as" ...
Зы
Главный "хит"
TCustomTabControl( PageControl1 ) .Pages.Clear; и TCustomTabControl( PageControl1 ).Pages.Text :=STab;
...никак особенно не сократишь хоть тресни (Запутать можно, а написать короче шишь с постным маслом! )
А в нем суть вопроса.

А сам вопрос прост :
Можно ли пользоваться этим недокументированным "черным ходом" без создания TTabSheet?
(Работает успешно но непонятно есть ли какое-то ограничения)
( TCustomTabControl в Pages просто список строк а TPageControl свойство возвращающее ссылку на TTabSheet )

+ Все это просто еще не много исследований теме "Динамическое создание компонентов".
Зы Зы
Текущий подпрограммы это хак не использует и все работает нормально. :idea:
Последний раз редактировалось Alex2013 03.12.2021 16:02:37, всего редактировалось 1 раз.
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

Я тебя не понимаю.
И в третий раз повторяю - чтобы другие форумчане могли тебя понять и помочь, нужен минимальный пример воспроизводящий проблему

ИМХО ты пишешь вкорне неправильно - от гуя. отсюда и проблемы
Нужно от данных. Контролы только способ временно показать и дать поредактировать данные пользователю.
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

zub писал(а):Нужно от данных. Контролы только способ временно показать и дать поредактировать данные пользователю.

Тут согласен ! Но мрачная перспектива бесконечной правки, вечно нерабочего кода , пугает меня достаточно сильно. К том уже основа данной задачи парсинг сайтов, который как известно вещь "скоропортящаяся" и нужно успеть с ним разобраться до очередного "взрыва креативности веб дизайнеров" ( сейчас я делаю динамический движок чтобы немного увеличить свободу маневра, но первые сборки все равно нужно "делать в статике" (просто потому вначале непонятно, что делать с этими сайтами вообще ( единственное, что есть как пример это полурабочая программа аналог (без исходников и в UWP ) заброшенная автором), а дальше какое-то время обе модели должны "мирно сосуществовать" для доработки "динамической модели". )

"минимальный пример воспроизводящий проблему"

Назначение кода: переключает PageControl в альтернативный режим и возвращает его состояние обратно .

(Для получения рабочего примера нужно: Кинуть на пустую форму PageControl1, создать там несколько пустых закладок через IDE,
, добавить Button1 вне страниц PageControl1 и использовать обработчик нажатия кнопки код котрого приведен ниже )

:idea: По условиям задачи создавать, сохранять или очищать содержимое закладок не нужно .
( всем этим в моей программе занимается переключение страниц)

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

procedure  TForm1.Button1Click(Sender: TObject);
Const
STab:String='';
F_Script_Ctrl:boolean=False;
Var
i:Integer;
begin
F_Script_Ctrl:= not F_Script_Ctrl;
If F_Script_Ctrl Then begin // F_Script_Ctrl - Некий произвольный флаг .

// Сохраняю  заголовки закладок
Stab:=TCustomTabControl( PageControl1).Pages.Text;

TCustomTabControl( PageControl1).Pages.Clear;

//Тут идет код создания закладок PageControl для  работы в другом режиме работы ...
//Например такой...
{
  For I:=0 To 5 do
  begin
  TS:= TTabSheet.Create(MForm.PageControl1);
  TS.PageControl:=MForm.PageControl1;
  TS.Caption:= 'Test '+IntToStr(i);
  ts.Align:=alClient;
end;
}
end else begin
//Восстановление списка страниц.
TCustomTabControl( PageControl1).Pages.Text :=STab;
end;


Главный вопрос: можно ли считать это код стабильным ? ( В том что он рабочий сомнений нет ).

Дело в том, что если писать "по учебнику" аналогичная процедура выходит заметно сложнее и запутанней.
(+ Если есть возможность создавать закладки просто задавая список заголовков то это само по себе отличная новость!)

Но если делать с выше показанным применением приведения типов TCustomTabControl( PageControl1 ) то не понятно откуда "внезапно и загадочно " появляются новые TabSheet .
Зы
А вообще весьма возможно что я погорячился и использовать PageControl не имеет особого смысла ( По идее более простой TabControl справиться со всей этой ситуаций заметно успешнее ). (Но пока «Маємо те що маємо» :wink: )
zub
долгожитель
Сообщения: 2889
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

такое считать стабильным нельзя))
он неправильно обработает наличие спецсимволов в капшенах, в частности #13 #10, может еще что, см. код стринглиста

"код" не сохраняет и не возвращает состояние, он пересоздает вкладки
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Ну что-ж жаль конечно, но не критично ... (в программе уже все успешно работает в варианте "по учебнику" )
ИзображениеИзображение
Видимая на скрине галка " Список основных источников " успешно переключила программу в "динамический режим" из "статического".
(Обратная операция тоже работает )
Ответить