2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Передача массива на обработчик клика по кнопке (Delphi)
Сообщение05.03.2015, 20:40 
Аватара пользователя


27/03/14
1091
Суть моей программы такова, нужно просто вывести одномерный массив и потом посчитать сумму нечетных элементов. Но это просто, у меня вопрос в другом. Дело в том, что мы теперь работаем не в консольном режиме, а в режиме application. Чтобы вывести массив и посчитать сумму нечетных элементов, я сделал две кнопки: на одну завязал вывод массива, а на другой хочу завязать вывод суммы. Чтобы как-то передать массив из обработчика одной кнопки на другой, я создал тип
Код:
TMatrix: array of integer;
Но процедуры обработчиков кликов по кнопкам не принимают записи вида
Код:
procedure TForm1.Button1Click( Sender: TObject; Var a:TMatrix );

Говорят
Код:
Declaration of 'Button1Click' differs from previous declaration

Я не понимаю, почему так. И тем более не понимаю, как мне ещё передать массив в обработчик другой кнопки.

 Профиль  
                  
 
 Re: Делфи
Сообщение05.03.2015, 21:17 
Заслуженный участник
Аватара пользователя


01/08/06
3136
Уфа
Вам нужно где-то объявить массив. Список формальных параметров метода — негодное место для этого. С помощью этой записи вы всего лишь объявляете, что метод TForm1.Button1Click требует этот параметр. Но объявлять (т.е., проще говоря, определять для него место) нужно по-другому. Например, в качестве локальной переменной:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  a: TMatrix;
...

При таком объявлении массив будет "жить" только внутри метода TForm1.Button1Click, снаружи его просто не будет существовать. Внутри метода можете его заполнить и вывести.
Можно вынести его определение за пределы методов, тогда он будет глобальной переменной. Она будет жить, пока жива Ваша программа, и "видна" в пределах модуля (ниже места, где объявлена):
Код:
var
  a: TMatrix;
procedure TForm1.Button1Click...

Т.е. её можно будет где-нибудь в другом месте заполнить или использовать. Или можно объявить в классе формы, выше по тексту, в том месте, где видите комментарий { Public declarations }, тогда переменная будет полем класса формы Form1 (т.е. частью этой формы), будет жить, пока та живёт и будет видна везде, где видна форма. Этот вариант предпочтительнее. Думаю, пока вам достаточно информации для размышления.

А Дельфи ругается, потому что объявление обработчика событий (т.е. набор параметров TForm1.Button1Click) нельзя менять, он так устроен.

Ну и ещё по мелочи замечание, TMatrix — не очень удачное название для типа одномерного массива. Лучше TArray или уж TVector.

 Профиль  
                  
 
 Re: Передача массива на обработчик клика по кнопке (Delphi)
Сообщение05.03.2015, 21:23 
Заслуженный участник
Аватара пользователя


04/09/14
5288
ФТИ им. Иоффе СПб
fronnya в сообщении #986113 писал(а):
Суть моей программы такова, нужно просто вывести одномерный массив и потом посчитать сумму нечетных элементов.

Что-то молчат программисты, поэтому влезу, а знающие, если что, поправят. Вы, видимо, впервые в жизни столкнулись с объектно ориентированным программированием. Оно не такое, как процедурное. Кнопка это объект класса TButton, класс этот предопределен в Delphi и так просто написать Sender: TObject; Var a:TMatrix нельзя. Надо либо создать свой класс, прародителем которого будет TButtom, либо передать значение через внешнюю переменную, видимую обеим кнопкам (читайте "область видимости переменных"). Я бы класс создал, это интересней и поучительней, но геморроя существенно больше.
О, опередили.

 Профиль  
                  
 
 Re: Передача массива на обработчик клика по кнопке (Delphi)
Сообщение05.03.2015, 21:23 
Заслуженный участник


02/08/11
7013
fronnya в сообщении #986113 писал(а):
Я не понимаю, почему так.
Потому что обработчик клика по кнопке вызываете на вы сами где-то в коде, а вызывает кнопка - а она-то ничего не знает ни о каких массивах и не в состоянии ничего вразумительного с этим сделать.
fronnya в сообщении #986113 писал(а):
И тем более не понимаю, как мне ещё передать массив в обработчик другой кнопки.
Объявите массив как переменную (поле, филд) в TForm1, за пределами всех обработчиков. Тогда все функции/процедуры (методы) в TForm1, в том числе обработчики кликов по кнопкам, получат к нему доступ.

 Профиль  
                  
 
 Re: Передача массива на обработчик клика по кнопке (Delphi)
Сообщение05.03.2015, 21:29 
Аватара пользователя


27/03/14
1091
Понимаете, мне нужно передать выведенный массив, вывожу я его нажатием на кнопку. Иначе нельзя, условие задания не позволяет.

 Профиль  
                  
 
 Re: Передача массива на обработчик клика по кнопке (Delphi)
