Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
1 / 1 / 0
Регистрация: 28.10.2012
Сообщений: 168
1

Обращение к объекту не по индексу, а по имени

27.12.2015, 10:59. Просмотров 2037. Ответов 21
Метки нет (Все метки)


Не знаю как словами описать, лучше пример приведу:
Delphi
1
2
3
4
5
6
7
8
9
10
  type
 
    TButtons = class
     Name:string;
     List:TList<TSpeedButton>;
     constructor New(NewName:string);
    end;
 
 var
   PF_Buttons:TList<TButtons>;
Смысл в том, что мы создаём класс, добавляем его в Лист PF_Buttons, в каждом классе есть список динамически созданных кнопок в "List:TList<TSpeedButton>;"

Далее идёт обращение, допустим:
Delphi
1
PF_Buttons[0].List[0].Down:=true;
Соответственно хочется обращаться не по индексу PF_Buttons[индекс], а как то по имени, т.к. индексов будет дофига, и код становится не читаемым. на много лучше, если бы было PF_Buttons[имя]. Думаю тут ничего не сделать, но может я чего то не знаю)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.12.2015, 10:59
Ответы с готовыми решениями:

Обращение к объекту в зависимости от имени, передаваемого в функцию
Добрый день. У меня есть форма с TDataGrid и несколькими TImage. Есть процедура, которая...

Обращение к компоненту по индексу
Помогите а как можно обратиться к компоненту frxDBDataset1&quot;Имя поля в таблице access&quot; по индексу...

Обращение к объекту родителю
Здравствуйте, у меня вот такая ситуация: Я создал два класса: type TClass1 = class ...

Обращение к объекту не по полю Name.
Ситуация такова: на форме есть шесть компонентов типа TShape(Shape1...Shape6). Как скопировать в...

__________________
Помогаю в написании студенческих работ здесь.
21
2646 / 2269 / 278
Регистрация: 24.12.2010
Сообщений: 13,725
27.12.2015, 11:23 2
TMyButtonList = TDictionary<String, TSpeedButton>;
List: TMyButtonList;
1
1 / 1 / 0
Регистрация: 28.10.2012
Сообщений: 168
27.12.2015, 12:33  [ТС] 3
А можно пример, как добавить кнопку и потом как к ней обратиться ( к любому параметру, например текст кнопки).
До этого было
Delphi
1
2
3
4
5
6
7
8
 
PF_Buttons.Add(TButtons.New('Stack'));
for i := 0 to SLDelimited.Count-1 do
 begin
  PF_Buttons[1].List.Add(TSpeedButton.Create(MF.P12));
  и т.д.
  и потом обращение
  PF_Buttons[0].List[0].Down:=true;
Добавлено через 39 минут
Кажется понял, что к чему, если в итоге не получиться, напишу.
0
2646 / 2269 / 278
Регистрация: 24.12.2010
Сообщений: 13,725
27.12.2015, 12:35 4
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
TMyButtons = class(TComponent)
protected
   function GetButtonByName(AName: String): TSpeedButton;   
public
   constructor Create(AOwner: TComponent; AName: String);
   function AddButton(NewName:string): TSpeedButton;
   property ButtonByName[AName: String]: TSpeedButton read  GetButtonByName;
end;
..
 
constructor TMyButtons.Create(AOwner: TComponent; AName: String);
begin
  inherited Create(AOwner);
  Name := AName;
end;
 
function TMyButtons.AddButton(AName:string): TSpeedButton;
begin
  Assert(Trim(AName) <> '', 'Не задано имя объекта');
  try   
    Result := TSpeedButton.Create(Self);
    Result.Name := AName;
  except
    Result.Free;
    raise;
  end;
end;
 
function TMyButtons.GetButtonByName(AName: String): TSpeedButton;   
begin
  Result := FindComponent(AName) as TSpeedButton;
end;
..
 
