Variable in mehreren Formularen

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
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 »

Wenn du es so machst, sind cirkuläre Bezüge sehr wohl erlaubt.
Wenn du es so macht sind es keine cirkulären bezüge und wenn du der omi die fernbedienung in einem rutsch erklärst weiss sie hinterher ger nix mehr ;)
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:Wenn du es so macht sind es keine cirkulären bezüge und wenn du der omi die fernbedienung in einem rutsch erklärst weiss sie hinterher ger nix mehr ;)


Zirkulär meinte ich ja einfach so als Kreislauf ;)
Aber zweitens stimt natürlich auch ;)

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

Beitrag von Peter »

Ich danke für Eure Mühen, muß aber doch den Weg über eine Datei gehen, da ich jetzt zwar den Inhalt der Variablen nach Form2 bekomme, aber leider nicht mit neuem Inhalt aus Form2 zurück nach Form1 bekomme.
Ich werde mich wohl oder übel doch noch genauer mit C befassen müssen, da ich dort eine Lösung für dieses Problem finden konnte.
Nochmals vielen Dank.

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 »

das muss gehen ;)

Falls du die Variable im Kopf einer Function, Variablen zwischenzeitlich handhabst, musst du noch var davorschreiben, damit nicht in einer Kopie sondern im Original gearbeitet wird.

häng mal deinen Quellcode, also beide Units hier an, oder schick sie per Mail.

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 »

monta hat geschrieben:das muss gehen ;)


Das geht definitiv. Jedenfalls in einigen meiner Projekte.

Der Fehler "Circular unit reference between unit2 and unit1" lässt sich höchstwahrscheinlich wie folgt vermeiden:

Geh mal kurz in deine Form1. Hier gibt es zwei Möglichkeiten, deine unit2 einzubinden:
1. Du schreibt deine Unit2 hinter das "uses" unter "Interface":

Code: Alles auswählen

unit unit1;
 
Interface
 
uses verschiedene, units, unit2;  // <--- 1. Möglichkeit
//...


Ich nehme an, dass du dies so gemacht hast. Daher die mögliche Lösung deines Problems:
Streich die unit2 da raus!

2. Schreibe statt dessen in der unit1 unter "Implementation":

Code: Alles auswählen

//...
Implementation
 
uses unit2;  //<---- 2. Möglichkeit
//...


... und dein Problem müsste behoben sein.

Wenn nicht: Einfach nochmal den dann entstehenden Fehler posten.

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 »

Peter sei mir nicht böse aber wenn du mit Pascal schon nicht klar kommst und so schnell das handtuch wirfst ist c erst recht nichts für dich.
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 »

Ich bin Niemanden Böse, im Gegenteil. Ich bin für ehrliche Meinungen dankbar, nur so kann man es besser machen (auch wenn es schwer fällt). In Assembler war es leicht, Adresse auf den Stack ablegen, Routine aufrufen, Rücksprungadresse holen, Adresse holen und die Rücksprungadresse wieder auf den Stack ablegen, fertig.
Ich danke Euch für Eure Geduld und Hilfe.

Hier sind die Auszüge des Quellcodes (die Variable sollte nur zum Test, ob es auch geht, dienen):

Code: Alles auswählen

1.Unit(Form1):
 
unit mainunit;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons, ExtCtrls, ExtDlgs, varunit1, subunit1, subunit2;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
...
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Image1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    tvar : string;
  end;
 
var
  Form1: TForm1;
  idummy : integer;
 
implementation
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  tvar:= 'Test Variable';
  label1.caption:= tvar;
  Form2.Show;
  label2.caption:= tvar;
end;



Code: Alles auswählen

2.Unit(Form2):
 
unit subunit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Buttons;
 
type
 
  { TForm2 }
 
  TForm2 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form2: TForm2;
 
implementation
uses mainunit;
 
{ TForm2 }
 
procedure TForm2.FormCreate(Sender: TObject);
begin
 
end;
 
procedure TForm2.Button3Click(Sender: TObject);
begin
  Form1.tvar:= 'Ende des Test';
  close;
end;


//Codetags gesetzt, monta ;)

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 »

Hallo Peter!

Folgender Quelltext sollte funktionieren:

unit1:

Code: Alles auswählen

unit Unit1; 
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons,
  StdCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    tvar:string;
  end;
 
var
  Form1: TForm1;
 
implementation
 
uses unit2;
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
 
tvar:= 'Test Variable';
label1.caption:= tvar;
Form2.Show;
 
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  label2.caption:= tvar;
end;
 
initialization
  {$I unit1.lrs}
 
end.


unit2:

Code: Alles auswählen

unit Unit2; 
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, Buttons;
 
type
 
  { TForm2 }
 
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form2: TForm2;
 
implementation
 
uses unit1;
 
{ TForm2 }
 
procedure TForm2.Button1Click(Sender: TObject);
begin
   Form1.tvar:= 'Ende des Test';
close;
end;
 
initialization
  {$I unit2.lrs}
 
end.


Habe ihn eben ausprobiert, der Quelltext funktioniert.

In deinem Quelltext liegt der Fehler in Button1Click der unit1: Wenn du dort die 2. Form aufrufst, fährt der Computer gleichzeitig in button1Click fort. Daher brauchst du noch ein button auf der 1. FOrm.

Obigen Quelltext einfach in ein neues Projekt einfügen. Ausführen. Auf Button1 der 1. Form Klicken, dann auf Button1 der 2. Form und schließlich auf Button2 der 1. Form.

Viele Grüße, Euklid

PS: Verwende am Besten den Quelltexthighlighter von monta, weils besser aussieht ;)

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

Beitrag von Peter »

Habe mich an Deinem Quelltext orientiert (mit Erfolg!!!). Nochmals vielen Dank auch allen Anderen, die sich die Mühe gemacht haben, um mein Problem zu lösen.

Danke nochmals,
viele Grüße
Peter

oldcoder
Beiträge: 4
Registriert: So 10. Dez 2006, 08:41
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Hamburg

Beitrag von oldcoder »

schreibe eine neue Unit, deklariere Deine Globalen Variablen und binde diese Unit in Form1 und Form2 ein. Wähle eindeutige Bezeichner, nicht A1, A2 usw..
Wähle lange Bezeichnernamen damit eine zufällige Zuweisung nicht passiert.

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 »

Wovon redest du ? Das problem ist doch schon lange gelöst und Bezeichner wie A1,A2 gibts auch nirgends ?!
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

oldcoder
Beiträge: 4
Registriert: So 10. Dez 2006, 08:41
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Hamburg

Beitrag von oldcoder »

Hallo Cristian, entschuldige das ich mich undeutlich ausgedrückt habe. Aber leider ist nichts gelöst weil die wenigsten Projekte zwei Forms haben. Sinn der objektorientierten Programmierung ist doch die Datenkapselung und die Wiederverwendung von Programmcode mit wechselnden Daten ( z.B Variablen ). Also ich habe TForm und der Code wird in allen meinen Fenstern verwendet. Wenn ich also die Datenkapselung ausheble warum dann nicht gleich richtig? In jedem Projekt sind eine Menge globaler Variablen und das schreit förmlich nach einer eigenen Unit.
Willst Du alle Forms untereinander includieren um irgentwann nicht mehr zu wissen wer wen sieht?
Wenn alle globalen Variablen in einer Unit, mit Kommentaren, sind kann man den Quelltext auch noch nach Jahren verstehen.
Also eine klare Trennung von Daten aber immer geht es nicht.

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 gar nicht mehr einsetzen. Bei mir landen die meissten Variablen in den Form klassen. Dadurch kann ich von überall darauf zugreifen und die zugehörigkeit der variable ist auch klar mir fällt momentan kein Fall ein wo man globale variablen braucht. Und du kannst die form so oft einbinden wie du willst du solltest die uses nur in der implementation section verwenden.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

schnullerbacke
Beiträge: 1187
Registriert: Mi 13. Dez 2006, 10:58
OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
CPU-Target: AMD A4-6400 APU
Wohnort: Hamburg

Beitrag von schnullerbacke »

Hmmmmmmm, machten die Umstehenden und nochmals, Hmmmmmmm.

Ich würde ja einfach für Form2 nen neuen constructor bauen, etwa so:

constructor Create(AOwner: TComponent; MyVar: MyType);
begin
MyInnerVar:= MyVar;
end;

und dann mit:

property MyExportVar: MyVar GetMyVar;

das Dings zurückholen. Das ist die sauberste Lösung, schon weil man dann auf globale Variablen ganz verzichten kann.
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.

(Ringelnatz)

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 »

Ich glaube, Peter gehört eher zu den Einsteigern....

... und da denke ich: Für kleinere Programme ist es für einen Einsteiger kein Verbrechen, globale Variablen zu verwenden...

Antworten