Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 15.03.2008, 14:56
Gad99 Gad99 вне форума
Новичок
 
Регистрация: 21.02.2008
Адрес: мурманск
Сообщения: 72
Репутация: 10
По умолчанию Обращение к динамическим компонентам

В программе : Вызываю процедуру в которой создается массив TLabel с последующим переименованием, завершаю процедуру, и при попытке обратится к одной из созданных TLabel Компилятор указывает на то что созданные мною MyLabel не задикларированны. Как быть?
Ответить с цитированием
  #2  
Старый 15.03.2008, 15:22
Аватар для zip000
zip000 zip000 вне форума
Начинающий
 
Регистрация: 24.07.2007
Сообщения: 194
Репутация: 25
По умолчанию

Искать нужный компонент по имени :
Код:
var
  lbl : TLabel;
...................
lbl := TLabel(FindComponent('имя_нужного_лейбла'));
__________________
Не профи, но и не чайник . D6 - лучше не придумали. Пока.
Ответить с цитированием
  #3  
Старый 15.03.2008, 15:41
Rosenkrantz Rosenkrantz вне форума
Активный
 
Регистрация: 04.12.2007
Адрес: Москва
Сообщения: 234
Версия Delphi: Delphi 7
Репутация: 40
По умолчанию

Как вы создаете метки и как обращаетесь?
Ответить с цитированием
  #4  
Старый 15.03.2008, 15:49
Gad99 Gad99 вне форума
Новичок
 
Регистрация: 21.02.2008
Адрес: мурманск
Сообщения: 72
Репутация: 10
По умолчанию

Вот так создаю
Код:
procedure TForm1.CreateLabel (x : integer);
var LabelAr : array of TLabel;
k : byte;
Begin
  For k := 1 to x do
    Begin
    SetLength(LabelAr,k);
    LabelAr[k] := TLabel.Create(self);
    LabelAr[k].Name := 'MyLabel'+inttostr(k);
    LabelAr[k].Left := 50;
    LabelAr[k].Top :=k * 50;
    LabelAr[k].Parent := Text.Panel1;
    End;
End;
Вот так пытаюсь использовать
Код:
CreateLabel(1);
Text.MyLabel1.Caption := 'hello';
Text.MyLabel1.Left := (Text.Panel1.Width - Text.MyLabel1.Width)Div 2;
Ответить с цитированием
  #5  
Старый 15.03.2008, 15:56
Gad99 Gad99 вне форума
Новичок
 
Регистрация: 21.02.2008
Адрес: мурманск
Сообщения: 72
Репутация: 10
По умолчанию

Цитата:
Сообщение от zip000
Искать нужный компонент по имени :
Код:
var
  lbl : TLabel;
...................
lbl := TLabel(FindComponent('имя_нужного_лейбла'));

не прокатывает, так же ругается на отсутствие LB1 компонента всписке.
Ответить с цитированием
  #6  
Старый 15.03.2008, 16:07
Аватар для zip000
zip000 zip000 вне форума
Начинающий
 
Регистрация: 24.07.2007
Сообщения: 194
Репутация: 25
По умолчанию

Gad99, в качестве имени нужно указывать вот это
Код:
    LabelAr[k].Name := 'MyLabel'+inttostr(k);
Т.е. MyLabel1, MyLabel2 и т.д.
__________________
Не профи, но и не чайник . D6 - лучше не придумали. Пока.
Ответить с цитированием
  #7  
Старый 15.03.2008, 16:26
Rosenkrantz Rosenkrantz вне форума
Активный
 
Регистрация: 04.12.2007
Адрес: Москва
Сообщения: 234
Версия Delphi: Delphi 7
Репутация: 40
По умолчанию

У вас небольшая путаница в голове, вызванная работой в IDE Delphi. Объясню: при создании метки в design-time ей присваивается имя, например, 'Label1', и одновременно в теле класса формы IDE создает переменную, указывающую на эту ссылку и называет переменную так же - Label1. Потом, если вы дадите метке другое имя, IDE автоматически переименует переменную. Но это все делает IDE, это не является функциональностью языка Delphi.

При работе в run-time от того, что вы дали компоненту метки имя 'Label1' переменная Label1 не появляется. Все переменные вам нужно объявлять явно. Еще раз посмотрим на ваш код:
Код:
procedure TForm1.CreateLabel (x : integer);
var LabelAr : array of TLabel;
k : byte;
Begin
  For k := 1 to x do
    Begin
    SetLength(LabelAr,k);
    LabelAr[k] := TLabel.Create(self);
    LabelAr[k].Name := 'MyLabel'+inttostr(k);
    LabelAr[k].Left := 50;
    LabelAr[k].Top :=k * 50;
    LabelAr[k].Parent := Text.Panel1;
    End;
End;
В этой процедуре вы объявляете массив LabelAr, заполняете его метками (кстати, неправильно используя индекс - открытые массивы нумеруются с нуля) и на этом процедура завершается. Поскольку LabelAr у вас объявлен как локальная переменная, после завершения процедуры вся информация о нем утеряна. Поэтому, в данном случае, вообще непонятно - зачем он нужен в программе.

Дальше вы пытаетесь обратится к метке, используя имя, которое вы присвоили, в качестве переменной. Компилятор не обнаруживает такой переменной и сообщает вам об ошибке.

Чтобы найти метку по имени, как совершенно правильно тут написали, нужно вызвать FindComponent:
Код:
var
  L: TLabel;
begin
...
  L := Text.FindComponent('MyLabel1');
  if L <> nil then 
    ...
...
end;
FindComponent - это метод класса TComponent, т.е. когда вы в методе формы пишете FindComponent, вы вызываете метод формы. Если метка лежит на фрейме, то форма ее не найдет, нужно вызывать метод FindComponent фрейма. Я надеюсь, что правильно догадался, что Text у вас - это фрейм?