MyButtons := TMyButtons.Create(nil, 'MyButtonsObject');
MyButtons.AddButton('blabla');
MyButtons.ButtonByName['blabla'].Down := True;
0
1 / 1 / 0
Регистрация: 28.10.2012
Сообщений: 168
27.12.2015, 12:43  [ТС] 5
Сделал так:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
unit Unit2;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Generics.Collections, Vcl.StdCtrls,
  Vcl.Buttons;
 
type
  TForm2 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
  TButtons = class
    List:Tlist<TSpeedButton>;
    Constructor New();
  end;
 
 TButtonList = TDictionary<String, TButtons>;
 
 
 
var
  Form2: TForm2;
  List: TButtonList;
 
implementation
 
{$R *.dfm}
 
{ TButtons }
 
constructor TButtons.New();
begin
 List:=Tlist<TSpeedButton>.Create;
end;
 
procedure TForm2.Button1Click(Sender: TObject);
var But:TButtons;
i:integer;
begin
But:=TButtons.New;
for i := 0 to 5 do
 begin
  But.List.Add(TSpeedButton.Create(Form2));
  But.List[i].Parent:=Form2;
  But.List[i].Name:='PF_Position'+inttostr(i);
  But.List[i].Caption:=inttostr(i);
  But.List[i].Height:=25;
  But.List[i].Width:=35;
  But.List[i].Top:=5;
  But.List[i].Left:=35*i+2;
  But.List[i].GroupIndex:=1;
  But.List[i].Tag:=i;
 end;
 
 List.Add('Position',But);
 
 Memo1.Lines.Add(List['Position'].List[0].Caption);
 
end;
 
procedure TForm2.FormCreate(Sender: TObject);
begin
  List:=TButtonList.Create;
end;
 
end.
Добавлено через 52 секунды
но я думаю ты другое имел ввиду)
0
2646 / 2269 / 278
Регистрация: 24.12.2010
Сообщений: 13,725
27.12.2015, 14:13 6
Я имел ввиду что применение дженериков в твоем случае мало чем оправдано.
0
1 / 1 / 0
Регистрация: 28.10.2012
Сообщений: 168
27.12.2015, 14:56  [ТС] 7
А можно не для посвящённых? Поиск по форуму дал
"Дженерик - это шаблон кода для конкретной задачи (Generic - сгенерированный код)", но от этого ясно не стало.
0
2646 / 2269 / 278
Регистрация: 24.12.2010
Сообщений: 13,725
27.12.2015, 15:00 8
Ну ты же сам их и использовал, объявив класс
TList<TSpeedButton>

Это и есть использование дженериков - шаблонов обобщенного программирования
1
1 / 1 / 0
Регистрация: 28.10.2012
Сообщений: 168
27.12.2015, 15:15  [ТС] 9
Понял. Чтобы до конца понять, а почему "мало чем оправдано"?
Извини за глупые вопросы, я в программировании не профи, а понять общую картину хочется.
0
2646 / 2269 / 278
Регистрация: 24.12.2010
Сообщений: 13,725
27.12.2015, 15:18 10
Цитата Сообщение от artyoms Посмотреть сообщение
почему "мало чем оправдано"?
Потому что атрибут Name уже встроен в объекты класса TComponent, равно как и поиск в списке по этому атрибуту.
1
1 / 1 / 0
Регистрация: 28.10.2012
Сообщений: 168
30.12.2015, 08:17  [ТС] 11
Из того кода, что привёл ранее, если к словарю добавить ещё список кнопок(с другими Caption), и запросить Caption любой кнопки из первого списка, то он почему то выводит Caption кнопки из второго списка.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
unit Unit2;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Generics.Collections, Vcl.StdCtrls,
  Vcl.Buttons;
 
type
  TForm2 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
  TButtons = class
    List:Tlist<TSpeedButton>;
    Constructor New();
  end;
 
 TButtonList = TDictionary<String, TButtons>;
 
 
 
var
  Form2: TForm2;
  List: TButtonList;
 
implementation
 
{$R *.dfm}
 
{ TButtons }
 
constructor TButtons.New();
begin
 List:=Tlist<TSpeedButton>.Create;
