SENDER an andere Form übermitteln

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
ppahl
Beiträge: 56
Registriert: Fr 25. Nov 2016, 00:02

SENDER an andere Form übermitteln

Beitrag von ppahl »

Falls ihr mit dem Titel nix anfangen könnt: Ehrlich gesagt wusste ich nicht wie ich es richtig titulieren soll, daher erkläre ich einfach mal worum es geht.
Ein Raspberry soll über Touchscreen bedient werden, d.h. es ist keine Tastatur angeschlossen.
Mehrere Labels sollen mit vierstelligen Zahlenwerten versehen werden können, mit diesen wird dann als Parameter weitergerechnet.

Meine aktuelle Lösung:

Ich habe eine zweite Form 'Eingabe' kreiert und auf dieser vier 'einstellige' Labels (label1000er, label100er, label10er, label1er) nebeneinander abgelegt, zusammen ergeben sie die Illusion einer vierstelligen Zahl.
Über/unter jedem Label befindet sich eine Grafik mit einem Up/Down Pfeil - siehe Anhang.
label.jpg
label.jpg (24.57 KiB) 2874 mal betrachtet


Über die OnClick Events dieser Grafiken kann ich die einzelnen 'Stellen' der pseudo-vierstelligen Zahl durchblättern.

Code: Alles auswählen

 
procedure TEingabe.Image1Click(Sender: TObject);
begin
  if strtoint(label1000er.Caption) < 9 then label1000er.Caption := inttostr(strtoint(label1000er.Caption) + 1) else label1000er.Caption := '0';
end;
procedure TEingabe.Image3Click(Sender: TObject);
begin
  if strtoint(label100er.Caption) < 9 then label100er.Caption := inttostr(strtoint(label100er.Caption) + 1) else label100er.Caption := '0';
end;
procedure TEingabe.Image5Click(Sender: TObject);
begin
  if strtoint(label10er.Caption) < 9 then label10er.Caption := inttostr(strtoint(label10er.Caption) + 1) else label10er.Caption := '0';
end;
procedure TEingabe.Image7Click(Sender: TObject);
begin
  if strtoint(label1er.Caption) < 9 then label1er.Caption := inttostr(strtoint(label1er.Caption) + 1) else label1er.Caption := '0';
end;
procedure TEingabe.Image2Click(Sender: TObject);
begin
  if strtoint(label1000er.Caption) > 0 then label1000er.Caption := inttostr(strtoint(label1000er.Caption) - 1) else label1000er.Caption := '9';
end;
procedure TEingabe.Image4Click(Sender: TObject);
begin
  if strtoint(label100er.Caption) > 0 then label100er.Caption := inttostr(strtoint(label100er.Caption) - 1) else label100er.Caption := '9';
end;
procedure TEingabe.Image6Click(Sender: TObject);
begin
  if strtoint(label10er.Caption) > 0 then label10er.Caption := inttostr(strtoint(label10er.Caption) - 1) else label10er.Caption := '9';
end;
procedure TEingabe.Image8Click(Sender: TObject);
begin
  if strtoint(label1er.Caption) > 0 then label1er.Caption := inttostr(strtoint(label1er.Caption) - 1) else label1er.Caption := '9';
end;
 

Vielleicht nicht besonders elegant und kompakt, funktioniert aber wenigstens erstmal und ist fürs eigentliche Problem auch nicht weiter relevant ;).

Die Label der Mainform 'Form1' haben alle das gleiche OnClick Event über das die zweite Form sichtbar gemacht wird:

Code: Alles auswählen

 
procedure TForm1.LabelClick(Sender: TObject);
begin
  dummy := (sender as TLabel).Caption;
  Unit2.Eingabe.label1000er.caption := copy(dummy,1,1);
  Unit2.Eingabe.label100er.caption := copy(dummy,2,1);
  Unit2.Eingabe.label10er.caption := copy(dummy,3,1);
  Unit2.Eingabe.label1er.caption := copy(dummy,4,1);
  Unit2.Eingabe.visible := true;
end;
 

Das klappt auch wunderbar, egal welches Label ich anklicke, die jeweilige Zahl wird auf die einzelnen Label der zweiten Form übertragen.

Die Frage jetzt aber: Wie bringe ich das Ergebnis aus der zweiten Form zurück zum auslösenden Label der ersten Form?
Eine direkte Zuweisung (nach Klick auf den 'Übernehmen'-Button) auf ein explizites Label der ersten Form funktioniert:

Code: Alles auswählen

 
  procedure TEingabe.ButtonOKClick(Sender: TObject);
  begin
   form1.label1.caption := label1000er.caption + label100er.caption + label10er.caption + label1er.caption;
   Eingabe.visible := false;
  end;
 

Aber ich möchte natürlich das Ergebnis in das Label der ersten Form schreiben, welches das OnClick Event ausgelöst hat. Und da stehe ich gerade mächtig auf der Leitung.

Ich hoffe die Problembeschreibung war halbwegs verständlich? :?

Mathias
Beiträge: 6143
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: SENDER an andere Form übermitteln

Beitrag von Mathias »

Verstehe ich dich richtig ?

Du hast ein Form(Eingabe) gemacht und wen du dort etwas änderst, dann soll dieser Wert(0-9999) in einem Label auf dem Hauptform angezeigt werden und dies am besten zur Echtzeit ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

ppahl
Beiträge: 56
Registriert: Fr 25. Nov 2016, 00:02

Re: SENDER an andere Form übermitteln

Beitrag von ppahl »

Vielleicht nochmal der Reihe nach.
Zunächst ist nur Form1 sichtbar, Form2 ist unsichtbar ('Eingabe.visible := false;')
Auf Form1 befinden sich mehrere Label, alle haben das OnClick Event TForm1.LabelClick(Sender: TObject);
Selbiges zerlegt die Caption des auslösenden Labels in Einzelziffern, überträgt diese Ziffern in die Labels der zweiten Form und macht diese sichtbar ('Eingabe.visible := true;')
Nun liegt die zweite Form im Vordergrund und die einzelnen Ziffern können über die hoch/runter Pfeile geändert werden.
Mit Klick auf den Button 'Übernehmen' sollen die einzelnen Zahlen wieder zu einem String zusammengesetzt und der Caption des auslösenden Labels der ersten Form zugewiesen werden (also nicht in Echtzeit sondern erst nach Klick auf den Button).
Gebe ich ein konkretes Label der ersten Form als Ziel an dannklappt das ja (erwartungsgemäss) ja auch.
Ich will aber das Label beschreiben was die ganze Prozedur ausgelöst hat.

ppahl
Beiträge: 56
Registriert: Fr 25. Nov 2016, 00:02

Re: SENDER an andere Form übermitteln

Beitrag von ppahl »

So, ich habe mir mal selbst was zusammengebogen.
Zunächst habe ich in der ersten Unit eine globale Variable 'ausloeser : tobject' deklariert.

Das OnClick Event der Labels von Form1 habe ich wie folgt geändert:

Code: Alles auswählen

 
procedure TForm1.LabelClick(Sender: TObject);
begin
  ausloeser := sender;
  Unit2.Eingabe.label1000er.caption := copy((ausloeser as tlabel).Caption,1,1);
  Unit2.Eingabe.label100er.caption := copy((ausloeser as tlabel).Caption,2,1);
  Unit2.Eingabe.label10er.caption := copy((ausloeser as tlabel).Caption,3,1);
  Unit2.Eingabe.label1er.caption := copy((ausloeser as tlabel).Caption,4,1);
  Unit2.Eingabe.visible := true;
end;
 


Ferner habe ich die erste Unit um diese Prozedur ergänzt:

Code: Alles auswählen

 
procedure TForm1.Return2Form1;
begin
  (ausloeser as tlabel).caption := eingabe.labeltext;
end;
 


In der zweiten Unit habe ich eine globale Variable 'labeltext' deklariert.
Und dann das OnClick Event des 'Übernehmen'-Buttons wie folgt geändert:

Code: Alles auswählen

  procedure TEingabe.ButtonOKClick(Sender: TObject);
  begin
   labeltext := label1000er.caption + label100er.caption + label10er.caption + label1er.caption;
   form1.Return2Form1;
   Eingabe.visible := false;
  end;
 

Funktioniert!
Aber gibts echt keine Möglichkeit diese zusätzliche Prozedur zu umgehen und die Label direkt von der zweiten Unit aus zu beschreiben? Wie kann ich die Variable 'ausloeser' direkt in der zweiten Unit nutzen?

Ach ja, ich weiss nicht ob es wichtig ist: Ich habe in den Units jeweils nach 'implementation' die andere Unit als uses eingetragen, die Variablen sollten also grundsätzlich gegenseitig sichtbar sein. Was ja auch generell funktioniert.
Aber etwas wie form1.(ausloeser as tlabel).caption := labeltext in Unit 2 funktioniert nicht.

Mathias
Beiträge: 6143
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: SENDER an andere Form übermitteln

Beitrag von Mathias »

Wen du im Eingabe-Form Übernehmen drückst, dann willst du das die Labels im Form1 die gleichen werte bekommen, wie die im Eingabe-Form ?
Oder verstehe ich immer noch was falsch ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

ppahl
Beiträge: 56
Registriert: Fr 25. Nov 2016, 00:02

Re: SENDER an andere Form übermitteln

Beitrag von ppahl »

Fast richtig.
Auf der 'Eingabe'-Form liegen vier Labels nebeneinander die die 1000er, 100er, 10er und 1er Stellen des ursprünglichen Werts darstellen. Einfach um einen grossen Zahlenbereich komfortabel einstellen zu können. Zur Erinnerung: Am RPi hängt keine Tastatur sondern die Eingabe erfolgt über den Touchscreen.
Wird nun der 'Übernehmen'-Button gedrückt so werden diese einzelnen label.captions wieder zu einen String verkettet -> 'labeltext'
Und dieser String soll nun das (der? die?) Caption des auslösenden Labels der ersten Form werden.

Beispiel:
Form1.label3.caption sei '1234';

Das wird nun zerlegt in
- Eingabe.label1000er.caption = '1'
- Eingabe.label100er.caption = '2'
- Eingabe.label10er.caption = '3'
- Eingabe.label1er.caption = '4'

Dann wird z.B. die 10er-Stelle geändert auf 7 -> Eingabe.label10er.caption = '7'

Dann werden die einzelnen Captions wieder verkettet und in der Variablen 'labeltext' gespeichert -> labeltext = '1274'

Und nach Klick auf den 'Übernehmen'-Button möchte ich dass dieser Text der/die/das neue Caption vom auslösenden form1.label3 wird, also form1.label3.caption soll nun '1274' sein.

Wird statt dessen in Form1 das Label1 angeklickt dann das gleiche in grün, nur eben mit Label1.

Besser kann ich es echt nicht erklären...

Mathias
Beiträge: 6143
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: SENDER an andere Form übermitteln

Beitrag von Mathias »

Wieso machst du beim Übernehmen nicht ein einfaches Form1.Label3.Caption := '1234' ?
Dann kannst du das ganze Zeugs mit sender, etc. sparen.

Im Anhang habe noch ein kleines Programm, welches einem Integer auf eine virtuelle 7-Segment anzeigt, damit könntest du dein Eingabeform optisch ausbessern. :wink:
Dateianhänge
Int_To_7Segment.tar.gz
(126.95 KiB) 78-mal heruntergeladen
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: SENDER an andere Form übermitteln

Beitrag von wp_xyz »

Im beigefügten Beispiel siehst du wie ich das mache. Alles nach Schema F: Das Eingabeformular bekommt ein Property, über das der Wert ein- und ausgelesen werden kann. Im Hauptformular, OnButtonClick, wird der aktuelle Wert ins Eingabeformular geschrieben, dieses mit ShowModal angezeigt, und wenn es mit mrOK beendet wurde, dann wird der Wert ausgelesen.
Dateianhänge
StellenEingabe.zip
(3.43 KiB) 70-mal heruntergeladen

ppahl
Beiträge: 56
Registriert: Fr 25. Nov 2016, 00:02

Re: SENDER an andere Form übermitteln

Beitrag von ppahl »

@Mathias
Weil mir das Form1.Label3.Caption := '1234' nix nützt wenn statt dessen Label2 der Auslöser war...
Ich baue gleich mal ein Mini-Beispiel, vielleicht wirds dann klar...hätte nicht gedacht dass meine Gedankengänge so verschwurbelt erscheinen...

Ach ja, k.A. was mir dein Beispiel zeigen soll, ich sehe nur schwarze Rechtecke...?

@wp_xyz
Schaue ich mir gleich an, danke derweil :).

ppahl
Beiträge: 56
Registriert: Fr 25. Nov 2016, 00:02

Re: SENDER an andere Form übermitteln

Beitrag von ppahl »

@wp_xyz
Lege mal Button1.Click als OnClick-Event des Label1 fest.
Dann ziehe eine Kopie von diesem Label.
Dann lass das Prog laufen und klicke auf Label2 - fällt dir was auf? Der neue Wert wird nicht Label2 zugewiesen sondern weiterhin Label1. Er soll aber Label2 zugewiesen werden. Und bei Klick aufs erste label eben diesem.

Mathias
Beiträge: 6143
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: SENDER an andere Form übermitteln

Beitrag von Mathias »

Ach ja, k.A. was mir dein Beispiel zeigen soll, ich sehe nur schwarze Rechtecke...?

Eigentlich sollte es wie im Anhang ersichtlich sein.

statt dessen Label2 der Auslöser war...
Ein Label nimmt man normalerweise nicht als Auslöser, aus es ist ein Link.
Dateianhänge
Bildschirmfoto vom 2017-12-30 21-49-07.png
Bildschirmfoto vom 2017-12-30 21-49-07.png (2.54 KiB) 2852 mal betrachtet
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

ppahl
Beiträge: 56
Registriert: Fr 25. Nov 2016, 00:02

Re: SENDER an andere Form übermitteln

Beitrag von ppahl »

Anbei mein Beispiel.
Dateianhänge
forum.zip
(66.62 KiB) 66-mal heruntergeladen

Mathias
Beiträge: 6143
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: SENDER an andere Form übermitteln

Beitrag von Mathias »

Ich habe das Beispiel von wpx ein wenig abgeändert, ist das was du suchst ?
Dateianhänge
test.tar.gz
(3.75 KiB) 75-mal heruntergeladen
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: SENDER an andere Form übermitteln

Beitrag von wp_xyz »

ppahl hat geschrieben:@wp_xyz
Lege mal Button1.Click als OnClick-Event des Label1 fest.
Dann ziehe eine Kopie von diesem Label.
Dann lass das Prog laufen und klicke auf Label2 - fällt dir was auf? Der neue Wert wird nicht Label2 zugewiesen sondern weiterhin Label1. Er soll aber Label2 zugewiesen werden. Und bei Klick aufs erste label eben diesem.

Du musst den Sender des OnClick-Events auswerten, dann weißt du, welches Label geklickt wurde.

Code: Alles auswählen

var
  FCurrValues: array[0..1] of Integer;
 
procedure TForm1.LabelClick(Sender: TObject);
var
  lbl: TLabel;
  valIndex: Integer;
begin
  if not (Sender is TLabel) then
    exit;
 
  lbl := TLabel(Sender);
  if lbl = Label1 then valIndex := 0 else valIndex := 1;
 
  Form2.Value := FCurrValues[valIndex];
  Form2.Left := Left + Width;
  Form2.Top := Top;
  if Form2.ShowModal = mrOK then begin
    FCurrValue[valIndex] := Form2.Value;
    lbl.Caption := 'Aktueller Wert: ' + IntToStr(FCurrValues[valIndex]);
  end;
end;

ppahl
Beiträge: 56
Registriert: Fr 25. Nov 2016, 00:02

Re: SENDER an andere Form übermitteln

Beitrag von ppahl »

Probiert doch einfach mal mein Beispiel aus. Einfach auf die Labels klicken und schauen was passiert.


Edith sagt: Uups, hat sich überschnitten, denk ich mal kurz drüber nach... ;).

Antworten