Mehrere Formulare in Lazarus

1. Zwei Formulare

Wir erstellen eine Popup-Funktion mit Form1 (Hauptformular) und Form2 (Popup-Fenster)

1. Schritt-für-Schritt Anleitung

  1. Neues Projekt erstellen, ziehe einen Button1 auf Form1, setze Caption = Open Form2 und erzeuge das OnClick-Ereignis (du kannst einfach doppelt auf den Button im Formulardesign klicken, um das Klickereignis schnell anzulegen);
  2. Über das obere Menü File → New Form ein zweites Formular Form2 erstellen;
  3. Auf Form2 einen Button1 platzieren, Caption = Close vergeben und das zugehörige OnClick-Ereignis erstellen;
  4. Tastenkürzel zum Wechseln zwischen Formularen: Shift+F12 Formularliste aufrufen / F12 zwischen Design- und Codeansicht umschalten;
  5. Unit2 in Unit1 einbinden: Füge Unit2 im Bereich interface uses hinzu.

Unit1 (Hauptformular)

Zwei wichtige Stellen sind zu beachten: Unit2; // Einbindung von Unit2

Zweitens rufen wir im Klick-Handler das zweite Fenster als modales Dialogfenster auf: Form2.ShowModal; // Modales Öffnen von Form2

unit Unit1;

{$mode objfpc}{$H+}

interface

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

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; // Modales Öffnen von Form2
end;

end.

Unit2 (Unterformular)

So fügst du das zweite Formular zum Projekt hinzu

Nach dem Hinzufügen erscheint ein neuer Reiter im Editor

Einer für den Quellcode des Hauptfensters, einer für den Code von Form2

Um Form2 zu bearbeiten, wähle Unit2 aus und drücke F12, dann öffnet sich die Designansicht von Form2

Füge wie in den vorherigen Lektionen einen Button hinzu, setze seine Beschriftung auf Close und implementiere die Schließfunktion. Das hast du bereits gelernt, du kannst es selbst ausprobieren.

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; // Schließe das aktuelle Form2
end;

end.

2. Kernunterschied zwischen Show und ShowModal (Vergleichsbeispiel)

Oberfläche anpassen

Füge zwei Buttons auf Form1 hinzu:

  • btnShow: Caption = Show
  • btnShowModal: Caption = ShowModal
// Nicht-modales Fenster mit Show
procedure TForm1.btnShowClick(Sender: TObject);
begin
  Form2.Show;
  ShowMessage('Form2 wurde geöffnet, das Hauptformular bleibt bedienbar');
end;

// Modales Fenster mit ShowModal
procedure TForm1.btnShowModalClick(Sender: TObject);
begin
  Form2.ShowModal;
  ShowMessage('Dieser Hinweis erscheint erst, wenn Form2 geschlossen wurde');
end;Code-Sprache: JavaScript (javascript)

Erläuterung der Unterschiede

  1. Show (nicht-modal)
  • Der Code läuft sofort weiter, nachdem das Unterfenster geöffnet wurde;
  • Das Hauptformular bleibt verschiebbar und alle anderen Buttons sind anklickbar;
  • Entspricht Form2.Visible := True;, das Fenster wird automatisch nach vorne geholt.
  1. ShowModal (modales Dialogfenster)
  • Die Codeausführung pausiert, bis das Unterfenster geschlossen wird;
  • Das Hauptformular ist gesperrt und kann nicht bedient werden;
  • Es handelt sich um eine Funktion, mit deren Rückgabewert ModalResult du prüfen kannst, wie das Fenster geschlossen wurde.

Kurz zusammengefasst: Bei einem modalen Fenster musst du zuerst das Unterfenster schließen, bevor du wieder mit dem Hauptfenster arbeiten kannst. Bei einem nicht-modalen Fenster kannst du beide Fenster gleichzeitig bedienen.

3. Gegenseitiger Aufruf von Formularen: Fehler bei zyklischen Einbindungen beheben

Anforderung: Form1 öffnet Form2, Form2 öffnet Form1
Wenn du beide Units gegenseitig im Bereich interface uses einbindest, entsteht ein Fehler durch zyklische Abhängigkeit. Lösung: Platziere die Einbindung im Abschnitt 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; // Einbindung hier platzieren
{$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; // Gegenseitige Einbindung im Implementationsbereich
{$R *.lfm}

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

4. Werte zwischen Formularen übergeben (Beispiel mit öffentlichen Member-Variablen)

Funktion: Beim Öffnen des Unterfensters vom Hauptformular wird ein Zähler hochgezählt, das Unterfenster kann die Anzahl der Öffnungen anzeigen

Öffentliche Ganzzahlvariable in Unit2 definieren

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
  public
    Count: Integer; // Öffentliche Variable, auf die Unit1 zugreifen kann
  end;

Zähler inkrementieren beim Klick auf den Button in Unit1

procedure TForm1.Button1Click(Sender: TObject);
begin
  Inc(Form2.Count); // Zähler um 1 erhöhen
  Form2.ShowModal;
end;Code-Sprache: JavaScript (javascript)

Anzeige der Öffnungsanzahl in Unit2

procedure TForm2.Button1Click(Sender: TObject);
begin
  ShowMessage('Dieses Formular wurde '+IntToStr(Count)+' Mal geöffnet');
end;Code-Sprache: JavaScript (javascript)

Empfehlung zur sauberen Programmierung: Vermeide nach Möglichkeit globale oder öffentliche Variablen, nutze stattdessen Properties zur Wertübergabe.

5. Dynamische Erstellung von Formularen

Ohne automatisch generierte globale Form-Variable des Projekts arbeiten

Methode 1: Dynamische Instanz des entworfenen Form2

  1. Öffne die Datei Project.lpr und entferne die Zeile Application.CreateForm(TForm2, Form2);
  2. Code für den Button auf Form1:
procedure TForm1.Button1Click(Sender: TObject);
var
  frm2: TForm2;
begin
  frm2 := TForm2.Create(nil); // Manuelle Erstellung der Instanz
  frm2.ShowModal;
  FreeAndNil(frm2); // Speicher freigeben, um Speicherlecks zu vermeiden
end;Code-Sprache: JavaScript (javascript)

Methode 2: Vollständige Generierung eines Formulars per Code (ohne vorheriges Design)

Beim Klick auf den Button wird ein komplett neues Fenster mit integriertem Schließbutton erstellt

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); // Eigenes Klickereignis für dynamischen Button
  public
  end;

var Form1: TForm1;

implementation
{$R *.lfm}

procedure TForm1.DynamicBtnClick(Sender: TObject);
begin
  ShowMessage('Das dynamische Fenster wird bald geschlossen');
  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 := 'Dynamisch erstelltes Formular';

  // Button erstellen, Eigentümer ist MyForm – der Button wird automatisch beim Schließen des Fensters zerstört
  MyBtn := TButton.Create(MyForm);
  MyBtn.SetBounds(10,10,200,30);
  MyBtn.Caption := 'Fenster schließen';
  MyBtn.Parent := MyForm;
  MyBtn.OnClick := @DynamicBtnClick;

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

Meldung „Choose Debug Information format“ erscheint

Einfach das passende Debug-Format auswählen, dann läuft alles normal.

Mehrere Formulare in Lazarus

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert