[erl.] Dynamisch erzeugtes Programm

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
MacWomble
Lazarusforum e. V.
Beiträge: 977
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 19.3 Cinnamon / FPC/Lazarus
CPU-Target: Intel i7 64/32 Bit
Wohnort: Freiburg

[erl.] Dynamisch erzeugtes Programm

Beitrag von MacWomble »

Hallo, kann mir evtl. jemand weiter helfen?
Ich versuche mich gerade an der dynamischen Erstellung einer GUI-Anwendung. Hierbei stellen sich mir zu Anfang zwei Fragen:

1. Geht das nur im MODE Delphi?
2. Das Button-Click-Event funktioniert mit dem remarkten Teil nicht. Was mache ich hier falsch?

Basis ist das Beisliel aus WIKI, damit spiele ich erts mal rum ;-)

Code: Alles auswählen

unit mainform;
 
{$MODE Delphi}{$H+}
 
interface
 
uses Forms, StdCtrls, Classes;
 
type
  TMyForm = class(TForm)
  public
    MyButton: TButton;
    MyEdit: TEdit;
    procedure ButtonClick(ASender: TObject);
    constructor Create(AOwner: TComponent); override;
  end;
 
implementation
 
procedure TMyForm.ButtonClick(ASender: TObject);
begin
  //Edit3.Text := Edit2.Text + ' ' + Edit1.Text;
end;
 
constructor TMyForm.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  //Hint: FormCreate() is called BEFORE Create() !
  //so You can also put this code into FormCreate()
  //(This is not the case when creating components ..)
 
  Position := poScreenCenter;
  Height := 400;
  Width := 400;
 
  VertScrollBar.Visible := False;
  HorzScrollBar.Visible := False;
 
  MyButton := TButton.Create(Self);
  with MyButton do
  begin
    Height := 30;
    Left := 100;
    Top := 100;
    Width := 100;
    Caption := 'Close';
    OnClick := ButtonClick;
    Parent := Self;
  end;
 
  MyEdit := TEdit.Create(Self);
  with MyEdit do
  begin
    Name := 'Edit1';
    left := 120;
    Top := 10;
    Width := 250;
    Parent := Self;
  end;
 
  MyEdit := TEdit.Create(Self);
  with MyEdit do
  begin
    Name := 'Edit2';
    left := 120;
    Top := 40;
    Width := 250;
    Parent := Self;
  end;
 
  MyEdit := TEdit.Create(Self);
  with MyEdit do
  begin
    Name := 'Edit3';
    left := 120;
    Top := 70;
    Width := 250;
    Parent := Self;
  end;
 
  // Erstellen Sie hier noch weitere Komponenten
end;
 
end.
Zuletzt geändert von MacWomble am Mo 27. Jan 2020, 22:05, insgesamt 1-mal geändert.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Warf
Beiträge: 1474
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Dynamisch erzeugtes Programm

Beitrag von Warf »

Versuchs dochmal mit OnClick := @ButtonClick; Dann sollte es auch im Mode ObjFPC gehen :wink:

Ansonsten, solang du die TApplication erstellst sollte das auch so gehen

MacWomble
Lazarusforum e. V.
Beiträge: 977
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 19.3 Cinnamon / FPC/Lazarus
CPU-Target: Intel i7 64/32 Bit
Wohnort: Freiburg

Re: Dynamisch erzeugtes Programm

Beitrag von MacWomble »

Das Onclick geht nun in objectFPC mit @ButtonClick

jedoch findet er die TEdits nicht :-(

Hier noch die ppr:

Code: Alles auswählen

program codegui;
 
{$mode objfpc}{$H+}
 
uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  Interfaces, // this includes the CT adLCL widgetset
  Forms, StdCtrls,
  MainForm;
 
var
  MyForm: TMyForm;
begin
  Application.Initialize;
  Application.CreateForm(TMyForm, MyForm);
  Application.Run;
end
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2281
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.8, FPC 3.0.4)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Dynamisch erzeugtes Programm

Beitrag von m.fuchs »

