MDI Многодокументный интерфейс со вкладками

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

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

MDI Многодокументный интерфейс со вкладками

Сообщение blacksirius » 18.04.2010 22:13:45

я хочу сделать приложение, у которого будут свои независимые дочерние окна или формы, но для этого нужно возможности MDI. Я знаю что что Lazarus не поддерживает MDI. И компонент MultiDoc меня не устроил некоторыми мелочами. Я решил попробовать сделать Многодокументный интерфейс со вкладками. Но негде не могу найти описание как правильно такое сделать. Мне нужно что бы вкладка добавлялась со своими элементами, на вкладке был крестик для закрытия вкладки, в меню "окна" добавлялося название открытого окна для быстрого перехода, и самое главное что бы оно работало и под виндовсом и под линуксом(Ubuntu).
На форуме везде идет рассказы про то что очень много тем для решение похожей задачи как моя, но я не нашёл не одной темы.
Помогите решить этот вопрос....
Пожалуйста, или опишите как оптимально реализовать такое, или если уж столько много тем сошли меня на них, или описания вне форума.
Аватара пользователя
blacksirius
новенький
 
Сообщения: 16
Зарегистрирован: 18.04.2010 18:43:49
Откуда: UA, Николаев

Re: MDI Вкладками

Сообщение Mr.Smart » 18.04.2010 22:27:24

В виндас вкладки с крестиком у вас не получаться.
А вообще сейчас доделали механизм фреймов. Смотрите в эту сторону.
Добавление наименования в заголовок и всё остальное делается только ручками :wink:
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: MDI Многодокументный интерфейс со вкладками

Сообщение blacksirius » 18.04.2010 22:43:26

вообще думаю кто то встречался с задачей сделать MDI приложение, как из этого выходили??
Последний раз редактировалось blacksirius 18.04.2010 23:51:34, всего редактировалось 1 раз.
Аватара пользователя
blacksirius
новенький
 
Сообщения: 16
Зарегистрирован: 18.04.2010 18:43:49
Откуда: UA, Николаев

Re: MDI Многодокументный интерфейс со вкладками

Сообщение Mr.Smart » 18.04.2010 23:46:00

Сталкивался, выходил методом создания вкладок. Создавал новую вкладку и перенаправлял паренты контролов. Проще контролы на на отдельной форме создавать на родителе типа TPanel, а после менять их на допустим TTabSheet.
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: MDI Многодокументный интерфейс со вкладками

Сообщение blacksirius » 19.04.2010 08:29:21

всетаки решил реализовать на TFrame, но мне нужно придумать процедуру которая динамически будет создавать фрейм
Код: Выделить всё
FR:=TFrEngineer.Create(self);
  FR.Parent:=self;
  FR.Align:=alClient;

вот экземпляр вызывающий фрейм, но как возможно процедуру придумать при условии что меняется только FrEngineer
Аватара пользователя
blacksirius
новенький
 
Сообщения: 16
Зарегистрирован: 18.04.2010 18:43:49
Откуда: UA, Николаев

Re: MDI Многодокументный интерфейс со вкладками

Сообщение alaken » 19.04.2010 10:46:44

мне интересно по разбираться с компонентом TPageControl чтобы его улучшить, довести до функционала TRzPageControl (в нем есть кнопка закрытия таба) из пакета Raize для Delphi

Добавлено спустя 1 час 19 минут 44 секунды:
blacksirius писал(а):всетаки решил реализовать на TFrame, но мне нужно придумать процедуру которая динамически будет создавать фрейм
Код: Выделить всё
FR:=TFrEngineer.Create(self);
  FR.Parent:=self;
  FR.Align:=alClient;

вот экземпляр вызывающий фрейм, но как возможно процедуру придумать при условии что меняется только FrEngineer

возможно что никак, задачу нужно ставить по другому
alaken
постоялец
 
Сообщения: 221
Зарегистрирован: 18.02.2010 09:02:13

Re: MDI Многодокументный интерфейс со вкладками

Сообщение blacksirius » 19.04.2010 14:15:46

у меня возникла идея создавать фреймы в динамическом масиве и для вкладок взять шапку от TTabControl
Код: Выделить всё
var
  FR:array of TFrame;
  WindowsN:integer;

