Forum > Beginners

Getting started with GUI

(1/2) > >>

segfault:
I've only ever written procedural programs so I'm having some problems getting started with GUIs. I suspect this is partly because I haven't got my head around OOP yet. Anyway, I have some questions which I haven't seen the answers to in any tutorials, probably because they're so basic.  :-[

So suppose I put together a very simple form using Lazarus and create an event handler for a button, like this:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls; type   { TForm1 }   TForm1 = class(TForm)    Button1: TButton;    Edit1: TEdit;    procedure Button1Click(Sender: TObject);  private    { private declarations }  public    { public declarations }  end; var  Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject);begin end; end.                 
My questions are:

1. Where do I put procedures/functions which aren't event-handlers?. E.g. a function which is to be called from multiple event handlers. Do these functions need to be declared? and if so where?

2. Do I put all global variables under the main var section?

3. Where do I initialise variables?

4, Why isn't there a 'begin' statement?

Thanks in advance for any help.

howardpc:

--- Quote from: segfault on October 10, 2017, 08:54:58 pm ---1. Where do I put procedures/functions which aren't event-handlers?. E.g. a function which is to be called from multiple event handlers. Do these functions need to be declared? and if so where?
--- End quote ---
All functions need to be declared.
Usually you would declare them in the private section of the form class, or in a higher visibility section if necessary.


--- Quote from: segfault on October 10, 2017, 08:54:58 pm ---2. Do I put all global variables under the main var section?
--- End quote ---
Avoid introducing global variables. But if you absolutely need a few, it is best to declare them all together, so that means grouping them with the global form variable Form1.
 

--- Quote from: segfault on October 10, 2017, 08:54:58 pm ---3. Where do I initialise variables?
--- End quote ---
Most global variables can be intialised in their declaration, e.g.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  globalCount: Integer = -1;Other variables can probably be initialised in the form's OnCreate handler, or perhaps in an initialization section at the end of the main form's unit.
Note that the compiler initialises all global variables for you (if they are not initialised manually), and also zeros all field variables for all classes, so you only need to manually initialise any variables that should start out with non-compiler-default values.


--- Quote from: segfault on October 10, 2017, 08:54:58 pm ---4, Why isn't there a 'begin' statement?
--- End quote ---
There is. You'll find it in the project's .lpr (Project -> View project source).

mas steindorff:
1st off I recommend checking out the tons of utube demos and get a few working programs under your belt.
Simple procedural programs do not often take advantage of OPP (object and classes). you should plan to learn this concept if you want to create for today's OSs 

1: you can add procedures and functions anywhere below the implementation key word.  if you what to access any form controls then it's best to make them part of the form by added the TForm1. (in your case) as part of the name.  (you will also need to add the procedure to the tform class)

2: you can use the var keyword and place you variables in the same section or just add them to the Tform's type and let it create and dispose of them.

3: most time they are init in "formCreate". This can be added to your code by clicking on the form (not on any buttons or panels you may had added), go to the object inspctor and click on the "event" tab under the tree, and the clicking on the OnCreate field.  you can add your code to the automatically generate procedure.

4: that is due to the fact that you are only adding to an OS Application that was created to run you program. It is the one who is getting stuff from the OS like memory and processing resources  and taking care of all of the stuff you don't know about.  (keyboard,mouse,display area,....) and plays well with others.  the "Events" are how it creates hooks for you to add your code. as you see under the forms Events, there are many places you can hook into or you can leave the fields blank and let the default application code do it's thing.

taazz:
Hrmm. where to start..... OK here it goes.

--- Quote from: segfault on October 10, 2017, 08:54:58 pm ---My questions are:

4, Why isn't there a 'begin' statement?

--- End quote ---
because form1 is not the main application it is a unit used by the main application. Open your project inspector (menu project\project inspector) and double click the lpr file you will find your main application code there. Do not try to change it before researching what it does and how.


--- Quote from: segfault on October 10, 2017, 08:54:58 pm ---1. Where do I put procedures/functions which aren't event-handlers?. E.g. a function which is to be called from multiple event handlers. Do these functions need to be declared? and if so where?

--- End quote ---
Coming from a procedural background I would say that for now you declare them in the public section of the form class. That would be under

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  public    { public declarations } and before the end; That will give you access to everything you place on the form and make it a bit easier to start. as for the class section there are in total 4
Private, protected, public and published. The default section is published  which means that the methods and objects declared in just below the TForm1 declaration are published and they should remain published. for now just use public for your own properties and methods until you find some use of the protected and private sections. The published section is only relevant to component writers you can leave with out it.

--- Quote from: segfault on October 10, 2017, 08:54:58 pm ---2. Do I put all global variables under the main var section?

--- End quote ---
No you do not! well, not quite, that is my opinion the fact is that a unit can have multiple var sections in between type and const sections there is no specific order for those 3 sections that it is required, you have to choose your own order. In general after the unit declaration comes the uses clause then a number of const, type and var sections, the implementation declaration, the implementation uses clause and the code for you procedures functions with a number of const, type or var sections in between.
As for the global part it is considered bad practise to use global variables, mainly because it is hard to track from where they get their values and why. So we usually tell people that they should never use global variables. In this case I'm guessing that you will have a single form for now, then add all your variables in a protected section in the tform1 class. As long as you place your procedures in the public section of tform1 you will have access to them. When the need arises for a second form ask again.

--- Quote from: segfault on October 10, 2017, 08:54:58 pm ---3. Where do I initialise variables?

--- End quote ---
Depends on the variables. If you follow my advice above then double click the form's background make sure you do not double click any control that covers the form completely and the IDE will create a onFormCreate event for you. This is called when the form is created and at that point the variables have their memory allocated and it is safe to initialize them. That been said every variable (known as field when declared inside a class) gets a default value by the compiler as a result of the process of allocating memory for the class (the memory allocated is zerod out) which helps for fast prototyping, regardless I always initialize key fields to the expected value to avoid problems down the road.

Always keep in mind that a class is the blueprint of an object and object is what exists in your memory at runtime.
to use a class you need to define a variable with its type eg

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  Form1 : TForm1;  then you need to initialize the variable by calling the class constructor eg

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Form1 := TForm1.Create(nil);  after you finished using it you need to free its memory by calling its destructor eg

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  form1.Free;//<-- method that checks for nil before calling the destructor. 
That's it, have fun.

segfault:
Thanks for responses guys, much appreciated and very helpful.  :)

Navigation

[0] Message Index

[#] Next page

Go to full version