end;
 
procedure TForm2.Button1Click(Sender: TObject);
var But:TButtons;
i:integer;
begin
But:=TButtons.New;
for i := 0 to 5 do
 begin
  But.List.Add(TSpeedButton.Create(Form2));
  But.List[i].Parent:=Form2;
  But.List[i].Name:='PF_Position'+inttostr(i);
  But.List[i].Caption:=inttostr(i);
  But.List[i].Height:=25;
  But.List[i].Width:=35;
  But.List[i].Top:=5;
  But.List[i].Left:=35*i+2;
  But.List[i].GroupIndex:=1;
  But.List[i].Tag:=i;
 end;
List.Add('Position',But);
 
But.List.Clear;
 
for i := 0 to 5 do
 begin
  But.List.Add(TSpeedButton.Create(Form2));
  But.List[i].Parent:=Form2;
  But.List[i].Name:='PF_Window'+inttostr(i);
  But.List[i].Caption:=inttostr(i*10);
  But.List[i].Height:=25;
  But.List[i].Width:=35;
  But.List[i].Top:=30;
  But.List[i].Left:=35*i+2;
  But.List[i].GroupIndex:=1;
  But.List[i].Tag:=i;
 end;
 List.Add('Window',But);
 
 Memo1.Lines.Add(List['Position'].List[1].Caption);
 Memo1.Lines.Add(List['Window'].List[1].Caption);
end;
 
procedure TForm2.FormCreate(Sender: TObject);
begin
  List:=TButtonList.Create;
end;
 
end.
0
2646 / 2269 / 278
Регистрация: 24.12.2010
Сообщений: 13,725
30.12.2015, 08:30 12
Какой-то бардак у тебя творится со списками.

Выкинь вообще класс TButtons и пользуй вот этот:

TButtonListsNamedList = TDictionary<String, TList<TSpeedButton>; // именованый список списков кнопок

Его вполне достаточно для решения задачи в том виде , в каком ты ее представил.
1
1 / 1 / 0
Регистрация: 28.10.2012
Сообщений: 168
30.12.2015, 09:21  [ТС] 13
Да, класс тут это бред, удалил его. Но проблема осталась. В мемо1 добавляется 2 строки '10';

"// именованый список списков кнопок" да, все верно, именно это я и хотел (в простом варианте)

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
unit Unit2;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Generics.Collections, Vcl.StdCtrls,
  Vcl.Buttons;
 
type
  TForm2 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
  TButtonList = TDictionary<String, TList<TSpeedButton>>;
 
var
  Form2: TForm2;
  List:TButtonList;
 
implementation
 
{$R *.dfm}
 
{ TButtons }
 
 
procedure TForm2.Button1Click(Sender: TObject);
var But:TList<TSpeedButton>;
i:integer;
begin
But:=TList<TSpeedButton>.Create;
for i := 0 to 5 do
 begin
  But.Add(TSpeedButton.Create(Form2));
  But[i].Parent:=Form2;
  But[i].Name:='PF_Position'+inttostr(i);
  But[i].Caption:=inttostr(i);
  But[i].Height:=25;
  But[i].Width:=35;
  But[i].Top:=5;
  But[i].Left:=35*i+2;
  But[i].GroupIndex:=1;
  But[i].Tag:=i;
 end;
List.Add('Position',But);
 
But.Clear;
 
for i := 0 to 5 do
 begin
  But.Add(TSpeedButton.Create(Form2));
  But[i].Parent:=Form2;
  But[i].Name:='PF_Window'+inttostr(i);
  But[i].Caption:=inttostr(i*10);
  But[i].Height:=25;
  But[i].Width:=35;
  But[i].Top:=30;
  But[i].Left:=35*i+2;
  But[i].GroupIndex:=1;
  But.List[i].Tag:=i;
 end;
 List.Add('Window',But);
 
 Memo1.Lines.Add(List['Position'].List[1].Caption);
 Memo1.Lines.Add(List['Window'].List[1].Caption);
end;
 
procedure TForm2.FormCreate(Sender: TObject);
begin
  List:=TButtonList.Create;
end;
 
end.
Добавлено через 6 минут
Смысл в том, что при запуске программы, весь её интерфейс создаётся динамически. Есть несколько листов кнопок со своими задачами, и чтобы не создавать под каждую группу кнопок отдельный лист, я захотел их обобщить в 1 лист, с поиском по названию листов.
0
3568 / 3040 / 819
Регистрация: 29.08.2013
Сообщений: 20,274
Записей в блоге: 2
30.12.2015, 09:26 14
а почему не использовать массив для хранения кнопок?
0
1 / 1 / 0
Регистрация: 28.10.2012
Сообщений: 168
30.12.2015, 09:36  [ТС] 15
Ты имеешь ввиду создать двумерный массив? Я тоже сначала так сделал, но это оказалось немного не удобно, т.е. куча индексов, допустим от 0 до 10, и в коде по ним становиться немного трудно ориентироваться. Поэтому я и решил спросить на форуме - хотелось что то типо [имя списка][номер кнопки].Параметр.

Добавлено через 1 минуту
А если ты имеешь ввиду заменить TList<TSpeedButton> на массив, то по моему TList тот же самый одномерный массив, только с большим функционалом.
0
3568 / 3040 / 819
Регистрация: 29.08.2013
Сообщений: 20,274
Записей в блоге: 2
30.12.2015, 09:57 16
artyoms, а почему двумерный?
0
2646 / 2269 / 278
Регистрация: 24.12.2010
Сообщений: 13,725
30.12.2015, 10:01 17
Цитата Сообщение от artyoms Посмотреть сообщение
Да, класс тут это бред, удалил его.
Где удалил ?
Опять в коде та же хренотень с List
0
1 / 1 / 0
Регистрация: 28.10.2012
Сообщений: 168
30.12.2015, 13:42  [ТС] 18
Удалил класс:
Delphi
1
2
3
4
 TButtons = class
    List:Tlist<TSpeedButton>;
    Constructor New();
  end;
Сейчас у меня:
1. Создали словарь
2. В обработчике кнопки: создали лист TList<TSpeedButton>, заполнили его кнопками, добавили лист к словарю:
Delphi
1
ButtonList.Add('Position',But);
Вывод данных:
Delphi
1
2
 Memo1.Lines.Add(ButtonList['Position'][1].Caption);
 Memo1.Lines.Add(ButtonList['Window'][1].Caption);
Добавлено через 3 часа 21 минуту
qwertehok, я подумал [номер листа с кнопками][индекс кнопки]
0
3568 / 3040 / 819
Регистрация: 29.08.2013
Сообщений: 20,274
Записей в блоге: 2
30.12.2015, 13:48 19
Цитата Сообщение от artyoms Посмотреть сообщение
я подумал [номер листа с кнопками][индекс кнопки]
а что у вас за листы с кнопками?
куда столько?
0
1 / 1 / 0
Регистрация: 28.10.2012
Сообщений: 168
30.12.2015, 13:53  [ТС] 20
qwertehok, для создание интерфейса при старте программы.

Добавлено через 3 минуты
Кажется я понял:
Когда мы добавляем в словарь
Delphi
1
 TButtonList = TDictionary<String, TList<TSpeedButton>>;
список кнопок:
Delphi
1
ButtonList.Add('Position',But);
добавляются не сами листы с кнопками, а ссылки на них?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.12.2015, 13:53

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Обращение по имени и индексу
Ребята, ткните носом, как реализовать следующее: Есть список объектов Items. namespace...

Обращение к объекту по имени
В ходе скрипта генерируется какое-то количество объектов img с name вида n1,n2 и т.д. Я хочу...

Обращение к объекту по имени
Такая ситуация: Есть много listbox'ов и в один прекрасный момент когда нажимается кнопка TButton на...

Обращение к объекту не зная его имени
Есть у нас объект tefal в объекте machines, и у него есть метод run(); Зная название объекта...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.