MacWomble hat geschrieben:jedoch findet er die TEdits nicht :-(


Die gibt es ja auch nicht. Du hast nur das Feld MyEdit, dem du nacheinander drei neu erzeugte TEdit zuweist.
Du müsstest stattdessen deine Edit1, Edit2, Edit3 in die Klassendefinition packen und diese jeweils mit einem erzeugten TEdit füllen.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

MacWomble
Lazarusforum e. V.
Beiträge: 977
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 19.3 Cinnamon / FPC/Lazarus
CPU-Target: Intel i7 64/32 Bit
Wohnort: Freiburg

Re: Dynamisch erzeugtes Programm

Beitrag von MacWomble »

:oops:

Eigentlich logisch - Danke funktioniert!
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

wp_xyz
Beiträge: 3302
Registriert: Fr 8. Apr 2011, 09:01

Re: Dynamisch erzeugtes Programm

Beitrag von wp_xyz »

MacWomble hat geschrieben:jedoch findet er die TEdits nicht :-(

Weil du dreimal ein TEdit erzeugtst, aber jedesmal dieselbe, global innerhalb TMyForm verwendbare Variable MyEdit nimmst. Das erzeugt außerdem ein Speicherleck, weil nur das letzte der drei erzeugten TEdits freigegeben wird.

Nimm einfach drei unterschiedliche Variablen für jedes TEdit:

Code: Alles auswählen

type
  TMyForm = class(TForm)
  public
    MyButton: TButton;
    MyEdit1: TEdit;
    MyEdit2: TEdit;
    MyEdit3: TEdit;
    procedure ButtonClick(ASender: TObject);
    constructor Create(AOwner: TComponent); override;
  end;
 
constructor TMyForm.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  [...]
 
  MyEdit1 := TEdit.Create(Self);
  with MyEdit1 do
  begin
//    Name := 'Edit1';  // Zur Laufzeit erzeugten Komponenten, für die es eine Variable gibt, würde ich keinen Namen geben, sonst bist du dafür zuständig, dass der Name eindeutig ist
    left := 120;
    Top := 10;
    Width := 250;
    Parent := Self;
  end;
 
  MyEdit2 := TEdit.Create(Self);
  with MyEdit2 do
  begin
//    Name := 'Edit2';
    left := 120;
    Top := 40;
    Width := 250;
    Parent := Self;
  end;
 
  MyEdit3 := TEdit.Create(Self);
  with MyEdit3 do
  begin
//    Name := 'Edit3';
    left := 120;
    Top := 70;
    Width := 250;
    Parent := Self;
  end;
end;

Damit geht dann auch der Click-Code des Buttons. Allerdings musst du die richtigen Variablenbezeichnung verwenden - in meinem Beispiel heißen die TEdits MyEdit1, MyEdit2 und MyEdit3, in deinem Click-Code aber Edit1, Edit2 und Edit3:

Code: Alles auswählen

procedure TMyForm.ButtonClick(ASender: TObject);
begin
  MyEdit3.Text := MyEdit2.Text + ' ' + MyEdit1.Text;
end;

Am besten verwendet du "sprechende" Variablenberzeichnungen, die ausdrücken, was in ihnen gespeichert ist. Wenn z.B. MyEdit1 einen Nachnamen, MyEdit2 einen Vornamen und MyEdit3 den vollen Namen enthalten, dann solltest du die Bezeichner NachnameEdit, VornameEdit und VollerNameEdit verwenden, oder vielleicht kürzer: edNachname, edVorname, edVollerName (wobei "ed" verdeutlicht, dass es sich um TEdit-Controls handelt).

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2281
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.8, FPC 3.0.4)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Dynamisch erzeugtes Programm

Beitrag von m.fuchs »

wp_xyz hat geschrieben:Weil du dreimal ein TEdit erzeugtst, aber jedesmal dieselbe, global innerhalb TMyForm verwendbare Variable MyEdit nimmst. Das erzeugt außerdem ein Speicherleck, weil nur das letzte der drei erzeugten TEdits freigegeben wird.

Das Speicherleck dürfte nicht auftreten, da ja alle TEdit mit dem Owner des Forms erzeugt werden. Das räumt sie also automatisch ab.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

wp_xyz
Beiträge: 3302
Registriert: Fr 8. Apr 2011, 09:01

Re: Dynamisch erzeugtes Programm

Beitrag von wp_xyz »

m.fuchs hat geschrieben:Das Speicherleck dürfte nicht auftreten, da ja alle TEdit mit dem Owner des Forms erzeugt werden. Das räumt sie also automatisch ab.

Hast recht.

Antworten