Сообщение05.03.2015, 21:49 
Заслуженный участник


06/07/11
5627
кран.набрать.грамота
Ну вот, опоздал :mrgreen:
worm2 в принципе все правильно написал, но если копнуть глубже, то проблема ваша - в непонимании основ языка. Скорее всего, вы учили его по не самым хорошим книгам, а то и вообще перешли с паскаля, потому что "там все то же самое" :wink: Для полноты знаний порекомендую книгу Марко Кэнту "Delphi 7 для профессионалов".
Если вкратце, то события работают так. Событие - это поле класса процедурного типа. Для вызова и обработки событий используется примерно такой код:
Код:
type
TOnButtonClick = procedure (Sender: TObject) of object;
...
class TCustomButton (<не помню, кто там у него предок ;)>)
  private
    FOnButtonClick: TOnButtonClick;
    procedure SomeBehaviorProc;
  public
    property OnButtonClick: TOnButtonClick read FOnButtonClick write FOnButtonClick;
  end;

...
implementation

procedure TCustomButton.SomeBehaviorProc;
begin
...
  if FOnButtonClick <> nil then
     FOnButtonClick(Self);
...
end;
Здесь FOnButtonClick - свойство класса, которое хранит ссылку на процедуру обработки. Когда вы в IDE создаете форму и обработчик клика, а потом запускаете программу на выполнение, в эту переменную помещается адрес вашей процедуры TForm1.Button1Click - так программа узнает, что делать при клике (Это назначение скрыто глубоко в недрах библиотеки VCL, но подобную операцию легко прописать руками). Это к вопросу
fronnya в сообщении #986113 писал(а):
Но процедуры обработчиков кликов по кнопкам не принимают записи вида
Код:
procedure TForm1.Button1Click( Sender: TObject; Var a:TMatrix );

Говорят
Код:
Declaration of 'Button1Click' differs from previous declaration

Я не понимаю, почему так.
Поле FOnButtonClick ждет на вход адрес процедуры с определенной сигнатурой, а вы суете ему совсем другую процедуру.
На вопрос
fronnya в сообщении #986113 писал(а):
И тем более не понимаю, как мне ещё передать массив в обработчик другой кнопки.
в общем случае ответить сложнее, потому как истинно православная архитектура ПО - это густой дремучий лес, и предела совершенству там тоже нет. Для простоты в учебном проекте можно писать так:
Код:
Class TForm1 (TCustomForm)
  private
    FMyArray: TMyArray;
  public
    procedure Output;
    procedure Calculate;
end;

implementation

procedure TForm1.Output;
begin
// тут выводите
end;

procedure TForm1.Calculate;
begin
// тут вычисляете
end;
А уже вызов этих процедур засовываете в обработчики кликов.
Если какие слова непонятны или на ругательства похожи - вы спрашивайте, не стесняйтесь.

-- 05.03.2015, 22:53 --

fronnya в сообщении #986128 писал(а):
Понимаете, мне нужно передать выведенный массив
Нет, вам это не нужно :wink: Ну в том смысле, что передать массив так, как хотите вы - не единственный и даже не лучший способ решения.

-- 05.03.2015, 22:59 --

amon в сообщении #986124 писал(а):
Что-то молчат программисты
Ничего себе у вас запросы, да на эту тему целый трактат можно написать, а вы хотите, чтобы за 40 минут после создания топика вам уже ответ дали :wink: Да тут людей, писавших на делфи, по пальцам одной руки пересчитать можно.

P. S. ТСу рекомендую читать блог http://www.gunsmoker.ru/ - наверно, лучший русскоязычный блог о Delphi и один из лучших о программировании вообще.

 Профиль  
                  
 
 Re: Передача массива на обработчик клика по кнопке (Delphi)
Сообщение05.03.2015, 22:45 
Заслуженный участник
Аватара пользователя


04/09/14
5288
ФТИ им. Иоффе СПб
rockclimber в сообщении #986139 писал(а):
Ничего себе у вас запросы
Надо же было оправдаться за лазанье по чужим огородам ;)

 Профиль  
                  
 
 Re: Передача массива на обработчик клика по кнопке (Delphi)
Сообщение05.03.2015, 23:44 
Заслуженный участник


02/08/11
7013
fronnya в сообщении #986128 писал(а):
Понимаете, мне нужно передать выведенный массив, вывожу я его нажатием на кнопку. Иначе нельзя, условие задания не позволяет.
Куда передать, зачем передать? Приведите условие что ль.

 Профиль  
                  
 
 Re: Передача массива на обработчик клика по кнопке (Delphi)
Сообщение06.03.2015, 09:19 


24/05/09

2054
1. Объявить массив глобальным - тогда его будет видно везде.
2. Объявить массив в классе формы - его будет видно во всех обработчиках прерываний формы.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group