MDI Многодокументный интерфейс со вкладками
Модератор: Модераторы
- blacksirius
- новенький
- Сообщения: 16
- Зарегистрирован: 18.04.2010 18:43:49
- Откуда: UA, Николаев
MDI Многодокументный интерфейс со вкладками
я хочу сделать приложение, у которого будут свои независимые дочерние окна или формы, но для этого нужно возможности MDI. Я знаю что что Lazarus не поддерживает MDI. И компонент MultiDoc меня не устроил некоторыми мелочами. Я решил попробовать сделать Многодокументный интерфейс со вкладками. Но негде не могу найти описание как правильно такое сделать. Мне нужно что бы вкладка добавлялась со своими элементами, на вкладке был крестик для закрытия вкладки, в меню "окна" добавлялося название открытого окна для быстрого перехода, и самое главное что бы оно работало и под виндовсом и под линуксом(Ubuntu).
На форуме везде идет рассказы про то что очень много тем для решение похожей задачи как моя, но я не нашёл не одной темы.
Помогите решить этот вопрос....
Пожалуйста, или опишите как оптимально реализовать такое, или если уж столько много тем сошли меня на них, или описания вне форума.
На форуме везде идет рассказы про то что очень много тем для решение похожей задачи как моя, но я не нашёл не одной темы.
Помогите решить этот вопрос....
Пожалуйста, или опишите как оптимально реализовать такое, или если уж столько много тем сошли меня на них, или описания вне форума.
В виндас вкладки с крестиком у вас не получаться.
А вообще сейчас доделали механизм фреймов. Смотрите в эту сторону.
Добавление наименования в заголовок и всё остальное делается только ручками
А вообще сейчас доделали механизм фреймов. Смотрите в эту сторону.
Добавление наименования в заголовок и всё остальное делается только ручками
- blacksirius
- новенький
- Сообщения: 16
- Зарегистрирован: 18.04.2010 18:43:49
- Откуда: UA, Николаев
вообще думаю кто то встречался с задачей сделать MDI приложение, как из этого выходили??
Последний раз редактировалось blacksirius 18.04.2010 23:51:34, всего редактировалось 1 раз.
Сталкивался, выходил методом создания вкладок. Создавал новую вкладку и перенаправлял паренты контролов. Проще контролы на на отдельной форме создавать на родителе типа TPanel, а после менять их на допустим TTabSheet.
- blacksirius
- новенький
- Сообщения: 16
- Зарегистрирован: 18.04.2010 18:43:49
- Откуда: UA, Николаев
всетаки решил реализовать на TFrame, но мне нужно придумать процедуру которая динамически будет создавать фрейм
вот экземпляр вызывающий фрейм, но как возможно процедуру придумать при условии что меняется только FrEngineer
Код: Выделить всё
FR:=TFrEngineer.Create(self);
FR.Parent:=self;
FR.Align:=alClient;вот экземпляр вызывающий фрейм, но как возможно процедуру придумать при условии что меняется только FrEngineer
мне интересно по разбираться с компонентом TPageControl чтобы его улучшить, довести до функционала TRzPageControl (в нем есть кнопка закрытия таба) из пакета Raize для Delphi
Добавлено спустя 1 час 19 минут 44 секунды:
возможно что никак, задачу нужно ставить по другому
Добавлено спустя 1 час 19 минут 44 секунды:
blacksirius писал(а):всетаки решил реализовать на TFrame, но мне нужно придумать процедуру которая динамически будет создавать фреймКод: Выделить всё
FR:=TFrEngineer.Create(self);
FR.Parent:=self;
FR.Align:=alClient;
вот экземпляр вызывающий фрейм, но как возможно процедуру придумать при условии что меняется только FrEngineer
возможно что никак, задачу нужно ставить по другому
- blacksirius
- новенький
- Сообщения: 16
- Зарегистрирован: 18.04.2010 18:43:49
- Откуда: UA, Николаев
у меня возникла идея создавать фреймы в динамическом масиве и для вкладок взять шапку от TTabControl
вызываю фрейм, и создаю вкладку:
сделал переключение между вкладками
и закрываю их
только вот переключение между табами не работает, думаю модуль TFrame не имеет параметра visible. И при закрытие приложения в режиме отладки появляется ошибка, и появляется только после того как объявляю массив из TFrame-ов
может у когото есть идеи, как такое довести до ума
Код: Выделить всё
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'может у когото есть идеи, как такое довести до ума
-
Padre_Mortius
- энтузиаст
- Сообщения: 1265
- Зарегистрирован: 29.05.2007 17:38:07
- Откуда: Спб
забыли про
Сам использую следующий вариант использования TabControlChange (при небольшом количестве фреймов)
Код: Выделить всё
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;- blacksirius
- новенький
- Сообщения: 16
- Зарегистрирован: 18.04.2010 18:43:49
- Откуда: UA, Николаев
нашол такой вариант
но у людей тоже проблема при доступе к фреймам
Код: Выделить всё
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); но у людей тоже проблема при доступе к фреймам
-
Padre_Mortius
- энтузиаст
- Сообщения: 1265
- Зарегистрирован: 29.05.2007 17:38:07
- Откуда: Спб
Может стоит проверить на существование фрейм (создавать только если не существует) и уничтожить при открытии нового фрейма?
- blacksirius
- новенький
- Сообщения: 16
- Зарегистрирован: 18.04.2010 18:43:49
- Откуда: UA, Николаев
для каких целей этот момент нужен?? и куда его добавлять если использовать??
Добавлено спустя 2 минуты 6 секунд:
Padre_Mortius
для начала нужно сделать что бы работало, а после можно добавить проверку на копии фреймов
-
Padre_Mortius
- энтузиаст
- Сообщения: 1265
- Зарегистрирован: 29.05.2007 17:38:07
- Откуда: Спб
Код: Выделить всё
{ 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 для переключения между фреймами. Код работает без ошибок
в вашем коде происходит не переключение а пересоздание экземпляров фреймов, и если вдруг были введены данные в поля фрейма (TEdit) то после переключения они исчезнут, для переключения достаточно оперировать параметром TFrame.Parent и все введенные данные остануться
TFrame.Parent := Nil - Скрывает фрейм
TFrame.Parent := TWinControl(ParentControl) - Отображает фрейм
TFrame.Parent := Nil - Скрывает фрейм
TFrame.Parent := TWinControl(ParentControl) - Отображает фрейм
- Brainenjii
- энтузиаст
- Сообщения: 1351
- Зарегистрирован: 10.05.2007 00:04:46
Вот простенький пример фреймов в TNotebook'е - http://pastebin.com/UkdqCw76
Создаются фреймы только при переходе на ранее не открытую вкладку
Кстати, "вкладчатый" интерфейс зовётся TDI
Создаются фреймы только при переходе на ранее не открытую вкладку
Кстати, "вкладчатый" интерфейс зовётся TDI
- blacksirius
- новенький
- Сообщения: 16
- Зарегистрирован: 18.04.2010 18:43:49
- Откуда: UA, Николаев
я нашол вариант выхода из проблемы используя
в переменных:
получаем процедуру вызова новой вкладки
решил закрывать через всплывающие меню, только как его привязать к шапкам вкладки??
Код: Выделить всё
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;
решил закрывать через всплывающие меню, только как его привязать к шапкам вкладки??