вызываю фрейм, и создаю вкладку:
Код: Выделить всё
procedure TFGlobal.MCategoryClick(Sender: TObject);
begin
  TCWindows.TabIndex:=TCWindows.Tabs.Add('Категории оборудований');
  SetLength(FR,WindowsN+1);
  FR[TCWindows.TabIndex]:=TFrCategory.Create(nil);
  FR[TCWindows.TabIndex].Parent:=PContent;
  FR[TCWindows.TabIndex].Align:=alClient;
end;

сделал переключение между вкладками
Код: Выделить всё
procedure TFGlobal.TCWindowsChange(Sender: TObject);
var i:integer;
begin
  for i:=0 to WindowsN-1 do
      if TCWindows.TabIndex<>i
         then  FR[i].Visible:=False
         else FR[TCWindows.TabIndex].Visible:=True;
end;

и закрываю их
Код: Выделить всё
procedure TFGlobal.FormDestroy(Sender: TObject);
var i:integer;
begin
  for i:=0 to WindowsN-1 do FR[i].Destroy;//Выгружаем все окна
end;


только вот переключение между табами не работает, думаю модуль TFrame не имеет параметра visible. И при закрытие приложения в режиме отладки появляется ошибка, и появляется только после того как объявляю массив из TFrame-ов
Код: Выделить всё
Проект Сервисный центр вызвал класс исключения 'External:SIGSEGV'

может у когото есть идеи, как такое довести до ума
Аватара пользователя
blacksirius
новенький
 
Сообщения: 16
Зарегистрирован: 18.04.2010 18:43:49
Откуда: UA, Николаев

Re: MDI Многодокументный интерфейс со вкладками

Сообщение Padre_Mortius » 19.04.2010 14:23:15

забыли про
Код: Выделить всё
if not assigned(TFrame) then


Сам использую следующий вариант использования TabControlChange (при небольшом количестве фреймов)
Код: Выделить всё
procedure TMainForm.TabControl1Change(Sender:TObject);
var
  Index: byte;
begin
  Index := TabControl1.TabIndex;
  case Index of
    0 : begin
          if assigned(CurrListFrame) then FreeAndNil(CurrListFrame);
          if assigned(ParamFrame) then FreeAndNil(ParamFrame);
          FirstPageShow;
        end;
    1 : begin
          if assigned(ReportFrame) then FreeAndNil(ReportFrame);
          if assigned(ParamFrame) then FreeAndNil(ParamFrame);
          SecondPageShow;
        end;
    2 : begin
          if assigned(ReportFrame) then FreeAndNil(ReportFrame);
          if assigned(CurrListFrame) then FreeAndNil(CurrListFrame);
          ThirdPageShow;
        end;
  end;
end;
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Re: MDI Многодокументный интерфейс со вкладками

Сообщение blacksirius » 19.04.2010 14:35:01

нашол такой вариант
Код: Выделить всё
private
myframe : array of TIWFrame;
end;

Код: Выделить всё
SetLength(myframe, qryMaster.RecordCount);
For I := 0 to qryMaster.RecordCount-1 do
begin
myframe := TIWFrame.Create(self);
with myframe do
begin
Name := 'frames' + IntToStr(I);

но у людей тоже проблема при доступе к фреймам
Аватара пользователя
blacksirius
новенький
 
Сообщения: 16
Зарегистрирован: 18.04.2010 18:43:49
Откуда: UA, Николаев

Re: MDI Многодокументный интерфейс со вкладками

Сообщение Padre_Mortius » 19.04.2010 14:38:55

Может стоит проверить на существование фрейм (создавать только если не существует) и уничтожить при открытии нового фрейма?
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Re: MDI Многодокументный интерфейс со вкладками

Сообщение blacksirius » 19.04.2010 14:40:17

Padre_Mortius писал(а):забыли про
Код: Выделить всё
if not assigned(TFrame) then


для каких целей этот момент нужен?? и куда его добавлять если использовать??

Добавлено спустя 2 минуты 6 секунд:
Padre_Mortius
для начала нужно сделать что бы работало, а после можно добавить проверку на копии фреймов
Аватара пользователя
blacksirius
новенький
 
Сообщения: 16
Зарегистрирован: 18.04.2010 18:43:49
Откуда: UA, Николаев

Re: MDI Многодокументный интерфейс со вкладками

