Recent

Author Topic: Help with TFrame  (Read 638 times)

VTwin

  • Hero Member
  • *****
  • Posts: 1182
  • Former Turbo Pascal 3 user
Help with TFrame
« on: January 22, 2023, 10:51:14 pm »
I am trying to understand how a TFrame works. Attached is a simple example project that does not work.

Any help is appreciated.
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.4 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.4 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.4 (64 bit on VBox)

wp

  • Hero Member
  • *****
  • Posts: 10644
Re: Help with TFrame
« Reply #1 on: January 23, 2023, 12:27:58 am »
Frames are great components to split code out of an overcrowded unit into their own units. But when you are careless they can be quite nasty...

I confirm that in your example the paintbox OnPaint handler implemented in the frame is not executed. Opening the lfm file in an external editor I see that the instances Frame1_1 and Frame1_2 inserted into Form1 at designtime do have nil as OnPaint handlers. This is wrong - it should be the event handler inherited from the frame class, and since this is the default there should not be any OnPaint handler in the lfm for the frames in Form1. This happens too easily when you try to attach an event handler to frames' Paintbox and then change you mind and delete the handler in Form1 - no Frame1_1.Paintbox1 does not have an OnPaint handler any more! The same happens very easily with normal properties of the controls on the frame.

The only way to fix this is to delete the lines "OnPaint = nil" (of Frame1_1.Paintbox1 and Frame1_2.Paintbox) from the lfm in an external editor. You can do it in the IDE, too, when you right-click on the form in the designer and select "View source (.lfm)". But then you MUST reload the entire project to clear internal caches, and I think you must also do a "Run" > "Build".

See "frame1-wp.zip" (I took the freedom to change the OnPaint code of the frame's Paintbox a bit in order to show that something is happening when the checkbox is clicked).

You can avoid this hassle when you do not insert frames at designtime, but at runtime - see "frame1-wp-runtime.zip". This way the frame does not exist on the form at designtime, and there is absolutely no chance that you might want to click somewhere on the frame. However there an issue to be mentioned here, too: Frames created at runtime automatically get the name derived from the class - i.e. all instances of TFrame1 are named "Frame1_1" (I think this is a bug). And of course, the IDE does not like this when you add the same frame a second time! To avoid this give each inserted frame a unique name after creation, or, better, simply set it to an empty string.

VTwin

  • Hero Member
  • *****
  • Posts: 1182
  • Former Turbo Pascal 3 user
Re: Help with TFrame
« Reply #2 on: January 23, 2023, 04:02:38 pm »
Wow. Thanks for the working examples wp, they are invaluable. The example in the wiki does not address these complexities.

I hoped using frames might be simpler than my current method. I use the anchor editor to lay everything out at design time, and then attach the controls to a wrapper class which takes care of the painting. For my purposes, frames are not a simpler solution.
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.4 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.4 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.4 (64 bit on VBox)

wp

  • Hero Member
  • *****
  • Posts: 10644
Re: Help with TFrame
« Reply #3 on: January 23, 2023, 04:22:07 pm »
The example in the wiki does not address these complexities.
Are you referring to this article: https://wiki.lazarus.freepascal.org/Frames ?

For my purposes, frames are not a simpler solution.
Usually they are, in particular for complex forms with tabcontrols/notebooks and many groupboxes offering always the same logical functionality. Such forms usually have thousands of lines for the gui event handlers. When you move each tabsheet into a frame all the related event handlers go with it, and in the end only the essential code is left. Look at the TAChart sample project in components/tachart/demo/charteditor for a more complex example.
« Last Edit: January 23, 2023, 04:28:42 pm by wp »

VTwin

  • Hero Member
  • *****
  • Posts: 1182
  • Former Turbo Pascal 3 user
Re: Help with TFrame
« Reply #4 on: January 23, 2023, 04:56:09 pm »
Yes.

I am sure there are numerous cases where they are very useful. In my case, it is just two or three controls, my solution would not work for more complex groups.

I will have a look at TAChart.

Thanks. 
“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.4 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.4 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.4 (64 bit on VBox)

jamie

  • Hero Member
  • *****
  • Posts: 5180
Re: Help with TFrame
« Reply #5 on: January 23, 2023, 11:17:39 pm »
the OI needs a lot of improvement to make Frames work in point and click environments.

But one of the sores are the fact that the OI does not prefix the generated event name with the name of the Frame, so it can get mixed up using other events that don't belong to it.

 Unless they have changed it, normally you can type in a fully qualified name and the OI will create it.
The only true wisdom is knowing you know nothing

VTwin

  • Hero Member
  • *****
  • Posts: 1182
  • Former Turbo Pascal 3 user
Re: Help with TFrame
« Reply #6 on: January 23, 2023, 11:29:03 pm »
It was opaque to me, but I'm sure others have more experience.

I could not have figured it out without wp's examples.

“Talk is cheap. Show me the code.” -Linus Torvalds

Free Pascal Compiler 3.2.2
macOS 12.1: Lazarus 2.2.4 (64 bit Cocoa M1)
Ubuntu 18.04.3: Lazarus 2.2.4 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.2.4 (64 bit on VBox)

Joanna

  • Sr. Member
  • ****
  • Posts: 296
Re: Help with TFrame
« Reply #7 on: January 26, 2023, 11:25:08 am »
I use almost exclusively frames nested inside other frames for my project with the frames being created at runtime and the events being set at runtime. It is possible to pass the pointer to an event down to child controls of a frame and then assign it to controls. I don’t know if this is the orthodox way to do it but it works for me.

It’s not too hard to use anchor or align at runtime to get your frames where you want them .

One control that I’ve found particularly useful to use inside frames is the flowpanel.
Come chat on IRC .. https://libera.chat/guides/
IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channels  #fpc #lazarus #pascal 
Private Message me if you want to be added to invite list, otherwise type /msg nickserv help register to get started

 

TinyPortal © 2005-2018