Difference between revisions of "Form Tutorial/de"

From Free Pascal wiki
Jump to navigationJump to search
Line 60: Line 60:
 
== Verwendung einer zweiten Form ==
 
== Verwendung einer zweiten Form ==
  
Das Tutorial zeigt, wie man mehrere Forms in einem Projekt nutzen kann. Im Beispiel werden nur zwei Formen (Hauptform und Form2) erstellt, für weitere Forms kann man identisch verfahren.
+
Das Tutorial zeigt, wie Sie mehrere Forms in einem Projekt nutzen können. Im Beispiel werden nur zwei Formen (Hauptform und Form2) erstellt, für weitere Forms können Sie analog verfahren.
  
Kongret gibt es eine Hauptform mit einem Button, durch dessen klicken sich die neue Form öffnet. Die neue Form erhält ebenfalls einen Button, durch dessen klicken sich die neue Form wieder schließt und man zur Hauptform zurück gelangt.
+
In diesem Beispiel, erstellen Sie eine Hauptform mit einem Button, durch dessen Klicken sich die neue Form öffnet. Die neue Form erhält ebenfalls einen Button, durch dessen Klicken sich die neue Form wieder schließt und Sie zur Hauptform zurück gelangen.
  
Alle, die das Tutorial [[Form Tutorial/de#Einstieg, die erste GUI-Anwendung| Einstieg, die erste GUI-Anwendung]] durchgearbeitet haben müssten den Code zwischen begin und end von Procedure TForm1.Button1Click löschen. Alle anderen müssten ein neues Projekt (Anwendung) erstellen, einen Button auf der Form ablegen und den OnClick-Eventhandler von diesem Button1 erstellen.  
+
Wenn Sie das Tutorial [[Form Tutorial/de#Einstieg, die erste GUI-Anwendung| Einstieg, die erste GUI-Anwendung]] durchgearbeitet haben müssten Sie den Code zwischen begin und end von Procedure TForm1.Button1Click löschen. Ansonsten müssten Sie ein neues Projekt (Anwendung) erstellen, einen Button auf der Form ablegen und den OnClick-Eventhandler von diesem Button1 erstellen.  
 
<br>
 
<br>
Diesem Button geben wir noch eine andere Caption (sichtbarer Text auf dem Button). Dazu den Button anwählen (einfach einmal anklicken) und im Objektinspektor unter Eigenschaften -> Caption den Text "Form2 öffnen" eingeben.
+
Diesem Button geben Sie noch eine andere Caption (sichtbarer Text auf dem Button). Dazu den Button anwählen (einfach einmal anklicken) und im Objektinspektor unter Eigenschaften -> Caption den Text "Form2 öffnen" eingeben.
  
 
[[Image:Objektinspektor.png]]
 
[[Image:Objektinspektor.png]]
  
  
Unter dem Hauptmenupunkt Datei -> neues Formular können wir nun ein zweites Formular (Form2) dem Projekt hinzufügen. Auf diesem legen wir ebenfalls einen Button (Button1) ab und erstellen den OnClick-Eventhandler von diesem. Die Caption von diesem Button ändern wir analog oben zu "Schließen"
+
Unter dem Hauptmenupunkt Datei -> neues Formular können Sie nun ein zweites Formular (Form2) dem Projekt hinzufügen. Auf diesem legen Sie ebenfalls einen Button (Button1) ab und erstellen den OnClick-Eventhandler von diesem. Die Caption von diesem Button ändern Sie analog oben zu "Schließen"
 
<br>
 
<br>
 
<br>
 
<br>
Jetzt hat das Projekt zwei Forms, welche jeweils mit dem Hauptmenueintrag Projekt -> Formulare (oder Tastenkombination [Shift]+[F12]) ausgewählt und angezeigt werden können. Hilfsweise kann man auch im Quelltexteditor den Reiter der jeweiligen zur Form zugehörigen [[Unit/de| Unit]] auswählen und mit [F12] das entsprechende Formular anzeigen (mit [F12] wechselt man zwischen Quelltexteditor und Formular).
+
Jetzt hat das Projekt zwei Forms, welche jeweils mit dem Hauptmenueintrag Projekt -> Formulare (oder Tastenkombination [Shift]+[F12]) ausgewählt und angezeigt werden können. Hilfsweise können Sie auch im Quelltexteditor den Reiter der jeweiligen zur Form zugehörigen [[Unit/de| Unit]] auswählen und mit [F12] das entsprechende Formular anzeigen (mit [F12] wechselt man zwischen Quelltexteditor und Formular).
  
  
Im Quelltexteditor gehen wir jetzt auf die zur Form1 zugehörige [[Unit/de| Unit]] (Unit1) und fügen der Uses-Clause "Unit2" hinzu:
+
Im Quelltexteditor gehen Sie jetzt auf die zur Form1 zugehörige [[Unit/de| Unit]] (Unit1) und fügen der Uses-Klausel "Unit2" hinzu:
 
<syntaxhighlight>
 
<syntaxhighlight>
 
uses
 
uses
 
   Classes, SysUtils, ... , Unit2;  //wichtig ist dass die einzelnen Units mit einem Komma voneinander getrennt sind  
 
   Classes, SysUtils, ... , Unit2;  //wichtig ist dass die einzelnen Units mit einem Komma voneinander getrennt sind  
                                   //und die Uses-Clause mit einem Semikolon beendet wird
+
                                   //und die Uses-Klausel mit einem Semikolon beendet wird
 
</syntaxhighlight>
 
</syntaxhighlight>
 
Nun ist Unit2 und damit Form2 von der Unit1 aus aufrufbar.
 
Nun ist Unit2 und damit Form2 von der Unit1 aus aufrufbar.
  
  
Als nächstes bearbeiten wir noch die OnClick-Events von den Buttons der jeweiligen Form:
+
Als nächstes bearbeiten Sie noch die OnClick-Events von den Buttons der jeweiligen Form:
 
<syntaxhighlight>
 
<syntaxhighlight>
 
unit Unit1;
 
unit Unit1;
Line 103: Line 103:
 
end;  
 
end;  
 
</syntaxhighlight>
 
</syntaxhighlight>
Jetzt kann man das Projekt starten und von Form1 mittels Buttonklick Form2 öffnen.
+
Jetzt können Sie das Projekt starten und von Form1 mittels Buttonklick Form2 öffnen.
 
 
  
 
== Zwei Forms, die sich gegenseitig aufrufen können ==
 
== Zwei Forms, die sich gegenseitig aufrufen können ==

Revision as of 20:48, 11 May 2014

Deutsch (de) English (en) suomi (fi) 日本語 (ja) 中文(中国大陆)‎ (zh_CN)

Zurück zu den Zusätzlichen Informationen.

Eine kleine Einführung, wie man Forms in Lazarus nutzt.

Was ist ein(e) Form

Das Formular (engl. Form, Klasse TForm) wird auch im Deutschen oft als Form bezeichnet. Die Form stellt ein Fenster oder ein Dialogfeld dar, das die Benutzeroberfläche einer Anwendung bildet. Sie ist der Container, auf dem alle weiteren Komponenten (z.B. Buttons, Labels, Edit-Felder, Images etc.) eingefügt werden.


Einstieg, die erste GUI-Anwendung

Schon nachdem Sie Lazarus erfolgreich installiert haben, wird nach dem Start von Lazarus ein neues Projekt mit einer leeren Form erstellt. Ansonsten können Sie unter dem Hauptmenueintrag Projekt -> Neues Projekt -> Anwendung eine neue GUI Anwendung erstellen.

NeuesProjekt.png


NeuesProjekt1.png


Jetzt haben Sie schon ein neues, funktionstüchtiges Projekt mit einem Formular erstellt:

Form1 Designmodus.png


Um das neu erstellte Projekt zu starten, können Sie einfach die Taste [F9] drücken oder mit der Maus auf das Hauptmenu-Symbol Start.png klicken (oder Hauptmenü: Start -> Start). Das Projekt wird nun im Normalfall kompiliert und gestartet.

Es passiert nichts wirklich aufregendes, die Form (Form1) verändert jedoch geringfügig ihr Aussehen und wird die Punkte vom Raster-Gitter (Hilfe für Positionierung einzelner Komponenten) verlieren (solange die Gitterpunkte sichtbar sind, wissen Sie auch, dass Sie sich noch im Designmodus befinden):

Form1 Designmodus.png -> Form1 Runmodus.png


Als nächstes legen Sie ein TButton auf der Form ab. Dieser soll später das Öffnen einer zweiten Form ermöglichen:

  • Unter der Standard-Komponentenpalette den TButton auswählen

TButtonStandardpalette.png

  • auf die Form klicken: Es wird ein Button auf Form1 abgelegt mit dem Namen und Caption "Button1".


Damit dieser Button auch einen Sinn bekommt, müssen Sie diesem mitteilen, dass er etwas tun soll, wenn auf ihn geklickt wird. Dieses Klicken kann man vereinfacht als ein Ereignis (engl. Event) betrachten. Dafür benötigt man Ereignisbehandlungsroutinen (engl. listener, observer, event handler), die nach dem Klick aufgerufen werden. Der Event Handler für ein Mausklick kann recht einfach erreicht werden, indem Sie auf den einfügten Button1 doppelklicken (oder im Objektinspektor -> Button1 -> Reiter Ereignisse -> OnClick auf den Button [...] klicken). Es wird nun im Quelltexteditor eine Procedure TForm1.Button1Click erstellt, die immer aufgerufen wird (zur Laufzeit, nicht im Desingnmodus), wenn Button1 geklickt wird:

NeuesProjekt2.png


Damit die Anwendung nach dem Klick von Button1 etwas zu tun bekommt, fügen Sie einfach zwischen begin und end der Procedure TForm1.Button1Click etwas Code, wie

procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption:='Mein erstes Formular';  //Caption von Form1 wird geändert (Text im Formularkopf)
  //oder
  Button1.Caption:='Hallo';         //Caption vom Button1 wird geändert (angezeigter Text des Buttons)
end;

ein. Jetzt können Sie Ihre Anwendung starten (mit Taste [F9]) und sich freuen...

Verwendung einer zweiten Form

Das Tutorial zeigt, wie Sie mehrere Forms in einem Projekt nutzen können. Im Beispiel werden nur zwei Formen (Hauptform und Form2) erstellt, für weitere Forms können Sie analog verfahren.

In diesem Beispiel, erstellen Sie eine Hauptform mit einem Button, durch dessen Klicken sich die neue Form öffnet. Die neue Form erhält ebenfalls einen Button, durch dessen Klicken sich die neue Form wieder schließt und Sie zur Hauptform zurück gelangen.

Wenn Sie das Tutorial Einstieg, die erste GUI-Anwendung durchgearbeitet haben müssten Sie den Code zwischen begin und end von Procedure TForm1.Button1Click löschen. Ansonsten müssten Sie ein neues Projekt (Anwendung) erstellen, einen Button auf der Form ablegen und den OnClick-Eventhandler von diesem Button1 erstellen.
Diesem Button geben Sie noch eine andere Caption (sichtbarer Text auf dem Button). Dazu den Button anwählen (einfach einmal anklicken) und im Objektinspektor unter Eigenschaften -> Caption den Text "Form2 öffnen" eingeben.

Objektinspektor.png


Unter dem Hauptmenupunkt Datei -> neues Formular können Sie nun ein zweites Formular (Form2) dem Projekt hinzufügen. Auf diesem legen Sie ebenfalls einen Button (Button1) ab und erstellen den OnClick-Eventhandler von diesem. Die Caption von diesem Button ändern Sie analog oben zu "Schließen"

Jetzt hat das Projekt zwei Forms, welche jeweils mit dem Hauptmenueintrag Projekt -> Formulare (oder Tastenkombination [Shift]+[F12]) ausgewählt und angezeigt werden können. Hilfsweise können Sie auch im Quelltexteditor den Reiter der jeweiligen zur Form zugehörigen Unit auswählen und mit [F12] das entsprechende Formular anzeigen (mit [F12] wechselt man zwischen Quelltexteditor und Formular).


Im Quelltexteditor gehen Sie jetzt auf die zur Form1 zugehörige Unit (Unit1) und fügen der Uses-Klausel "Unit2" hinzu:

uses
  Classes, SysUtils, ... , Unit2;  //wichtig ist dass die einzelnen Units mit einem Komma voneinander getrennt sind 
                                   //und die Uses-Klausel mit einem Semikolon beendet wird

Nun ist Unit2 und damit Form2 von der Unit1 aus aufrufbar.


Als nächstes bearbeiten Sie noch die OnClick-Events von den Buttons der jeweiligen Form:

unit Unit1;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.ShowModal;  //Zeigt die Form2 an, der Focus wird auf Form2 gesetzt
end;
unit Unit2;
...
procedure TForm2.Button1Click(Sender: TObject);
begin
  Close;  //Schließt Form2
end;

Jetzt können Sie das Projekt starten und von Form1 mittels Buttonklick Form2 öffnen.

Zwei Forms, die sich gegenseitig aufrufen können

Generell ist es günstig (gutes Programmdesign), wenn von einer Form nicht deren Mainform (Haupt-Formular) aufgerufen wird. Besser ist es, entsprechend vorherigem Beispiel, von einer MainForm aus, immer nachfolgende Forms aufzurufen und durch das Schließen dieser wieder zur MainForm zurückzukehren. Somit entgeht man dem Problem einer zirkulären Unit - Referenz. Dass es theoretisch trotzdem geht, zeige ich hier.

Entweder wir modifizieren die Formulare vom Beispiel Verwendung einer zweiten Form oder es muss ein neues Projekt erstellt werden mit zwei Forms und jeweils einem Button. Caption von Form1.Button1 sollte "Form2 öffnen" lauten, die von Form2.Button1 müsste nach "Form1 öffnen" umgeändert werden.

Diesmal können wir nicht einfach in die vorhandene Uses-Clause von Unit2 (wie im vorherigen Beispiel - im Interfaceteil der Unit) "Unit1" einfügen, da sonst eine zirkuläre Unit-Referenz entstehen würde. "Unit2" müsste somit auch wieder aus der Interface-Uses-Clause von Unit1 entfernt werden.

Statt dessen fügen wir eine Uses-Clause in den Implementation-Teilen der Units ein:

unit Unit1;
...
implementation

uses
  Unit2;  
...
unit Unit2;
...
implementation

uses
  Unit1;  
...

Jetzt ändern wir noch die hinter den OnClick-Events der Buttons befindlichen Eventhandler zu:

unit Unit1;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.Show;  //Zeigt Form2
end;
unit Unit2;
...
procedure TForm2.Button1Click(Sender: TObject);
begin
  Form1.Show;  //Zeigt Form1
end;


Übergabe von Variablen in andere Forms

Entsprechend Beispiel Verwendung einer zweiten Form könnte man im Interface-Teil der Unit "Unit2" eine globale Variable deklarieren. Damit hätte man Zugriff in der Unit1 und Unit2 auf ein und die selbe Variable (da in der Unit1 unter uses die Unit2 mit einbunden wurde, werden alle im Interface-Teil der Unit2 deklarierten Variablen auch in Unit1 nutzbar). Dieses Vorgehen sollte man aber auf ein Minimum beschränken, da man bei größeren Projekten schnell nicht mehr weiss, was die einzelnen Variablen für eine Bedeutung haben bzw. wo man überall darauf zugreift (Fehlerquote erhöht sich).

Besser ist es lokale Variablen zu nutzen, diese als Property in einer Klasse oder hilfsweise als Variable in einer Klasse zu definieren und auf diese zuzugreifen.

Im nachfolgenden Projekt wird per Buttonklick eine zweite Form geöffnet. Dabei wird in der Unit der Hauptform gezählt, wie oft diese zweite Form angezeigt wurde. In dieser zweiten Form kann man sich per Buttonklick zeigen lassen, wie oft sie geöffnet wurde:

Ein neues Projekt mit zwei Forms, jeweils ein Button darauf und deren OnClick-Events auswerten.

Nun im Public-Teil der Klasse TForm2 (Unit2) eine Variable (in diesem Fall eine Konstante, die wir als definierte Variable missbrauchen) vom Typ Integer mit dem Namen Zaehler erstellen:

unit Unit2;
...
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    const Zaehler: Integer = 0;   //hier
  end;

Jetzt noch die Button-Eventhandler entsprechend anpassen:

unit Unit1;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  inc(Form2.Zaehler);  //Bei jedem Aufruf von Form2 den Zähler um 1 erhöhen
  Form2.ShowModal;     //Form2 anzeigen
end;
unit Unit2;
...
procedure TForm2.Button1Click(Sender: TObject);
begin
  ShowMessage('Form2 wurde insgesamt '+IntToStr(Zaehler)+' mal aufgerufen');
end;

Auf diese Weise kann man in Unit1 auf alle in Unit2 öffentlichen (public) Variablen/Properties/Funktionen/Proceduren (allgemein Methoden) zugreifen.


Sonstiges im Umgang mit Forms

Andere Form als MainForm verwenden

Stellt man nach einer Weile fest, dass man lieber eine andere Form oder neue Form zur Ansicht beim Programmstart angezeigt haben will, kann man unter dem Mainmenu Projekt -> Projekteinstellungen -> die Reihenfolge der Formulare ändern:

Projekteinstellungen Formulare.png

Alternativ kann man unter Mainmenu Projekt -> .lpr-Datei anzeigen sich die Projekt.lpr (Pascal-Quelltext des Hauptprogramms) anzeigen lassen und dort einfach die zuerst anzuzeigende Form als erstes erstellen lassen:

program Project1;
...
  Application.CreateForm(TForm2, Form2);  //Form2 wird als erstes erstellt und damit beim Start der Anwendung gezeigt
  Application.CreateForm(TForm1, Form1);


Eigenschaften der Form bei Programmende speichern

Bei manchen Anwendungen ist es schön, wenn die vom User geänderte Einstellungen bezüglich Position und Größe der Form bei Programmende gespeichert werden und bei Programmstart wieder so hergestellt werden. Dafür stellt Lazarus von Haus aus eine recht einfache Möglichkeit mittels TXMLPropStorage oder TIniPropStorage zur Verfügung.

Ein einfaches Beispiel soll die Funktionsweise verdeutlichen:

  • neue Anwendung erstellen (Hauptmenu Projekt -> Neues Projekt -> Anwendung)
  • eine TXMLPropStorage Komponente auf die Form ablegen (Zu finden ist sie auf dem Tab Misc in der Komponentenpalette)

KomponentenpaletteTXMLPropStorage.png

  • im Objektinspektor: XMLPropStorage1 -> FileName auf z.B. "session.xml" setzen
  • im Objektinspektor: Form1 -> SessionProperties bearbeiten (einfach den Button [...] anklicken)
  • nun jeweils die Properties Left;Top;Width;Height von der Komponente Form1 auswählen und den Selected Properties hinzufügen
  • mit OK bestätigen und Projekt starten, die Form in der Größe verändern und verschieben, beim nächsten Start hat es wieder diese Einstellung

Weitere Informationen unter TXMLPropStorage


Form dynamisch erzeugen

Von Lazarus designte Form dynamisch erstellen

Mann muss nicht alle Formulare, die während der Laufzeit einer Anwendung möglicherweise aufgerufen werden, immer bei Programmstart erstellen lassen. Manche Entwickler halten generell nichts davon und löschen den bei Einfügen eines neuen Formulars in ein Projekt automatisch erstellten Code aus der Projekt.lpr sofort heraus. Sobald man z.B. eine Library schreiben will, die ein paar GUIs enthält, kommt man um die dynamische Erstellung von Formularen nicht herum.

Ein Beispiel:

  • neue Anwendung mit zwei Formularen, auf Form1 ein Button (in uses-clause von Unit1, "Unit2" aufnehmen)
  • öffnen der Projekt.lpr (Projekt -> .lpr-Datei anzeigen)
  • löschen der Zeile " Application.CreateForm(TForm2, Form2);"
  • im OnClick-Ereignis von Form1 Button1 folgenden Code einfügen:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2:=TForm2.Create(Nil);  //Form2 wird erstellt
  Form2.ShowModal;            //Form2 wird angezeigt
  FreeAndNil(Form2);          //Form2 wieder freigeben  
end;
  • nun einfach starten


Neue Form dynamisch erstellen

Folgendes Beispiel soll demonstrieren, wie neue Forms per Hand, ohne den Formulardesigner, erzeugt werden können.

Mit einem Buttonklick soll sich eine weitere Form öffnen, die einen Button enthält, bei dessen Klick eine Warnmeldung erscheint, dass sich die Form schließen wird und daraufhin die Form geschlossen wird.

  • neue Anwendung mit einem Formular und einem Button
  • im OnClick-Ereignis von Form1 Button1 folgenden Code einfügen:
procedure TForm1.Button1Click(Sender: TObject);
var
  MyForm: TForm;
  MyButton: TButton;
begin
  MyForm:=TForm.Create(nil);             // Formular erzeugen
  MyForm.SetBounds(100, 100, 220, 150);  // Größe der Form
  MyForm.Caption:='Meine dynamisch erstellte Form';

  MyButton:=TButton.create(MyForm);      // Den Button erstellen, der Owner wird MyForm
  MyButton.Caption:='Schließe meine Form';
  MyButton.SetBounds(10, 10, 200, 30);
  MyButton.Parent:=MyForm;               // Festlegen, auf welcher Form der Button platziert wird

  MyButton.OnClick:=@MyButtonClick;      // Wird gleich noch erstellt...

  MyForm.ShowModal;                      // MyForm anzeigen

  FreeAndNil(MyForm);                    // MyForm (und MyButton) wieder freigeben
end;

Light bulb  Hinweis: Wenn eine Komponente mit einem Owner erzeugt wurde (TButton.Create(Owner: TComponent)), gehört sie dem Owner, der dann dafür zuständig ist,

die Komponente freizugeben. Somit wird MyButton bei der Freigabe von MyForm automatisch mit freigegeben.
  • Jetzt muss noch der Eventhandler von MyButtonClick erstellt werden
  • Dazu im private-Abschnitt der Klasse TForm1 folgende Procedure hineinschreiben und [Strg]+[Shift]+[C] (Codevervollständigung) drücken:
  TForm1 = class(TForm)
...
  private
    { private declarations }
    procedure MyButtonClick(Sender: TObject);
  • und folgenden Code dort einfügen
procedure TForm1.MyButtonClick(Sender: TObject);
begin
  Showmessage('Achtung, meine dynamisch erstellte Form wird geschlossen!');
  if Sender is TButton then
    TForm(TButton(Sender).Parent).Close;
end;
  • nun kann das Projekt kompiliert und gestartet werden

Ein paar Tipps für die manuelle Erzeugung von Bedienelementen


Weitere Informationen

Testen, ob Form existiert




--Michl 15:22, 8 May 2014 (CEST)