6.1. Een formulier om te kiezen
We willen een programma maken waarbij je woordjes in kunt voeren met hun vertaling
in het engels, frans of een andere taal.
Die woordjes worden vastgelegd in een bestand.
En dan kun je jezelf overhoren: er wordt steeds een woordje getoond en dan moet
je de vertaling geven.
Als het programma wordt gestart dan wordt er alleen maar een menu getoond, zoals hier rechts.
(Je kunt ook een professioneel menu maken, met een menubalk; daarover lees je in hoofdstuk 7 van Delphi).
Als je dan klikt op "Voer in", dan verschijnt er een nieuw formulier dat er uitziet zoals hieronder bij paragraaf 2.
We gaan ervan uit dat je maar met één woordjesbestand werkt, met de naam "woordjes.txt".
In hoofdstuk 7 van Delphi zie je hoe je verschillende woordjesbestanden kunt openen en/of bewaren.
We beginnen met het eerste formulier. Je zet er 3 "buttons" op,
met de tekst zoals hierboven rechts.
Als naam van het formulier voer je in: frmMenu, en als opschrift (Caption): Menu
Verder doe je er nog niets mee.
6.2 Nieuw formulier maken; woorden invoeren en bewaren; arrays
Klik in het menu op File, dan op New, en dan op Form.
Dan krijg je een tweede (leeg) formulier in beeld.
Standaard wordt dat "form2" genoemd, maar dat kun je veranderen.
Vul in het propertiesvenster voor dit formulier bij Name in : frmVoerin ,
en bij Caption : Woordjes invoeren
Zet er 2 labels met als opschrift Woord: en Vertaling: en 2 buttons met als opschrift OK en Stop
op. De naam van de OK-button verander je in cmdOK en de naam van de stop-button in cmdStop.
Verder zet je er twee tekstvensters op.
De bovenste geef je als naam txtWoord, en die daaronder
geef je als naam txtVertaling
Als je woorden wilt invoeren en opslaan als je klaar bent met het invoeren, dan moet de computer alle woordjes onthouden.
Als er honderd woordjes zijn ingevoerd dan moet hij die alle honderd onthouden, en ook de vertaling er van.
Daar ga je natuurlijk niet 100 aparte variabelen-namen voor bedenken, je doet dat met een
array zoals we dat ook in Pascal hebben gezien.
Je declareert een array "woord[....]", zodat in de variabele woord[1] het eerste
woord wordt bewaard, in woord[2] het tweede woord, enz.
De opdracht daarvoor is: var woord: Array[1..100] of String;
Verder moeten ook de vertalingen van die woorden worden onthouden, dat doe je met de opdracht:
var vertaling: Array[1..100] of String;
Ook het aantal woordjes, dat is ingevoerd, moet worden onthouden. Daarvoor gebruiken we de variabele aantal
Dit moeten globale variabelen zijn, we declareren ze dus
boven de regel met implementation, waar ook het formulier wordt gedeclareerd.
Bij procedure TfrmVoerin.FormCreate(Sender: TObject); zet je de volgende code:
procedure TfrmVoerin.FormCreate(Sender: TObject);
begin
aantal := 0;
end;
Voer bij de OK-knop als event-handler het volgende in:
procedure TfrmVoerin.cmdOKClick(Sender: TObject);
begin
// het woord met de vertaling wordt opgeslagen
// in de variabele woord[..] en vertaling[..]
aantal:=aantal+1;
woord[aantal]:=txtWoord.Text;
vertaling[aantal]:=txtVertaling.Text;
// de editvensters worden leeg gemaakt
txtWoord.Text := '';
txtVertaling.Text := '';
end;
Voer bij de Stop-knop als event-handler het volgende in:
procedure TfrmVoerin.cmdStopClick(Sender: TObject);
var i: integer;
begin
// het bestand wordt opgezocht
assignFile(f,'woordjes.txt');
// de schrijfwijzer wordt aan het begin van het bestand gezet
REWRITE(f);
// de woorden met de vertaling worden opgeslagen
// in het bestand "woordjes.txt"
for i := 1 to aantal do
begin
WRITELN(f,woord[i]);
WRITELN(f,vertaling[i]);
end;
// het bestand wordt afgesloten
CloseFile(f);
// Het invoer-formulier wordt verwijderd
frmVoerin.close;
end;
De tekstfile f moet je als globale variabele declareren, omdat hij in verschillende procedures wordt gebruikt.
Dus boven de regel met implementation komt: (het eerste staat er al) var
frmVoerin: TfrmVoerin;
// declaratie van de file
f:textFile;
// globale rij-variabelen voor de woorden, vertalingen enz.
// aantal geeft aan hoeveel woorden zijn ingevoerd
woord, vertaling: Array[1..100] of String;
aantal: integer;
6.3 Een nieuw formulier tonen en weer verwijderen.
Ga dan terug naar het eerste formulier (Klik bovenaan op het tabblad unit1).
Zorg er voor dat je het ontwerpvenster in beeld hebt (klik onderaan op het tabblad design Klik dan dus op frmMenu, en op View Form.
Dubbelklik in het formulier op de button met "Voer in", dan kun je de
bijbehorende programmaregels invoeren.
Voer bij procedure TfrmMenu.cmdVoerinClick de volgende code in:
procedure TfrmMenu.cmdVoerinClick(Sender: TObject);
var
formVoerin: TfrmVoerin;
begin
frmVoerin.ShowModal;
end;
Dat heeft tot gevolg dat als je op die button klikt het formulier met de naam "frmVoerin" wordt
ingeladen en getoond.
En dat was de bedoeling !
Maar er moet meer gebeuren, anders werkt het nog niet.
Klik in het menu op File, en dan op Use Unit.
Voer in het venster, dat dan verschijnt unit 2 in,
want de programmacode die bij frmVoerin hoort zit in unit 2.
Dan wordt aan de programmacode van unit 1 toegevoegd, onder implementation: uses unit 2;
Klik dan in het menu op Project, en dan op Options.
Dan verschijnt het Options-venster (zie hieronder)
Daarin zie je (zie het venster hier onder) dat frmMenu het main form is,
dat betekent dat bij het opstarten het formulier frmMenu getoond wordt.
Verder zie je onder Auto-create forms dat alle formulieren bij de start van het programma worden aangemaakt (in het
geheugen). Als een programma uit veel formulieren bestaat dan neemt dat nogal wat geheugenruimte in beslag, en dan kun je de
formulieren (behalve de eerste, want die moet er bij de start natuurlijk wel zijn) beter onder Available forms zetten.
Dat doe je door op die formulieren te klikken, en dan te klikken op > tussen Auto-create forms en Available forms
Dan zijn de formulieren wel beschikbaar, maar bij de start nog niet gecreëerd.
Dan moet er, elke keer als zo'n formulier getoond moet worden, een extra opdracht bij voor de creatie voor het formulier.
De opdracht daarvoor is (bijv. voor het frmVoerin-formulier:
Als er op de stop-knop wordt geklikt moet het formulier verdwijnen. Daarom moet
bij de procedure TfrmVoerin.cmdStopClick(Sender: TObject) o.a. de volgende regel code worden ingevoerd:
frmVoerin.close;
Dat heeft dus tot gevolg dat, als je op de stop-knop klikt, het invoer-formulier verdwijnt
(en je kunt verder met het eerste, want dat staat er nog)
6.4 Woorden inlezen, arrays
Als je jezelf wilt overhoren dan moet de computer allereerst de woordjes inlezen uit het bestand op de schijf.
En dan moet hij alle woordjes onthouden.
Als er honderd woordjes zijn ingevoerd dan moet hij die alle honderd onthouden, en ook
de vertaling er van.
Daar gebruik je natuurlijk weer een array voor.
We gebruiken weer een array "woord[....]", zodat in de variabele woord[1] het eerste
woord wordt bewaard, in woord[2] het tweede woord, enz.
En we gebruiken weer een array "vertaling[....]"
En dan moet de computer ook nog onthouden welke woorden al wel geweest zijn, en welke
niet, want er moet natuurlijk niet twee keer het zelfde woord gevraagd worden.
Daarvoor heb je zogenaamde boolean-variabelen nodig, die alleen maar
true of false kunnen zijn. Die variabele kunnen we bijv. geweest[....] noemen.
De opdracht daarvoor is: var geweest: Array[1..100] of Boolean;
Dit moeten allemaal globale variabelen zijn (ook die van de woordjes), we declareren ze dus
boven de regel met implementation, waar ook het formulier wordt gedeclareerd.
We beginnen met het overhoorformulier, dat moet er uitzien als hiernaast.
Klik in het menu op File, dan op New, en dan op Form.
Dan krijg je weer een nieuw leeg formulier in beeld.
Vul in het propertiesvenster voor dit formulier het volgende in:
bij Name: frmOverhoor
bij Caption: Woordjes overhoren
Zet drie labels op het formulier met als opschrift Woord: en Vertaling: en Tot nu toe goed: en één
met een 0.
Die labels noem je lblWoord, lblVertaling, lblGoed en lblAantalgoed
Zet er ook drie buttons op met als opschrift OK en Naar menu en Lees bestand in
De naam van de OK-button verander je in cmdOK
en de naam van de Naar-menu-button in cmdNaarmenu.
en de naam van de Lees-bestand-in-button in cmdLees.
Verder zet je er twee editvensters op.
De bovenste geef je als naam txtWoord
en die daaronder geef je als naam txtVertaling
In het begin moet alleen de knop met Lees bestand in zichtbaar zijn. Dus bij
procedure TfrmOverhoor.FormCreate(Sender: TObject); zorg je er voor dat alle andere objecten onzichtbaar zijn.
Boven de regel met implementation, waar ook het formulier wordt gedeclareerd, zet je de volgende regels (de eerste
staat er al):
var
frmOverhoor: TfrmOverhoor;
// globale rij-variabelen voor de woorden, vertalingen enz.
// a is het nummer van het woord dat aan de beurt is
woord, vertaling Array[1..100] of String;
geweest: Array[1..100] of Boolean;
aantalgoed, aantalgeweest, aantal, a: integer;
// declaratie van de file
f:textFile;
Bij procedure TfrmOverhoor.FormCreate(Sender: TObject); zet je de volgende programmaregels:
procedure TfrmOverhoor.FormCreate(Sender: TObject);
begin
lblWoord.visible:=false;
lblVertaling.visible:=false;
lblGoed.visible:=false;
lblAantalgoed.visible:=false;
txtWoord.visible:=false;
txtVertaling.visible:=false;
cmdOK.visible:=false;
cmdNaarmenu.visible:=false;
end;
Bij procedure TfrmOverhoor.cmdLeesClick(Sender: TObject); zet je de volgende programmaregels:
(in de commentaarregels lees je het hoe en waarom)
procedure TfrmOverhoor.cmdLeesClick(Sender: TObject);
var i: integer;
begin
begin
assignFile(f,'woordjes.txt');
// de leeswijzer wordt aan het begin van het bestand gezet
Reset(f);
// We lezen alle woorden in met de bijbehorende vertalingen
// tot het einde van de file is bereikt
//
// in het begin is nog geen enkel woordje aan de beurt
// geweest, daarom: geweest(i):=false;
i:=1;
while not eof(f) do
begin
readln(f, woord[i]);
if not eof(f) then readln(f, vertaling[i]);
geweest[i] := false;
aantal:=i;
i:=i+1;
end;
aantalgoed := 0;
aantalgeweest := 0;
// de objecten moeten nu zichtbaar worden
lblWoord.visible := true;
lblVertaling.visible :=true;
txtWoord.visible:=true;
txtVertaling.visible:=true;
cmdOK.visible:=true;
cmdNaarmenu.visible:=true;
lblGoed.visible:=true;
lblAantalgoed.visible:=true;
cmdLees.visible:=false;
// zorgen voor willekeurige getallen
randomize;
// a moet een willekeurig getal tussen 1 en aantal zijn
a := random(aantal)+1;
// als a dan bijvoorbeeld 3 is dan wordt het derde woordje gevraagd
txtWoord.text := woord[a];
// de cursor wordt in het vertaal-venster geplaatst
txtVertaling.setfocus;
// en het derde woordje moet dan worden geregistreerd als
// geweest zijnde, zodat het niet weer wordt gevraagd
geweest[a] := true;
end;
Bij procedure TfrmOverhoor.cmdOKClick(Sender: TObject); zet je de volgende programmaregels:
procedure TfrmOverhoor.cmdOKClick(Sender: TObject);
begin
geweest[a] := true;
aantalgeweest := aantalgeweest + 1;
if txtVertaling.text=vertaling[a] then
begin
ShowMessage('Goedzo');
aantalgoed:=aantalgoed+1;
lblAantalgoed.Caption:=IntToStr(aantalgoed);
end
else
begin
ShowMessage ('Neen, het juiste antwoord is '+ vertaling[a]);
end;
if (aantalgeweest=aantal) then
ShowMessage('Alle woorden zijn geweest')
else
while (geweest[a]=true) do
begin
a := random(aantal)+1;
txtWoord.text := woord[a];
txtVertaling.Text := '';
txtVertaling.setfocus;
end;
end;
en tenslotte zet je bij procedure TfrmOverhoor.cmdNaarmenuClick(Sender: TObject); de volgende code:
procedure TfrmOverhoor.cmdNaarmenuClick(Sender: TObject);
begin
// Het overhoor-formulier wordt verwijderd
frmOverhoor.close;
end;
6.5 Opdrachten.
Opgaven. Maak nu opgave 6 van de oefenopgaven van Delphi
|