[gelöst] Aufruf Ereignisroutine eines Parent vom Child

Rund um die LCL und andere Komponenten

[gelöst] Aufruf Ereignisroutine eines Parent vom Child

Beitragvon Helios » 14. Jul 2019, 22:22 [gelöst] Aufruf Ereignisroutine eines Parent vom Child

Hallo Forenmitglieder,

eine Frage zum Thema: Aufruf einer Ereignisroutine eines Parent und übermittlung Child Daten zum Parent.
Konkret:
In einer ScrollBox erzeuge ich mit einem Doppelklick dynamisch von TShape abgeleitetete Objekte (TOpticalArea)
(vgl. auch den Thread https://www.lazarusforum.de/viewtopic.php?f=18&t=12424, der mir dabei geholfen hat).
Die Eigenschaften eines TOpticalArea kann ich über ein (ebenfalls) dynamisch erzeugtes PopUpmenü (Farbe, Höhe, Breite, etc.)
mit einem Rechtsklick ändern.
Diese Funktionen sind (hoffe ich) nach der objektorientierten Lehre in dem entsprechenden Object (TOpticalArea) "gekapselt".
Um die grafischen TShape Elemente später verwalten zu können, zeige ich Diese auch in textueller Form in einem TreeView Fenster an.
Bei einem Doppelklick auf ein existierendes (grafisches) TOpticalArea soll es sowohl grafisch als auch aus dem Treeview Fenster gelöscht werden.
Das grafische Löschen funktioniert wunderbar. Leider weiss ich nicht, wie ich den Doppelklick auf das existierende TOpticalArea auf das
Parent, die ScrollBox, übermittle, damit ich von dort aus im TreeView den Eintrag der TOpticalView löschen kann.

Weiterhin möchte ich die Höhe, Breite, etc. vom TOpticalArea(=TShape) in der StatusBar anzeigen, wenn ich mit der Maus über der
entsprechenden Instanz des TOpticalArea bin.
Das ist eigentlich ein ähnliches Problem wie oben beschrieben, da ich mit einem MousEnter auf den TOpticalArea(=TShape) Informationen in ein
übergelagertes Objekt (hier die StatusBar) übertragen möchte (im Code Beispiel habe ich es direkt auf den Canvas des
TOpticalArea geschrieben, was ich eigentlich in der Statusbar sehen möchte).

Hier stoße ich an die Grenzen bzgl. meiner OOP- und Eventhandling-Kenntnisse und hoffe auf einen entsprechenden Tipp aus der
Forengemeinde.

Vielen Dank für eine Rückmeldung und schönen Abend
Arne

PS: Beispielcode nun wieder mit Lazarus 2.0.2 unter Windows 7 erstellt
Dateianhänge
OptischerKoppler.zip
(129.63 KiB) 4-mal heruntergeladen
Zuletzt geändert von Helios am 18. Jul 2019, 21:50, insgesamt 2-mal geändert.
Helios
 
Beiträge: 18
Registriert: 29. Jun 2011, 22:36
Wohnort: Leonberg
OS, Lazarus, FPC: Lazarus 2.0.2 Windows 7 64Bit / Lazarus 1.8.4 Debian 9 „Stretch" 64Bit | 
CPU-Target: 64Bit
Nach oben

Beitragvon af0815 » 15. Jul 2019, 07:26 Re: Aufruf Ereignisroutine eines Parent vom Child

Normalerweise löse ich das mit eine´m Callback. Damit kann ich dem Parent mitteilen das sich was geänderet hat. Siehe auch http://michael-puff.de/Programmierung/A ... back.shtml
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
af0815
 
Beiträge: 3764
Registriert: 7. Jan 2007, 11:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: FPC 3.2 Lazarus 2.0 per fpcupdeluxe | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon kupferstecher » 15. Jul 2019, 10:35 Re: Aufruf Ereignisroutine eines Parent vom Child

Das ist eigentlich genau der Einsatzzweck von Vererbung.

In der Elternklasse definierst du eine virtuelle Prozedur, in der du die gewünschten Aktionen ausführst, z.B.

Code: Alles auswählen
Type TElternKlasse = class
  Procedure DoSth(AParam: Boolean); virtual;
end;
 
implementation
Procedure TElternklasse.DoSth(AParam: Boolean);
begin
  self.setbounds(...);
end;


In der abgeleiteten überlädst du dann die Prozedur und rufst Inherited auf (und damit die Prozedur der Elternklasse).

Code: Alles auswählen
Type TKindKlasse = class(TElternKlasse)
  Procedure DoSth(AParam: Boolean); override;
end;
 
implementation
Procedure TElternklasse.DoSth(AParam: Boolean);
begin
  Inherited(AParam);
  //...
end;
kupferstecher
 
Beiträge: 227
Registriert: 17. Nov 2016, 12:52

Beitragvon Helios » 15. Jul 2019, 23:24 Re: Aufruf Ereignisroutine eines Parent vom Child

Hallo af0815 und kupferstecher,
vielen Dank für Eure schnelle Rückmeldung.
@kupferstecher:
Ich glaube ich habe mich falsch ausgedrückt. Das "Parent" ist die ScrollBox, in die ich meine TShapes platziere. Sie sind nicht miteinander verwandt.
Die TShapes/TOpticalAreas sind nur in dem Container "ScrollBox" erstellt worden. Weil die TShapes/TOpticalAreas so schon gekapselt sind, wird ein Doppelklick
nach der Erzeugung eines TShapes/TOpticalAreas von diesen "weggefangen" und nicht mehr an den übergeordneten Container (die ScrollBox) weitergeleitet.
Das ist eigentlich das was ich möchte: Nach dem Löschen des TShapes möchte ich der ScrollBox den weiteren Doppelklick mitteilen, damit dieser alle
weiteren Informationen des TShapes/TOpticalAreas löscht. Mit anderen Worten, das was in TFormMain.ScrollBox1DblClick dynamisch erzeugt wurde, soll
beim 2. Doppelklick auf das entsprechende TShape/TOpticalArea wieder vollständig gelöscht werden.
Ich glaube die Callback Vorgehensweise ist das, was mir hier weiterhelfen könnte, das muss ich mir in den nächsten Tagen nochmal anschauen.
Danke nochmal für Eure Hilfe und Gruß
Arne
Helios
 
Beiträge: 18
Registriert: 29. Jun 2011, 22:36
Wohnort: Leonberg
OS, Lazarus, FPC: Lazarus 2.0.2 Windows 7 64Bit / Lazarus 1.8.4 Debian 9 „Stretch" 64Bit | 
CPU-Target: 64Bit
Nach oben

Beitragvon fliegermichl » 16. Jul 2019, 09:57 Re: Aufruf Ereignisroutine eines Parent vom Child

Man kann den Mausklick prinzipiell an den Ereignishandler des Parents weiterleiten. Jedes Control hat ja die Eigenschaft Parent und man kann in dem OnClick Event Parent.OnClick(self) aurufen. Wenn dabei aber self freigegeben wird, fliegt dir das um die Ohren weil die Programmausführung nachher in einen Eventhandler zurückkehrt dessen Objektinstanz nicht mehr existiert.
Ich hab in solchen Fällen eine Liste "Zu_Loeschende_Objekte". Der Eventhandler des Controls macht dann nichts weiter als sich da einzutragen.

In einem Idle Event wird später geprüft, ob sich Werte in der Liste befinden und werden dann erst freigegeben.
fliegermichl
Lazarusforum e. V.
 
Beiträge: 398
Registriert: 9. Jun 2011, 09:42

Beitragvon kupferstecher » 16. Jul 2019, 12:08 Re: Aufruf Ereignisroutine eines Parent vom Child

@Helios:
Da hab ich dich etwas missverstanden. Die Vererbung kommt erst dann zum Tragen, wenn du verschiedene Elemente plazieren möchtest.

Ansonsten ist die Callback-Methode, also eine Prozedur über eine Funktionsvariable zu übergeben, schon der richtige Weg um eine saubere Trennung der Units zu gewährleisten. Für Quick-Und-Dirty bzw. einen Erstversuch kannst du natürlich auch die Prozedur aus dem Maus-Handler raus direkt rufen.
kupferstecher
 
Beiträge: 227
Registriert: 17. Nov 2016, 12:52

Beitragvon Helios » 18. Jul 2019, 01:08 Re: Aufruf Ereignisroutine eines Parent vom Child

Hallo alle zusammen,
vielen Dank für eure Hilfe. Ich habe mich nun für die schon erwähnte Callback Variante entschieden. Im Anhang nun ein Beispielprogramm (funktioniert ganz gut unter Windows, unter Debian ist
der Text etwas hässlich wenn man über die erzeugten Shapes mit der Maus drüber fährt, aber den Code kann man auch unter Debian auskommentieren;-).
Da die CallBack Routine in einem Objekt verpackt ist, muss bei
TCallBackFunc = procedure(Sender: TObject) of object;
noch das "of objekt" drangehängt werden, das war eigentlich die größte Hürde beim Kompilien. Nun läuft es und die Lösung finde ich schön elegant und wiederverwendungswert, Dank eurer Tipps.

Schönen Abend noch und nochmal herzlichen Dank für euren Support und an die Lazarus/Free Pascal Entwickler.
Einfach eine saugute Sprache/Entwicklungsumgebung und sie gefällt mir immer mehr!

Gruß

Arne
Dateianhänge
ShapeDesigner.zip
(129.83 KiB) 3-mal heruntergeladen
Helios
 
Beiträge: 18
Registriert: 29. Jun 2011, 22:36
Wohnort: Leonberg
OS, Lazarus, FPC: Lazarus 2.0.2 Windows 7 64Bit / Lazarus 1.8.4 Debian 9 „Stretch" 64Bit | 
CPU-Target: 64Bit
Nach oben

• Themenende •

Zurück zu Komponenten und Packages



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste

porpoises-institution
accuracy-worried