Сообщение Padre_Mortius » 19.04.2010 14:49:14

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

  TVCSForm = class(TForm)
    TabControl1:TTabControl;
    procedure FormClose(Sender:TObject;var CloseAction:TCloseAction);
    procedure FormCreate(Sender:TObject);
    procedure TabControl1Change(Sender:TObject);
  private
    { private declarations }
  public
    { public declarations }
    QSFrame: TQSFrame;
    MSFrame: TMSFrame;
  end;

var
  VCSForm: TVCSForm;

implementation

{ TVCSForm }

procedure TVCSForm.FormCreate(Sender:TObject);
begin
  TabControl1.TabIndex := 0;
  if not Assigned(QSFrame) then
  begin
    QSFrame:=TQSFrame.Create(self);
    QSFrame.Parent:=TabControl1;
  end;
end;

procedure TVCSForm.FormClose(Sender:TObject;var CloseAction:TCloseAction);
begin
  if Assigned(QSFrame) then FreeAndNil(QSFrame);
  if Assigned(MSFrame) then FreeAndNil(MSFrame);
end;

procedure TVCSForm.TabControl1Change(Sender:TObject);
var
  Index: Byte;
begin
  Index := TabControl1.TabIndex;
  case Index of
     0: begin
          if Assigned(MSFrame) then FreeAndNil(MSFrame);
          if not Assigned(QSFrame) then
           begin
             QSFrame:=TQSFrame.Create(self);
             QSFrame.Parent:=TabControl1;
           end;
        end;
     1: begin
          if Assigned(QSFrame) then FreeAndNil(QSFrame);
          if not Assigned(MSFrame) then
           begin
             MSFrame:=TMSFrame.Create(self);
             MSFrame.Parent:=TabControl1;
           end;
        end;
     2: begin

        end;
   end;
end;

Кусок модуля из рабочего проекта. Используется компонент TabControl для переключения между фреймами. Код работает без ошибок
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Re: MDI Многодокументный интерфейс со вкладками

Сообщение alaken » 19.04.2010 15:35:51

в вашем коде происходит не переключение а пересоздание экземпляров фреймов, и если вдруг были введены данные в поля фрейма (TEdit) то после переключения они исчезнут, для переключения достаточно оперировать параметром TFrame.Parent и все введенные данные остануться

TFrame.Parent := Nil - Скрывает фрейм
TFrame.Parent := TWinControl(ParentControl) - Отображает фрейм
alaken
постоялец
 
Сообщения: 221
Зарегистрирован: 18.02.2010 09:02:13

Re: MDI Многодокументный интерфейс со вкладками

Сообщение Brainenjii » 19.04.2010 15:47:19

Вот простенький пример фреймов в TNotebook'е - http://pastebin.com/UkdqCw76
Создаются фреймы только при переходе на ранее не открытую вкладку

Кстати, "вкладчатый" интерфейс зовётся TDI
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: MDI Многодокументный интерфейс со вкладками

Сообщение blacksirius » 19.04.2010 18:48:55

я нашол вариант выхода из проблемы используя
Код: Выделить всё
type
TFGlobal = class(TForm)
    NWindows: TNotebook;

в переменных:
Код: Выделить всё
var
  FR:TFrame;

получаем процедуру вызова новой вкладки
Код: Выделить всё
procedure TFGlobal.MCategoryClick(Sender: TObject);
var i,t:integer;
begin
  t:=-1;
  for i:=0 to NWindows.PageCount-1 do
    if NWindows.Page[i].Caption='Категории оборудований' then t:=i;
  if t>-1
    then NWindows.PageIndex:=t
    else
      begin
        NWindows.PageIndex:=NWindows.Pages.Add('Категории оборудований');
        NWindows.Page[NWindows.PageIndex].BorderWidth:=2;
        FR:=TFrCategory.Create(self);
        FR.Parent:=NWindows.ActivePageComponent;
        FR.Align:=alClient;
        FR.Name:='FrameWindows'+inttostr(NWindows.PageIndex);
      end;
end;

решил закрывать через всплывающие меню, только как его привязать к шапкам вкладки??
Аватара пользователя
blacksirius
новенький
 
Сообщения: 16
Зарегистрирован: 18.04.2010 18:43:49
Откуда: UA, Николаев

След.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru