Как создать вторую форму в Lazarus?
Я создала несколько форм. В первой форме я показала вторую (Unit2.Form2.Show). Проблема в том, что я её просто показала и не могу взаимодействовать с её компонентами. Мне нужно при помощи второй формы открыть третью. ShowModal по каким-то причинам не работает. Не знаю, что делать (._.)/
begin if pos(fPassword.Text, b.Text) > 0 then begin Main.Form2.Show; Form1.Hide; end else ShowMessage ('Ooops! Wrong password or password''s field is empty. Try again.'); b.Free; end;
Отслеживать
user176262
задан 22 фев 2018 в 17:20
23 9 9 бронзовых знаков
«ShowModal . не работает.» — у всех работает, а у Вас не работает? Вы считаетe, что кода Unit2.Form2.Show достаточно для ответа на Ваш вопрос?
– user176262
22 фев 2018 в 17:21
Я не поняла, что Вы имеете ввиду. ShowModal не работает в том плане, что на форме, показанной при помощи ShowModal, не работают компоненты. Unit2.Form2.Show мне не помогает, поэтому я и спросила здесь. Если Вы не можете или не хотите мне помочь, пожалуйста, пройдите мимо.
22 фев 2018 в 17:56
Смысл фразы «не работают компоненты» известен только Вам. Я, конечно, могу пройти мимо, но кто тогда Вам объяснит, как плохо Вы задали вопрос?
– user176262
22 фев 2018 в 18:02
«не работают» — это значит не работают. Например, компонент Button1 не открывает третью форму. А компонент Image вообще не показывается на второй форме, хотя Visible := True.
22 фев 2018 в 18:04
Мы продвигаемся вперед семимильными шагами :)! Вы уже приоткрыли завесу тайны, скрывающую Ваш код. Еще немного, и Вы полностью поймете, что мы не видим Ваш экран с кодом и мысли в Вашем мозгу.
TForm/ru
TForm является классом объекта ‘форма’. Все формы, созданные во время разработки, могут быть получены из TForm.
Форма представляет обычное или диалоговое окно, которое формирует интерфейс приложения. Она является контейнером, на котором могут быть размещены другие компоненты, например, кнопки, метки, поля редактирования текста, элементы с изображениями и т.д.
Новый экземпляр класса TForm может быть создан в среде Lazarus с помощью команд File|New. .
Contents
Приложение
При запуске программы главная форма (как и любая другая форма), которая должна быть создана автоматически, фактически так и создается. Создаваемые автоматически формы могут быть выбраны из списка доступных форм в [Project|Project Options|Forms]. Если по какой-либо причине среди перечисленных доступных форм нет формы, которая должна быть создана автоматически, добавьте необходимое имя формы в раздел Uses и строку Application.CreateForm для этой формы.
program PTest; uses Forms, UMainForm, UOtherForm; begin Application.Title:='Test'; RequireDerivedFormResource := True; Application.Initialize(); Application.CreateForm(TMainForm, MainForm); Application.CreateForm(TOtherForm, OtherForm); Application.Run(); end.
Свойства
- Menu — связь с элементом TMainMenu, который будет отображен в верхней части формы во время выполнения программы
- Popupmenu — связь с элементом TPopupMenu, который будет отображен при щелчке правой кнопкой мыши по форме
- PopupParent —
- SessionProperties —
- ActiveControl —
См. также
- Документация по TForm
- Руководство по работе с формами
Две формы
Можно ли как-то скрепить две формы?
Возможно ли сделать так, чтобы две формы перемещались синхронно?
Две формы (циклические ссылки на модули)
Нужен доступ из первой формы к контролам второй, и доступ из второй формы к контролам первой После.
Как можно связать две формы?
в делфи это делается Use Unit ,а как это можно в Лазарусе? заранее спасибо) Добавлено через 16.
Связать две формы для одновременного использования.
Здравствуйте.Подскажите пожалуйста,как связать две формы в делфи. Если прописать юнит1 и юнит2 -.
Почетный модератор
64300 / 47595 / 32743
Регистрация: 18.05.2008
Сообщений: 115,181
Сообщение было отмечено dikoss как решение
Решение
1 2 3 4 5 6 7 8 9 10 11 12 13 14
var Form1: TForm1; implementation uses Unit2; procedure TForm1.Button1Click(Sender: TObject); begin Form1.Hide; Form2.Show; end;
1 2 3 4 5 6 7 8 9 10 11 12 13 14
var Form2: TForm2; implementation uses Unit1; procedure TForm2.Button1Click(Sender: TObject); begin Form2.Hide; Form1.Show; end;
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь
Две формы
Как создать две формы в одной программе, так чтоб когда нажимаешь кнопку на первой появлялась.
Две формы
Доброго вам времени суток. Помогите пожалуйста! Вопрос есть задача: имею 2 формы, на главной.
Две формы в qt.
Подскажите пожалуйста, создал форму mainwindow2.ui и хочу ее открыть через главную форму.
Две формы
Как мне сделать так, чтобы после запуска программы выводилось окно с двумя button`ами и при нажатии.
Или воспользуйтесь поиском по форуму:
Работа с формами Lazarus
Эта статья врядли будет интересна тем, кто раньше программировал в Delphi. Она в большей степени рассчитана на программистов VB, MS Access и других средств быстрой разработки. В каждой системе существуют свои правила и подходы, касающиеся программного открытия экранных форм, а также передачи и возврата пареметров. Вот я и хочу рассказать о том, как это сделано в Lazarus. При этом я предполагаю, что читатель достаточно хорошо понимает принципы ООП и уже знаком с синтаксисом языка Free Pascal.
Открытие форм в модальном режиме
Наиболее очевидным применением программного открытия дополнительной формы является выбор или поиск какого-либо значения в справочнике с последующим возвратом, например, кода найденного элемента в основную форму. Такую форму надо открывать модально, так как нет смысла продолжать выполнение основной программы, пока не сделан выбор и форма не закрыта. Попробуем это реализовать.
В качестве примера создадим новый проект и на главную форму поместим пару полей ввода и кнопок:
unit Unit1; interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Edit1: TEdit; Edit2: TEdit; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private public end; var Form1: TForm1;
В качестве тестовой задачи будем открывать дополнительную форму с полем ввода, в котором первоначально должен содержаться текст из соответствующего поля ввода главной формы. Далее предусмотрим изменение этого текста и возврат обновленного значения в главную форму. Для этого сначала создадим дополнительную форму примерно такого вида:
unit Unit2; interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons; type TForm2 = class(TForm) Button1: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); private function GetTestValue: string; procedure SetTestValue(const AValue: string); public property TestValue: string read GetTestValue write SetTestValue; end; function RunTestForm(const InitialValue: string): string; var Form2: TForm2;
В качестве программного интерфейса для передачи параметра будем использовать свойство TestValue, которое определим в секции public класса формы. Также определим и реализуем более чем очевидные методы для установки и считывание значения свойства, а также обработчик события нажатия на кнопку, в котором свойству формы ModalResult присваивается значение mrOK, что и приводит к закрытию (но не уничтожению!) формы.
Однако, самый большой интерес представляет функция RunTestForm. Как можно заметить, она определена вне класса формы, хотя и в том же модуле. Это может показаться странным программистам VB, где модуль класса полностью отождествляется с самим классом. Как и в Delphi, в Lazarus это не так. Хотя в одном модуле можно определить только одну форму (иначе визуальный дизайнер форм не сможет работать), другие элементы приложения не обязательно реализовывать отдельно. В нашем случае функция RunTestForm содержит код, необходимый для создания формы, передачи ей начального значения поля ввода и возврата отредактированного значения. Очевидно, что RunTestForm по смыслу связана с классом формы, поэтому будет разумно (хотя и вовсе не обязательно) расположить её в модуле формы.
implementation function RunTestForm(const InitialValue: string): string; begin with TForm2.Create(Application) do // Создание экземпляра формы. try TestValue := InitialValue; // Установка начального значения. ShowModal; // Вывод формы на экран в модальном режиме. if ModalResult = mrOK then // Если форма закрыта нажатием кнопки, подтверждающей изменения, result := TestValue // возвращаем изменённое значение. else // Если форма закрыта любым другим способом, т.е. изменения отменены, result := InitialValue; // возвращаем первоначальное значение. finally Free; // Уничтожение экземпляра формы и высвобождение ресурсов. end; end; procedure TForm2.Button1Click(Sender: TObject); begin ModalResult := mrOK; end; function TForm2.GetTestValue: string; begin result := Edit1.Text; end; procedure TForm2.SetTestValue(const AValue: string); begin Edit1.Text := AValue; end; initialization end.
Теперь посмотрим, как использовать всё это в основной форме. Добавим в обработчики событий нажатия на кнопки вызовы функции RunTestForm, в результате чего раздел реализации модуля главной формы приобретёт такой вид:
implementation uses Unit2; procedure TForm1.Button1Click(Sender: TObject); begin Edit1.Text := RunTestForm(Edit1.Text); end; procedure TForm1.Button2Click(Sender: TObject); begin Edit2.Text := RunTestForm(Edit2.Text); end; initialization end.
Вот и всё. Только не забудьте в свойствах проекта удалить дополнитетьную форму из списка автоматически создающихся форм. Теперь можно потестировать, то, что у нас получилось. Запустите программу и понажимайте кнопки на главной форме. Обратите внимание, что пока дополнительная форма присутствует на экране, Вы не можете перевести фокус на какую-либо другую форму, как и положено для модального режима. И наверняка Вы подумаете, что такое поведение не всегда является подходящим. Вот это и обсудим далее.
Открытие форм в немодальном режиме
Итак, для начала определимся, что предназначение, поведение немодальной формы и принципы работы с ней совершенно другие. Прежде всего, немодальные формы не приспособлены для возврата значений, так как после их открытия программа не останавливается в ожидании закрытия формы, а продолжает выполняться. Из-за этого, если не предпринять специальных мер, указатель на открываемую форму будет утерян после завершения работы кода, который её создаёт (в нашем случае — это функция RunTestForm). Так ли это ужасно? В большинстве случаев — нет. Помните, что при создании экземпляра формы в конструктор передавался параметр Application? Так вот: Application — это объект, который представляет всё наше приложение. При таком создании формы он будет помнить о её присутствии, а мы сможем этим воспользоваться. Создадим в главной форме список, который будем заполнять именами форм, открытых в приложении. Основная форма при этом несколько изменится и будет выглядеть примерно так:
unit Unit1; interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Edit1: TEdit; Edit2: TEdit; ListBox1: TListBox; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure ListBox1Click(Sender: TObject); private procedure FillWindowsList; public end; var Form1: TForm1;
Обратите внимание, что мы задекларировали новый метод FillWindowsList, который как раз и выполняет заполнение списка форм приложения. Его реализация не слишком сложна:
procedure TForm1.FillWindowsList; var i: Integer; begin ListBox1.Clear; for i := 0 to Application.ComponentCount - 1 do if Application.Components[i] is TForm then ListBox1.Items.Add((Application.Components[i] as TForm).Caption); end;
Здесь есть некоторый интересный момент. Дело в том, что объект Application содержит единый список всех компонент, которыми владеет, поэтому приходится проверять, что очередной компонент является именно TForm.
Однако, что толку просто выводить список форм. Нужно сделать так, чтобы можно было переключиться на любую из них. В реальном приложении это, конечно, лучше сделать с помощью меню, но код получится несколько более громоздким, поэтому в нашем простом примере во-первых будем использовать список, а во-вторых опустим необходимые в реальном приложении проверки.
procedure TForm1.ListBox1Click(Sender: TObject); var FormName: string; begin FormName := ListBox1.Items[ListBox1.ItemIndex]; (Application.FindComponent(FormName) as TForm).SetFocus; end;
Ниже представлен весь код секции реализации модуля основной формы. Обратите внимание, что вызывая метод RunTestForm мы уже не ждём возвращаемого значения, но зато вызываем процедуру заполнения списка окон приложения.
implementation uses Unit2; procedure TForm1.FillWindowsList; var i: Integer; begin ListBox1.Clear; for i := 0 to Application.ComponentCount - 1 do if Application.Components[i] is TForm then ListBox1.Items.Add((Application.Components[i] as TForm).Caption); end; procedure TForm1.Button1Click(Sender: TObject); begin RunTestForm(Edit1.Text); FillWindowsList; end; procedure TForm1.Button2Click(Sender: TObject); begin RunTestForm(Edit2.Text); FillWindowsList; end; procedure TForm1.ListBox1Click(Sender: TObject); var FormName: string; begin FormName := ListBox1.Items[ListBox1.ItemIndex]; (Application.FindComponent(FormName) as TForm).SetFocus; end; initialization end.
Теперь создадим дополнительную форму, которую будем открывать из главной формы в немодальном режиме. Внешне она ничем не будет отличаться от рассмотренной в предыдущей главе модальной формы, а вот код несколько изменится. Обратите внимание, что свойство TestValue теперь только для записи, а метод RunTestForm стал процедурой вместо функции.
Появилась и новая глобальная переменная — счётчик форм Form2Count. Она понадобится нам, когда создаваемому экземпляру формы мы будем присваивать имя. Все объекты приложения должны иметь уникальные имена, однако LCL об этом никак не заботится, поэтому придётся действовать самостоятельно. Код, связанный с переменной Form2Count достаточно тривиален, поэтому останавливаться на нём не будем.
unit Unit2; interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons; type TForm2 = class(TForm) Button1: TButton; Edit1: TEdit; procedure Button1Click(Sender: TObject); procedure Form2Close(Sender: TObject; var CloseAction: TCloseAction); private procedure SetTestValue(const AValue: string); public property TestValue: string write SetTestValue; end; procedure RunTestForm(const InitialValue: string); var Form2: TForm2; Form2Count: Integer;
Реализация тоже довольно сильно изменилась. Показ формы теперь производится вызовом метода Show, а не ShowModal, поэтому выполнение программы не передаётся в создаваемую форму до её закрытия, а продолжается. О закрытии и освобождении ресурсов теперь должна заботиться сама форма. Для этого в процедуре обработки события закрытия формы мы присвоим переменной CloseAction значение caFree. Нажатие на кнопку теперь вызывает не установку значения ModalResult, а явное обращение к методу Close.
implementation procedure RunTestForm(const InitialValue: string); begin with TForm2.Create(Application) do // Создание экземпляра формы. try TestValue := InitialValue; // Установка начального значения. Inc(Form2Count); // Инкремент счётчика форм. Name := 'MyForm' + IntToStr(Form2Count); // Присвоение форме уникального имени. Show; // Отображение формы. except Free; // Уничтожение экземпляра формы и высвобождение ресурсов только в случае сбоя. end; end; procedure TForm2.Button1Click(Sender: TObject); begin Close; end; procedure TForm2.Form2Close(Sender: TObject; var CloseAction: TCloseAction); begin CloseAction := caFree; end; procedure TForm2.SetTestValue(const AValue: string); begin Edit1.Text := AValue; end; initialization Form2Count := 0; end.
Если Вы не просто читали эту статью, а создавали попутно описанную тестовую программу, самое время её запустить. Только снова не забудьте убрать дополнительную форму из списка автоматически создающихся при старте приложения.