Вот в таком вот аксепте
Ответить с цитированием
  #8  
Старый 15.03.2008, 16:44
Gad99 Gad99 вне форума
Новичок
 
Регистрация: 21.02.2008
Адрес: мурманск
Сообщения: 72
Репутация: 10
По умолчанию

Что то я совсем запутался.
Разве при выполнении процедуры по созданию массива меток они не появляются на фрейме?

Text это фрейм.

Что конкретно нужно сделать что бы задумка сработала, обявлять массив глобальным ???
Ответить с цитированием
  #9  
Старый 15.03.2008, 16:57
Аватар для zip000
zip000 zip000 вне форума
Начинающий
 
Регистрация: 24.07.2007
Сообщения: 194
Репутация: 25
По умолчанию

Вот вам нормальный код создания лейблов.
Код:
procedure TForm1.CreateLabel(X : Integer);
var
  l : TLabel;
begin
  while X > 0 do begin
    l := TLabel.Create(Self);
    l.Name := 'MyLabel' + IntToStr(X);
    l.Left := 50;
    l.Top  := X * 50;
    l.Parent := Text.Panel1;
    Dec(X);
  end;
end;
А вот так обращаться к нужному лейблу
Код:
var
  l : TLabel;
................................
  CreateLabel(1);
  l := Text.FindComponent('MyLabel1');
  if l <> nil then begin
    l.Caption := 'hello';
    l.Left := (Text.Panel1.Width - l.Width)Div 2;
  end;
__________________
Не профи, но и не чайник . D6 - лучше не придумали. Пока.
Ответить с цитированием
  #10  
Старый 15.03.2008, 17:11
Rosenkrantz Rosenkrantz вне форума
Активный
 
Регистрация: 04.12.2007
Адрес: Москва
Сообщения: 234
Версия Delphi: Delphi 7
Репутация: 40
По умолчанию

Цитата:
Сообщение от Gad99
Что то я совсем запутался.
Разве при выполнении процедуры по созданию массива меток они не появляются на фрейме?
Они появляются в результате выполнения вот этой строчки:
Код:
LabelAr[k].Parent := Text.Panel1;
При этом не имеет значения, где хранится указатель на метку - в локальном или глобальном массиве или вообще не хранится:
Код:
with TLabel.Create(Self) do begin
  ...
  Parent := Text.Panel1;
end;
Этот код тоже прекрасно будет работать и метки появятся на форме.

Цитата:
Сообщение от Gad99
Что конкретно нужно сделать что бы задумка сработала, обявлять массив глобальным ???
Я не знаю, какая у вас была задумка про массив, поэтому не могу ничего определенного ответить. Если вы хотели где-то в программе обращаться к меткам по индексу в массиве - то, да, нужно сделать массив либо глобальной переменной, либо членом класса.
Но если вы будете искать метки по имени, то массив вам вообще не нужен. Поиск, строго говоря, работает, конечно, дольше прямого обращения, но вряд ли вы создадите столько меток, чтобы это стало заметным.

Вы бы написали какую задачу-то пытаетесь решить? Может и не нужен там массив совсем, а мы тут мучаемся.
Ответить с цитированием
  #11  
Старый 15.03.2008, 17:23
Gad99 Gad99 вне форума
Новичок
 
Регистрация: 21.02.2008
Адрес: мурманск
Сообщения: 72
Репутация: 10
По умолчанию

Компилятор ругается вот на это:
l := Text.FindComponent('MyLabel1');
Incompatible TLabel и TComponent
Ответить с цитированием
  #12  
Старый 15.03.2008, 17:29
Rosenkrantz Rosenkrantz вне форума
Активный
 
Регистрация: 04.12.2007
Адрес: Москва
Сообщения: 234
Версия Delphi: Delphi 7
Репутация: 40
По умолчанию

Ну да, это я приведение типов забыл поставить. Вот так нужно:
Код:
l := TLabel(Text.FindComponent('MyLabel1'));
А ругается потому, что FindComponent возвращает объект класса TComponent, который в иерархии классов VCL стоит до TLabel. Такое присвоение, согласно правил ООП является недопустимым. После приведения типов компилятору становится понятно, каким образом он должен выполнить присвоение.
Ответить с цитированием
  #13  
Старый 15.03.2008, 17:32
Gad99 Gad99 вне форума
Новичок
 
Регистрация: 21.02.2008
Адрес: мурманск
Сообщения: 72
Репутация: 10
По умолчанию

У меня тема дипломной работы "Разработка конкретной обучающей программы"

Создаю текстовый файл с методическим материалом откудава текст буду загружать в эти самые TLabel, количество которых будет зависеть от количества текста.
Ответить с цитированием
  #14  
Старый 15.03.2008, 17:40
Rosenkrantz Rosenkrantz вне форума
Активный
 
Регистрация: 04.12.2007
Адрес: Москва
Сообщения: 234
Версия Delphi: Delphi 7
Репутация: 40
По умолчанию

Ну так и загружайте текст сразу при создании метки, зачем к ней второй раз-то обращаться? Там же где создаете, напишите "Caption := ...".
Ответить с цитированием
  #15  
Старый 15.03.2008, 17:45
Gad99 Gad99 вне форума
Новичок
 
Регистрация: 21.02.2008
Адрес: мурманск
Сообщения: 72
Репутация: 10
По умолчанию

Просто помимо мет.материала сначало будет название темы, предмета ну и т.д.
чтото
l := TLabel(Text.FindComponent('MyLabel1'));
возвращает NIL, при этом компонент на фрейме появляется и имеет имя MyLabel1

Последний раз редактировалось Gad99, 15.03.2008 в 17:56.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 17:47.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter