Recent

Author Topic: [SOLVED] Passing data back and forth between forms  (Read 2812 times)

HopefulGuy

  • New Member
  • *
  • Posts: 28
[SOLVED] Passing data back and forth between forms
« on: May 09, 2021, 07:00:37 am »
I guess I'm too used to Delphi. I have a program I'm working on with multiple forms. Form A has a button who's onClick event calls Form B. So naturally the unit file for Form A uses the unit file for Form B. BUT, Form B needs to change properties on Form A. In Delphi I'd just include Form A's unit in Form B. But Lazarus/FreePascal doesn't seem to want to let me do that. So how do I access a property of From A from Form B? I tried referencing Self.Parent, but the compiler doesn't recognize the properties in form A that way. I can't typecast as Form A because in order to do that Form B would need to know the format of Form A, which brings me right back to where I started.

Help?
« Last Edit: May 09, 2021, 10:39:25 am by HopefulGuy »

kapibara

  • Hero Member
  • *****
  • Posts: 610
Re: Passing data back and forth between forms
« Reply #1 on: May 09, 2021, 07:47:09 am »
To avoid circular reference, add Form A's unit to Form B's implementation uses instead of the interface part.

Then you reference form A's properties with frmA.SomeProperty.

Code: Pascal  [Select][+][-]
  1. var
  2.   frmB: TfrmB;
  3.  
  4. implementation
  5.  
  6. uses
  7.   uFormA;
  8.  
  9. {$R *.lfm}
  10.  
  11. { TfrmB }
  12.  
« Last Edit: May 09, 2021, 08:33:14 am by kapibara »
Lazarus trunk / fpc 3.2.2 / Kubuntu 22.04 - 64 bit

HopefulGuy

  • New Member
  • *
  • Posts: 28
Re: Passing data back and forth between forms
« Reply #2 on: May 09, 2021, 10:37:18 am »
Thanks! That's exactly what I needed!

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: [SOLVED] Passing data back and forth between forms
« Reply #3 on: May 09, 2021, 10:42:32 am »
You might still find that you have a circular reference in the form/class definition. You can fix that using a class helper, yell if you need an example.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: [SOLVED] Passing data back and forth between forms
« Reply #4 on: May 09, 2021, 01:04:21 pm »
I try to avoid such a situation from the beginning. When a form defines settings needed by another form then I never acces the form to read the settings but declare a variable in a third unit, and this unit is to be used by both forms.

Example (untested):
Suppose Form1 contains a Combobox in which a particular font size is selected, and this font size will be needed by another Form2.

Code: Pascal  [Select][+][-]
  1. unit Globals;
  2. interface
  3.  
  4. var
  5.   GlobalFontSize: Integer = 10;
  6.  
  7. implementation
  8.  
  9. end.
  10.  
  11. -----------------------------
  12.  
  13. unit Unit1;
  14.  
  15. ...
  16.  
  17. implementation
  18.  
  19. uses
  20.   Unit2, Globals;   // Use the implementation "uses" whenever possible.
  21.  
  22. procedure TForm1.Combobox1Change(Sender: TObject);
  23. begin
  24.   if Combobox1.ItemIndex > -1 then
  25.     // Store selected font size in global variable
  26.     GlobalFontSize := StrToInt(Combobox1.Items[Combobox1.ItemIndex]);
  27. end;
  28.  
  29. ------------------------------
  30.  
  31. unit Unit2;
  32.  
  33. ...
  34.  
  35. implementation
  36.  
  37. uses
  38.   Globals;
  39.  
  40. procedure TForm2.UpdateFontSize;
  41. begin
  42.   // do something with GlobalFontSize
  43.   // Read the font size from the global variable rather than from Form1's combobox.
  44. end;

I know global variables are usually considered to be bad programming style. But here a global variable is a true solution to the circular reference issue which sooner or later may become unresolvable.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: [SOLVED] Passing data back and forth between forms
« Reply #5 on: May 09, 2021, 01:58:30 pm »
I know global variables are usually considered to be bad programming style. But here a global variable is a true solution to the circular reference issue which sooner or later may become unresolvable.

I think the "considered harmful" designation is unsupportable as long as Lazarus insists on representing each form by a global variable.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

jcmontherock

  • Full Member
  • ***
  • Posts: 234
Re: [SOLVED] Passing data back and forth between forms
« Reply #6 on: May 09, 2021, 06:22:21 pm »
Another way:

Code: Pascal  [Select][+][-]
  1.     unit Unit1;
  2.     Interface    
  3.    
  4.     uses Unit2;
  5.     implementation
  6.     ...
  7.     var Font1: TFont;
  8.    
  9.     procedure TForm1.FormCreate(Sender: TObject);
  10.     begin
  11.       PFont :=  @Font1;
  12.       ......
  13.     end;
  14.     ===================================================
  15.     unit Unit2;
  16.     implementation
  17.  
  18.     var PFont: ^TFont;      // address of Font1 in Unit1    
  19.  
  20.     procedure TForm2.UpdateFontSize;
  21.     var fontSize: Single;
  22.     begin
  23.       fontSize := PFont^.Size;
  24.       .......
  25.       PFont^.Size := 9;
  26.       .......
  27.     end;
  28.  
Windows 11 UTF8-64 - Lazarus 3.2-64 - FPC 3.2.2

 

TinyPortal © 2005-2018