Несколько модулей .pas с одной формой

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

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

Несколько модулей .pas с одной формой

Сообщение PSergey » 25.01.2017 09:32:12

Здравствуйте.
Подскажите пожалуйста как объединить в проект несколько модулей .pas с одной формой.
Не удобно работать с одним модулем получается длинным и не читабельным.
Мануала толково описывающий не нашел :(
пример:
Unit1
Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption:='Test_1';
end;
end.

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

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button2Click(Sender: TObject);
begin
  Label1.Caption:='Test_2';
end;

end.

Подскажите, что не так и что надо сделать чтоб можно было добавлять Unit3, Unit4, ...
PSergey
незнакомец
 
Сообщения: 1
Зарегистрирован: 24.01.2017 18:47:29

Re: Несколько модулей .pas с одной формой

Сообщение Лекс Айрин » 28.01.2017 09:57:46

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


Код: Выделить всё
implementation
uses about, LazFileUtils, LConvEncoding, Tree;
{$R *.lfm}
{$I mainfunction.inc}   



А если хочешь расцепить по нескольким юнитам, то придется использовать фреймы, но тут придется распределять и объявления и реализации.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Несколько модулей .pas с одной формой

Сообщение zub » 28.01.2017 10:11:24

Лекс Айрин
Это вредные советы. include совсем не для этого.

PSergey
то что ты описываешь не реализуемо (да и ненужно), описание одной формы должно быть в одном юните.
Но GUI логику и "бизнес" логику нужно разносить по разным юнитам, причем в идеале чтоб одно от другого не зависело
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Несколько модулей .pas с одной формой

Сообщение Лекс Айрин » 28.01.2017 10:21:02

zub писал(а):include совсем не для этого.


Тем не менее, практически так его используют разработчики Lazarus. А может, и самого FPC.

Понятное дело, что тупо делить неудачная идея. Однако, отделить длинные описания списка констант и/или реализацию второстепенного более-менее связанного кода можно. Кстати, если подумать, то можно inc-файлы потихоньку преобразовывать в полноценные модули.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Несколько модулей .pas с одной формой

Сообщение zub » 28.01.2017 10:45:04

Использование чегото должно быть обосновано, а не тупо можно так.
Нормально include использовать для выноса плотформенно зависимых вещей - путем подстановки директорий при компиляции включатся разные файлы. Либо наоборот, для "централизованного" для выноса какихто общих вещей - потом исправил в одном месте, оно автоматом подтянулось во все места где вставлено. При этом надо помнить что вставленное через include одно и тоже в разных местах стьановится разными сущьностями.
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Несколько модулей .pas с одной формой

Сообщение Лекс Айрин » 28.01.2017 11:01:52

zub писал(а):Если такой инклуд вставлен в одном месте - то он ненужен.


Не стоит забывать о том, что кроме чисто программных штучек есть еще и удобство навигации по коду для самого программиста. А вот тут разделение интерфейса и реализации по разным файлам вполне себя оправдывает. Взять хотя бы Сишных программистов. Плюс, длинный список определений типов и констант очень сильно неудобен, если он в начале файла. Так что его по любому лучше отделить.

zub писал(а):Если такой инклуд вставлен в разных местах, то все эти константы\типы\коды становятся разными сущьностями и загаживают пространства имен, рано или поздно такой разраб наступит на эти грабли.


А это уже зависит от программиста. В любом случае, можно разделить пространства имен для системной и пользовательской областей.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Несколько модулей .pas с одной формой

Сообщение zub » 28.01.2017 12:02:26

>>есть еще и удобство навигации по коду для самого программиста.
Проще не делать больших юнитов чем городить инклуды на ровном месте. Получилось чтото огромное - думай как его разделить, а не как сделать вид что ты его разделил))
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Несколько модулей .pas с одной формой

Сообщение Лекс Айрин » 28.01.2017 12:11:57

zub, не спорю. Но как разделить форму с десятком элементов и сотней методов? Хорошо если удастся часть превратить в компонент... а если ну никак?
Или создавать динамически?
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Несколько модулей .pas с одной формой

Сообщение zub » 28.01.2017 12:16:00

>>десятком элементов
нестрашно. Но формошлепать тоже с умом надо - колво контролов унифицировать и минимизировать

>>сотней методов
ну тут явно можно оставить тоже с десяток, остальное скинуть в модуль "бизнес" логики
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Несколько модулей .pas с одной формой

Сообщение MysticCoder » 28.01.2017 12:17:12

Можно в OnCreate назначить динамически обработчики событий экземпляру другого класса. по типу:

Код: Выделить всё
Unit unit1;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  Self.OnMouseDown := Helper.FormMouseDown;
end;

Unit HelperUnit;
...
procedure THelper.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Form1.Label.Caption := 'test2';
end;


Но это только обработчики. По идее наоборот, обработчики лучше оставить в юните формы, а логику лучше перенести в другие юниты. Разделить интерфейс и логику.

PSergey писал(а):Не удобно работать с одним модулем получается длинным и не читабельным.


Это ты еще не работал с pas файлами размером в несколько мегабайт, где секцию интерфейсов пролистываешь вниз, а она все не кончается и не кончается :lol:

Могу посоветовать забить на то, что творится в implementation, привести в порядок секцию interface, разделить её на логические части отделенные внятными комментариями типа здесь обработчики событий, здесь вспомогательные функции, здесь еще что то, ну и обернуть эти части регионами, что позволит сворачивать\разворачивать участки кода:
Код: Выделить всё
  TForm1 = class(TForm)
    {$Region Callbacks}
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    {$EndRegion}
  private
    { private declarations }
  public
    { public declarations }
  end;     


в итоге все будет хорошо читабельным, да и навигация относительно удобная будет.
MysticCoder
постоялец
 
Сообщения: 154
Зарегистрирован: 14.09.2013 00:20:28

Re: Несколько модулей .pas с одной формой

Сообщение Лекс Айрин » 28.01.2017 12:24:19

MysticCoder писал(а):Это ты еще не работал с pas файлами размером в несколько мегабайт, где секцию интерфейсов пролистываешь вниз, а она все не кончается и не кончается


Можно, для примера, указать определения импортируемых из системных библиотек функций... или констант... очень "увлекательное" чтиво. (модуль windows)
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Несколько модулей .pas с одной формой

Сообщение Pavia » 28.01.2017 13:05:47

PSergey
Такое не реализуемо в паскале.
Вариант с includa'ми вам уже предложили.
Предложу второй вариант вы можете переписать код, с тем что-бы вынести повторяющийся код в отдельные функции и сложить их в отдельный модуль.
Или выделить объекты и вынести их по разным юнитамё А вот обращение к этим объектом сделать с юнита с формой.
Аватара пользователя
Pavia
постоялец
 
Сообщения: 290
Зарегистрирован: 07.01.2011 12:46:51

Re: Несколько модулей .pas с одной формой

Сообщение Снег Север » 28.01.2017 13:24:53

Как уже написали - одна форма, один .pas файл.
Правильная реализация - в файле с формой должно быть только то, что нужно контролам формы. Все собственные классы и общие процедуры выносятся в другие модули.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2996
Зарегистрирован: 27.11.2007 16:14:47


Вернуться в Lazarus

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

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

Рейтинг@Mail.ru