14. fejezet: Az első grafikus alkalmazás
A Lazarus IDE segítsége már szöveges alkalmazásoknál is jól érzékelhető volt. Egy egyszerűbb grafikus alkalmazásnál pedig a kód jelentős részét a Lazarus készíti el. A fejlett (4. generációs) szerkesztőben a grafikus felületet összerakhatjuk egérrel, az egyes objektumokat kezelő kód egy része automatikusan megjelenik. A Lazarus alkotóinak határozott elképzelése volt az alkalmazás elkészítésének folyamatáról. Ha ezt követjük, az IDE segítségünkre lesz. Természetesen lehetséges másképpen, más sorrendben is elkészíteni a programot, akkor viszont a Lazarus inkább akadályoz. Ismerkedjünk meg egy egyszerű programon keresztül a fejlesztés lépéseivel!
Eseményvezérelt programozás
Egy grafikus program működése alapjában különbözik az eddig írt programok stílusától. Az eddigi programjaink imperatív stílusban íródtak, vagyis előírták, a programnak milyen műveleteket, milyen sorrendben kell elvégezni. (A strukturált, procedurális programozás ennek a stílusnak a továbbfejlesztése, mely a program logikus szerkezetére és a részfeladatok eljárásokra bontására koncentrál.)
A grafikus program azonban idejének nagy részében arra vár, hogy bekövetkezzen valamilyen esemény (gombra kattintás, ablak mozgatása...), ekkor lefut a beépített vagy általunk megírt eseménykezelő, majd a program tovább vár. Itt tehát a program által végrehajtott tevékenységek sorrendje a külső hatásoktól függ. Ez az eseményvezérelt programozás.
A programunk fő része az eseménykezelő ciklus:
Ismételd
ha van értesítés eseményről, hajtsd végre az eseménykezelőjét
ha van változás a felületen, frissítsd
amíg nincs vége
A grafikus felületet a Windows kezeli, ez számunkra nagy könnyebbség, hiszen a megjelenítést (gombok, szövegmezők), a grafikus elemek kezelését (gomb lenyomása, szöveg beírása) nem nekünk kell elkészíteni. Ha a Windows egy eseményt észlel, üzenetet küld a programunknak (pl. "megnyomták az OK gombot"), ekkor az eseménykezelő ciklus lefuttatja az előre beállított eseménykezelőt. Ha az eseménykezelő valamit módosított a grafikus felületen (pl. egy gomb lenyomására megjelenített egy képet), annak kirajzolására az eseménykezelő futtatása után kerül sor.
Objektumorientált programozás
Az objektumok használata jelentősen megkönnyíti a grafikus felület programozását. Egy objektum nem csak adatokat tartalmazhat (mint pl. egy tömb), hanem az adatokat kezelő eljárásokat is. Így az adataival és az azokat kezelő eljárásokkal együtt egy zárt egységet alkot. A program működése során ezek az objektumok hatnak kölcsön. Pl. van egy Button1
nevű gombunk. Ennek van felirata, ez a Button1.Caption
tulajdonság (a tulajdonság egy objektumban tárolt adat), és van egy Button1.OnClick
eljárása (más néven metódusa), ami a gomb lenyomásakor végrehajtódó eseménykezelő eljárás. Ez az eseménykezelő tartalmazhat egy Label1.Caption:='start'
utasítást, amely egy felirat (szintén objektum) szövegét módosítja. Látható, hogy az objektumot és tulajdonságát pont választja el.
Kezdetben előre elkészített objektumokat használunk, majd létrehozzuk saját objektumainkat.
Az első projekt
A Projekt->Új projekt menüből most az Alkalmazást válaszd. Mivel ez a projektünk mindenképpen több fájlból áll, rögtön mentsd is el egy külön mappába. Most több fájl mentésére is rákérdez a Lazarus. Azt elsőnél (ez az .lpi fájl) adj nevet a projektnek a korábbi szabályok szerint. A második fájl neve maradhat unit1.pas.
A főablakon (itt van a menüsor és jó pár eszköztár), a forráskód-szerkesztőn és az üzeneteken kívül két újabb elemre is szükségünk lesz. Az egyik az objektumfelügyelő, a másik a formszerkesztő. Ha valamelyik eltűnik, használd a Nézet menüt.
A programunk legalább egy ablakot létre fog hozni a képernyőn, ezt az IDE rögtön el is készíti. Ezt hívják Form1
-nek (többnyire megtartjuk az objektumok Lazarus által adott nevét). Az objektumfelügyelőben láthatjuk az egyes objektumok tulajdonságait és eseménykezelőit. Keresd meg a felügyelőben a Form1.Height
tulajdonságot, majd a formszerkesztőben állítsd át egérrel az ablak magasságát! A formszerkesztővel az ablakunk és a benne lévő elemek helyzetét, méretét gyorsan beállíthatjuk.
Más tulajdonságokat a felügyelőben tudunk állítani. Állíts be háttérszínt (Form1.Color
). A clRed
és hasonló konstansok előre beállított számokat tartalmaznak, de használhatsz egyéni színt is. Módosítsd az ablak feliratát is (Form1.Caption
). Ezután futtasd le a programot!
Ez a program még nem sokat tudott. Zárd be az ablakot. Az eszköztárról (Standard fül) válaszd ki az OK-val jelölt gombot (a buboréksúgó jelzi a típusát: TButton
), és kattints a formszerkesztőben. Létrejött egy Button1
nevű gomb. Egészen pontosan Form1.Button1
, mert a Form1
tartalmazza a Button1
objektumot. A Button1.Caption
tulajdonságot írd át "Bezár"-ra.
Ettől a gomb még nem fogja bezárni a formot. Kattints duplán a gombra. Ekkor az IDE létrehozza a gomb megnyomásra reagáló eseménykezelőjének vázát. Adott neki egy logikus nevet. Ezt egészítsd ki így:
procedure TForm1.Button1Click(Sender: TObject); begin Form1.Close; end;
Próbáld ki a programot. Ezután figyed meg a következőket:
A Form1.Close
begépelése közben az IDE megjelenít egy segédablakot, amelyből kiválaszthatod a Form1
megfelelő eljárását vagy tulajdonságát (ha mégsem, nyomj CTRL+szóközt). Mivel egy objektumnak rengeteg tulajdonsága van, nem tudjuk mindet megjegyezni, szerencsére az elnevezésük logikus.
A Close
a Form1
objektum egy eljárása, mely bezárja az ablakot, egyúttal a fő eseménykezelő ciklusnak is vége lesz.
Elegendő lett volna csak a Close
használata, mert most a Form1
(egészen pontosan a TForm1 osztály)eljárását adjuk meg, és az alapból a Form1 objektumból indul ki.
A felügyelőben a Button1
eseményeinél, az OnClick
eseménynél megtaláljuk a legutóbbi eljárásunk nevét. Ezen kívül rengeteg más eseményt is látunk itt, az OnMouseEnter
pl. akkor következik be, ha rávisszük az egeret a gombra. Ehhez most nem rendelünk eseménykezelőt. Ennek ellenére ha a program futásakor ráviszed az egeret a gombra, valami változást látsz. Ennek az az oka, hogy a gombnak vannak alapértelmezett eseménykezelői, amelyek akkor is lefutnak, ha te nem adsz meg ilyet (ezek nagy részét a Windows kezeli).
Mi a különbség a Form1 és a TForm1 között?
Ezzel a magyarázattal most egy kicsit előreszaladunk; nem kell elolvasnod, később még visszatérünk rá.
A TForm
egy Lazarusba beépített objektumtípus, más néven osztály. Ennek leszármazottja a TForm1
osztály, melyet kibővítettünk egyéb objektumokkal (pl. gomb) és eljárásokkal (pl. a gomb eseménykezelője).
A Form1
egy olyan objektum, melynek típusa TForm1
. A programunk indulásakor létrehozza a Form1
objektumot. Ebből következik, hogy a TForm1
osztály alapján akár több egyforma ablakot is készíthetnénk. (Ekkor viszont a gomb eseménykezelőjében már nem szerepelhetne Form1.Close
, csak Close
!)
A projekt bővítése
Szükség lesz a formon még egy gombra (Button2
), és egy TLabel
típusú feliratra (Label1
). Írd át a Labe1.Caption
-t "..."-ra, a Button1.Caption
-t pedig erre: "Szia program". Állítsd át a Label1.Font.Size
-t 20-ra. Készíts eseménykezelőt Button2
-höz:
procedure TForm1.Button2Click(Sender: TObject); begin Form1.Label1.Caption:='Szia programozó!'; end;
(Most is elég lett volna csak Label1.Caption
megadása.)
Feladatok
52. Készíts programot, amely tartalmaz egy "0" feliratú gombot, amely minden megnyomásra eggyel továbbszámol!
53. Készíts programot, amely tartalmaz egy olyan gombot, amely minden megnyomásra a form véletlenszerű helyére ugrik! Használd a Top
(elem bal felső pontjának távolsága a tartalmazó elem tetejétől), Left
(elem bal felső pontjának távolsága a tartalmazó elem bal szélétől), Height
(magasság) és Width
(szélesség) tulajdonságokat!