The following sections briefly describe a number of common steps that are useful when developing a Graphical User Interface (GUI) application with Lazarus.
We assume that the reader has a basic understanding of using Lazarus and of programming in Object Pascal.
Also see the Lazarus Tutorial.
Contents:
A new, unsaved project is created, consisting of
Unit1.pas
as MainForm.pas
:
Lazarus saves the unit in the file mainform.pas
and
the form data in the file mainform.lfm
.
The unit is renamed to MainForm
.Project1.lpi
as MyApp.lpi
:
Lazarus saves the project information in myapp.lpi
and the main program (whose source you usually will not need to see)
in myapp.lpr
.
The main program is renamed to MyApp
.
Also see Changing the options in a project of Getting Started with Lazarus at TU/e.
The recommended options for GUI applications are:
GUI elements (also known as widgets), such as labels, edit boxes, and buttons, are called components in Lazarus. The window that holds these components is called a form.
You can find the available components on the Component Palette:
The Component Palette is tabbed. Some relevant tabs and components are:
This is what a form looks like after adding some components:
Lazarus adds component declarations to the unit's *.pas
file:
unit Unit1; ... interface ... type { TForm1 } TForm1 = class(TForm) Button1: TButton; Button2: TButton; PaintBox1: TPaintBox; Panel1: TPanel; private { private declarations } public { public declarations } end; var Form1: TForm1; implementation
You can change the names of components to something better in the next step.
Note that components on the form are organized in a hierarchy. E.g., the form can contain a TPanel, which in turn contains a TButton. The hierarchical relationship among components is visualized in the top panel of the Object Inspector as a tree structure:
Components can be configured by changing their settings, also called properties in Lazarus. Properties can be inspected and edited using the Object Inspector, under the Properties tab. The Object Inspector can be opened via the Windows menu.
Some relevant properties:
To change the same property of multiple components at once, you can first select all relevant components (use Shift-click to add a component to the selection). The Object Inspector then shows all common properties, which you can subsequently edit to change them for all selected components.
The property values of components are stored in the *.lfm
file.
When a GUI application is started,
the run-time system will create all objects on the form and
will set the inital values of their properties.
After start-up,
the program can change property values at run-time as well.
The *.lfm
file can also be viewed and edited as text,
by right-clicking on the form and selecting View Source (.lfm):
object Form1: TForm1 Left = 489 Height = 300 Top = 254 Width = 400 Caption = 'Form1' ClientHeight = 300 ClientWidth = 400 OnCreate = FormCreate ParentFont = False LCLVersion = '0.9.26' object PaintBox1: TPaintBox Height = 300 Width = 225 Align = alClient OnPaint = PaintBox1Paint end object Panel1: TPanel Left = 225 Height = 300 Width = 175 Align = alRight Caption = 'Panel1' ClientHeight = 300 ClientWidth = 175 TabOrder = 0 object Button1: TButton Left = 50 Height = 25 Top = 24 Width = 75 Caption = 'Button1' OnClick = Button1Click TabOrder = 0 end object Button2: TButton Left = 50 Height = 25 Top = 64 Width = 75 Caption = 'Button2' TabOrder = 1 end end end
User actions and internal system actions generate events that are destined for particular components. Each component can be configured with event handlers to process events that arrive at that component.
Use the Events tab of the Object Inspector to configure the event handlers for all relevant events. There are two ways of doing so:
Here are some events and typical names of their event handlers:
Lazarus adds event handler code in two places
in the *.pas
source file:
TForm1 = class(TForm) ... procedure Button1Click(Sender: TObject); private { private declarations } public { public declarations } end; ... implementation { TForm1 } procedure TForm1.Button1Click(Sender: TObject); begin end;
Add your handler code in the implementation part.
The event handler's body can refer to components on the form and other form fields (see below) without further qualifiers:
procedure TForm1.Button1Click(Sender: TObject); begin TButton1.Enabled := False; TButton2.Enabled := True; end;
Each type of event handler has its own specific parameters.
For the the OnClick event handler of a button,
the Sender parameter is the actual button that was clicked.
You can access it with the expression
(Sender as TButton)
:
Several components can share the same event handler. The Sender parameter can be used to make the response of the event handler depend on which component received the event:
procedure TForm1.ButtonClick(Sender: TObject); begin (Sender as TButton).Enabled := False; end;
If you need auxiliary routines (procedures or functions), you can add them as methods to the form.
Put the routine's heading in the public section of the form's class definition:
TForm1 = class(TForm) ... private { private declarations } public { public declarations } procedure UpdateViews; end;
Use Code Completion:
procedure TForm1.UpdateViews; begin end;Put your code there. Like event handlers, such routines can access all components on the form and other form fields (see below) by their name (without further qualifiers).
If you wish to store some additional information with a form, you can do so in additional fields of the form. These are declared as variables, and are best put in the private section of the form's class definition:
TForm1 = class(TForm) ... private { private declarations } FFileNameList: TStringList; { list of file names to search } public { public declarations } ... end;
Such fields (FFileNameList in the example above) are accessible inside procedures and functions defined within the form, in particular, inside its event handlers.
*.pas
of the given unit to the project folder.
If it has an associated form,
then also include the *.lfm
file.
Visibility: default, protected, private, public
You can put functionality in
Separate algorithmic code from GUI code. In particular, do not put algorithmic code directly inside event handlers, and preferably not even in the form's unit.
Callbacks ...