Desenvolvimento com múltiplos formulários no Lazarus

1. Dois Formulários

Vamos implementar uma janela pop-up com Form1 (formulário principal) + Form2 (janela pop-up)

1. Passo a Passo

  1. Crie um novo projeto, arraste o Button1 para o Form1, altere Caption = Open Form2 e gere o evento OnClick (você pode clicar duas vezes no botão diretamente no designer do formulário para criar o evento de clique rapidamente);
  2. Acesse o menu superior File → New Form para criar o Form2;
  3. Coloque um Button1 no Form2, defina Caption = Close e gere seu evento OnClick;
  4. Atalhos para alternar formulários: Shift+F12 abrir lista de formulários / F12 alternar visualização designer e código;
  5. Referenciar Unit2 no Unit1: adicione Unit2 dentro da seção interface uses.

Unit1 (Formulário Principal)

Há dois pontos cruciais para atenção: Unit2; // Importar Unit2

O segundo ponto está dentro da função de clique: abrir a segunda janela de forma modal com Form2.ShowModal; // Exibir Form2 de forma modal

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Unit2; // Importar Unit2 

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.ShowModal; // Exibir Form2 de forma modal
end;

end.

Unit2 (Formulário Filho)

Como adicionar o segundo formulário ao projeto

Após adicionar, uma aba extra aparecerá no editor de código

Uma aba contém o código do formulário principal, a outra guarda o código backend do Form2

Para editar o Form2, selecione a aba Unit2 e pressione F12 para abrir sua janela de designer

Adicione um botão, altere seu texto para Close e implemente a lógica de fechamento como visto nas aulas anteriores. Você pode concluir essa parte por conta própria.

unit Unit2;

{$mode objfpc}{$H+}

interface

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

type

  { TForm2 }

  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

var
  Form2: TForm2;

implementation

{$R *.lfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  Close; // Fechar o Form2 atual
end;

end.

2. Diferenças Centrais entre Show e ShowModal (Exemplo Comparativo)

Modificar a Interface

Adicione dois botões no Form1:

  • btnShow:Caption = Show
  • btnShowModal:Caption = ShowModal
// Não modal com Show
procedure TForm1.btnShowClick(Sender: TObject);
begin
  Form2.Show;
  ShowMessage('O Form2 foi aberto, o formulário principal continua interativo');
end;

// Modal com ShowModal
procedure TForm1.btnShowModalClick(Sender: TObject);
begin
  Form2.ShowModal;
  ShowMessage('Essa mensagem só aparece após fechar o Form2');
end;Code language: JavaScript (javascript)

Explicação das Diferenças

  1. Show (Não modal)
  • A execução do código continua imediatamente após abrir o formulário filho;
  • O formulário principal pode ser arrastado e outros botões clicados livremente;
  • Equivale a Form2.Visible := True; e traz a janela automaticamente para frente.
  1. ShowModal (Janela Modal Pop-up)
  • A execução do código é pausada até que o formulário filho seja fechado;
  • O formulário principal é bloqueado e não pode ser manipulado;
  • É uma função que retorna ModalResult para identificar como a janela foi fechada.

Resumo curto: uma janela modal obriga você a fechar o formulário filho antes de interagir com o principal; a não modal permite usar ambas as janelas ao mesmo tempo.

3. Chamadas Mútuas entre Formulários: Resolver Erro de Referência Circular

Requisito: Form1 abre Form2, Form2 abre Form1
Referenciar mutuamente dentro de interface uses causa erro de unidade circular. Solução: Mover as referências para a seção implementation

Unit1

unit Unit1;

interface
uses Forms,StdCtrls;

type
  TForm1=class(TForm)
    Button1:TButton;
    procedure Button1Click(Sender:TObject);
  end;
var Form1:TForm1;

implementation
uses Unit2; // Coloque a referência aqui
{$R *.lfm}

procedure TForm1.Button1Click(Sender:TObject);
begin
  Form2.Show;
end;
end.

Unit2

unit Unit2;

interface
uses Forms,StdCtrls;

type
  TForm2=class(TForm)
    Button1:TButton;
    procedure Button1Click(Sender:TObject);
  end;
var Form2:TForm2;

implementation
uses Unit1; // Referências mútuas ficam na implementação
{$R *.lfm}

procedure TForm2.Button1Click(Sender:TObject);
begin
  Form1.Show;
end;
end.

4. Passar Valores entre Formulários (Exemplo com Variável Membro Pública)

Funcionalidade: incrementar um contador toda vez que o formulário principal abrir o filho; o formulário filho exibe quantas vezes foi aberto

Declarar variável inteira pública no Unit2

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
  public
    Count: Integer; // Variável pública acessível pelo Unit1
  end;

Incrementar contador no clique do botão do Unit1

procedure TForm1.Button1Click(Sender: TObject);
begin
  Inc(Form2.Count); // Contador +1
  Form2.ShowModal;
end;Code language: JavaScript (javascript)

Exibir quantidade de aberturas em pop-up no Unit2

procedure TForm2.Button1Click(Sender: TObject);
begin
  ShowMessage('Esse formulário foi aberto '+IntToStr(Count)+' vezes');
end;Code language: JavaScript (javascript)

Recomendação de padrão de código: minimize o uso de variáveis globais/públicas, prefira passar dados via Property.

5. Criar Formulários Dinamicamente

Sem depender da variável Form global gerada automaticamente pelo projeto

Método 1: Criação dinâmica do Form2 já projetado

  1. Abra o arquivo Project.lpr e exclua a linha Application.CreateForm(TForm2, Form2);
  2. Código do botão no Form1:
procedure TForm1.Button1Click(Sender: TObject);
var
  frm2: TForm2;
begin
  frm2 := TForm2.Create(nil); // Instanciar manualmente
  frm2.ShowModal;
  FreeAndNil(frm2); // Liberar memória para evitar vazamentos
end;Code language: JavaScript (javascript)

Método 2: Formulário gerado totalmente por código (sem projeto prévio)

Clicar no botão gera uma janela nova completa com botão de fechar embutido

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure DynamicBtnClick(Sender: TObject); // Manipulador de clique para botão dinâmico
  public
  end;

var Form1: TForm1;

implementation
{$R *.lfm}

procedure TForm1.DynamicBtnClick(Sender: TObject);
begin
  ShowMessage('Fechando o formulário criado dinamicamente');
  TForm(TButton(Sender).Parent).Close;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  MyForm: TForm;
  MyBtn: TButton;
begin
  MyForm := TForm.Create(nil);
  MyForm.SetBounds(100,100,220,150);
  MyForm.Caption := 'Formulário Gerado Dinamicamente';

  // Criar botão com proprietário MyForm, destruído automaticamente ao fechar a janela
  MyBtn := TButton.Create(MyForm);
  MyBtn.SetBounds(10,10,200,30);
  MyBtn.Caption := 'Fechar Janela';
  MyBtn.Parent := MyForm;
  MyBtn.OnClick := @DynamicBtnClick;

  MyForm.ShowModal;
  FreeAndNil(MyForm);
end;
end.

Aparece a caixa “Choose Debug Information format”

Basta configurar o formato de depuração para funcionar normalmente.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *