Variable in mehreren Formularen

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Peter
Beiträge: 12
Registriert: So 26. Nov 2006, 19:07

Variable in mehreren Formularen

Beitrag von Peter »

Hallo,

ich habe eine Variable in Unit1(Form1) erstellt und möchte bei Aufruf von Form2 diese übergeben, dort (in Form2, bzw. FormX) verändern und den neuen Wert zurück an Form1/Unit1 übergeben. Vielleicht kann mir Jemand weiterhelfen.

Danke im voraus
Peter

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Beitrag von monta »

Du kannst das mit einer globalen Variable erledigen:

Code: Alles auswählen

{ private declarations }
  public
    { public declarations }
  end; 
 
var
  Form_Updates: TForm_Updates;
  globale_var: Tirgend_ein_typ;    //<<dort muss sie dann hin
 
implementation
wenn du nun die Unit in die Uses-Klausel der anderen einbindest, kannst du auf diese Variable zugreifen.

Wenn du sie nur in einer Procedure brauchst, kannst du sie alternativ auch direkt in der Parameterliste beim Aufruf übergeben:

Code: Alles auswählen

procedure xy (var uebergabe: TTyp)
begin
//...
end;
 
//und dann beim Aufruf einfach die Variable übergeben, bspw. so:
 
procedure von_Form_eins;
var variable:ttyp;
begin
  xy (variable)
  //danach kannst du auf den veränderten wert zugreifen, aber nur aus der aufrufenden Procedure.
end;
begin

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Globale Variablen sollte man heutzutage vermeiden, in dem fall ist es denk ich besser die Variable unter public der jewailigen Form zu deklarieren.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Euklid
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Beitrag von Euklid »

Da kann ich dem Christian nur zustimmen. Das zu beachten ist umso wichtiger, je größer das Projekt.

Wenn du deine Variable im public-Teil deiner Form1 definierst, kannst du sie beispielsweise wie folgt verändern:

Code: Alles auswählen

//...
implementation
uses unit1;  //die Unit deiner Form1
//...
 
procedure TForm1.Button1Click(Sender:TObject);
begin
  Form1.VariablenName:='Hallo Universum!'; //hier übergibst du die Variable
end;

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Beitrag von monta »

Ja, dass ist auch ein beliebtes Streitthema ;)
An Public hab ich gar nicht gedacht, weil ichs eigentlich generell vermeide, sieht natürlich schöner aus, als mein Vorschlag.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Wiso verneidest du es, bei multithread programmierung wie sie in kurzer zeit wichtig werden wird kommst du mit globalen variablen nicht sonderlich weit. Ausserdem optimiert der compiler da schlechter ist halt einfach ne unart.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Peter
Beiträge: 12
Registriert: So 26. Nov 2006, 19:07

Beitrag von Peter »

Danke für Eure Hilfe,

aber sie führen nicht zum Erfolg.
Problem: Ich habe 2 Formulare erstellt (Form1, Form2) wobei ich in Form1 einige Variable definiert habe. Form1 ruft Form2 auf und dort soll die Variable (aus Form1) verändert werden und mit neuem Inhalt an Form1 zurückgegeben werden. Form2 wird aus Form1 mit dem Befehl: 'Form2.show' aufgerufen.

Vielleicht wird das Problem jetzt ersichtlicher.

P.S.: Eine Variable im Public-Teil definieren, wie? var variable : string; geht nicht. Mache ich einen Denkfehler?

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Das Problem ist von anfang an ersichtlich gewesen, und die dir dargebotenen lösungen führen wenn mans richtig macht durchaus beide zum erfolg.

...
private
public
variable : string;
end;
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Peter
Beiträge: 12
Registriert: So 26. Nov 2006, 19:07

Beitrag von Peter »

Leider ist das Problem doch nicht richtig erkannt und die dargebotenen Lösungen führen allesamt nicht zum Erfolg.
Eine Variable ist in Form1 (Unit) im public-bereich erzeugt. Auf diese Variable soll aus Form2 zugegriffen werden, leider kennt Form2 diese Variable nicht. Also: VariableX:= 'Irgendeintext'; führt in Form2 zu einer Fehlermeldung (variable unbekannt), genauso wie der Versuch mit Form1.VariableX:= 'Irgendeintext';
Vielleicht kennt Jemand eine Möglichkeit um eine Adresse an Form2 (in Form von Form2.show(adr...)) zu übergeben.
Trotzdem vielen Dank für alle Tipps und Hilfen.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

VariableX:= 'Irgendeintext'; führt in Form2 zu einer Fehlermeldung
Richtig, weil du nach deiner Aussage die variable in Form1 deklariert hast musst du in Form2 Form1.variableX := 'Irgendwas'; benutzen.
In Form1 nicht
Form1.VariableX:= 'Irgendeintext';
sondern variableX := 'Irgendwas'; dein beispiel sollte aber aucg gehen.

In form2 muss natürlich in der Uses anweisung Form1 mit drin stehen.
Villeicht schaust du dir mal ein Objektpascal tuturial an.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Peter
Beiträge: 12
Registriert: So 26. Nov 2006, 19:07

Beitrag von Peter »

Danke für all Deine Mühen, aber wie zuvor leider ohne Erfolg. Ich hatte in Form2 folgenden Aufruf (wie ich schon beschrieben hatte): Form1.VariableX:= 'Irgendeintext';
Und der Versuch Form1, bzw. unit1 in der uses-Anweisung von Form2 aufzunehmen, wird mit einem Fehler abgebrochen.
Zu einem Objectpascal-Tutorial: ich habe noch keines gefunden, das dieses Problem behandelt.
Ich werde wohl den Umweg über eine Datei gehen müßen.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Quatsch, natürlich geht des villeicth erwähnst du mal den fehler mit dem der eintrag in die uses abgebrochen wird. Auch an alle anderen ICH HAB HIER NE FEHLERMELDUNG hab ich satt man muss schon angeben welche...
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Peter
Beiträge: 12
Registriert: So 26. Nov 2006, 19:07

Beitrag von Peter »

Die Fehlermeldung lautet: Circular unit reference between unit2 and unit1.
Wie einfach war doch Assembler unter DOS.
Danke für Deine Hartnäckigkeit bei meinem Problem.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

du darfst nicht unit2 in der uses von unit1 haben und umgekehrt.
wozu auch.
also nimm unit2 aus der uses von unit1
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Beitrag von monta »

Christian hat geschrieben:du darfst nicht unit2 in der uses von unit1 haben und umgekehrt.
wozu auch.
also nimm unit2 aus der uses von unit1
Also das stimmt so nicht ganz ;), du darfst nur in der ersten Uses im Interface-Teil keine Circularen Bezüge haben.
Wenn du die aber doch brauchst, was ja durchaus sein kann, kannst du die Unit einfach als Uses unter Implementation einbinden und in der Uses-Klausel im Interface löschen.

Code: Alles auswählen

implementation
 
uses main;
 
{ TForm_Updates }
Wenn du es so machst, sind cirkuläre Bezüge sehr wohl erlaubt.

Wiso verneidest du es, bei multithread programmierung wie sie in kurzer zeit wichtig werden wird kommst du mit globalen variablen nicht sonderlich weit. Ausserdem optimiert der compiler da schlechter ist halt einfach ne unart.
Ich meinte nicht, das ich Public-Variablen vermeide. Aber ich bin im Allgemeinen darauf bestrebt, die Variablen direkt weiterzugeben, also nur Lokale Variablen in den Prozeduren/Funktionen zu verwenden.
Und vielleicht nochmal eine Unitweite-Variable, was bis jetzt gelangt hat.
Ist es eigentlich von der Optimierung auch von Gewicht, ob privat im privat-Teil deklariert wird, oder ob man eine Unit-Weite variable im
Implementation-Teil deklariert? Klar fehlt die Referenz zur Form, aber sonst?

Antworten