7. díl - Dialogy, práce se soubory a kalendář

Ostatní jazyky Delphi Dialogy, práce se soubory a kalendář

Jsem rád, že už jste pokročili až k sedmé části! Tentokrát se zaměřím na práci se soubory! Začněme okny pro výběr souboru. Nejprve pro otevírání! V položce Dialogs najděte úplně vlevo OPENDIALOG.

Opendialog

To je jakoby takovéto okno, které se otevře, když chcete něco načíst (otevřít). Tak se podívejme do Object Inspectoru na dvě důležité věci:

  • DefaultExt - zde je uložena koncovka souboru, která se k němu má automaticky přidávat. Např.: htm
  • FileName - zde je uložena adresa souboru
  • Filter - klikněte 2x na položku a v otevřeném okně editujte typy souborů, které se smí otevírat. Vlevo typ souboru popište a vpravo napište jeho koncovku ve tvaru např.: *.htm
  • FilterIndex - zde si vyberete pořadové číslo položky výběru typu souboru, který má být aktivní.
  • Options - zde je spoustu dalších nastavení, jaký má soubor být (viz. 2.bod-SaveDialog)
  • Title - text, který bude nahoře na okně (titulek)

Tak to by byl OpenDialog. Probereme ještě SaveDialog a pak podrobnější práci se soubory.

Napravo od OpenDialogu by měl být SAVEDIALOG.

Savedialog

Má naprosto stejné položky, jako OpenDialog a tak si pouze probereme pár položek Options. Popis odpovídá tomu, když zadáte určité položce True:

  • ofReadOnly - kolonka otevřít jen pro čtení je zaškrtnuta
  • ofHideReadOnly - soubory pouze pro čtení a kolonka otevřít pouze pro čtení se nezobrazí
  • ofPathMustExist - adresa souboru musí existovat, aby se dalo stisknout Otevřít
  • ofFileMustExist - soubor musí existovat, aby se dalo stisknout Otevřít

A to je z těch důležitějších vše! Nyní postupme k používání základních funkcí Open/SaveDialogu: Hlavní asi je zjistit, který soubor si uživatel vybral! K tomu slouží již zmíněná položka FileName. Ta se ale změní i když při výběru souboru kliknete na Storno! Okno (dialogové) pro hledání souboru k načtení otevřete příkazem EXECUTE!

Např.:

OpenDialog1.Execute;

Tím ale nezjistíme, zda uživatel stiskl Storno či OK. K tomu slouží tento příkaz, ale jinak napsaný. Tak, aby byl zároveň Boolean:

if OpenDialog1.Execute then
begin
end

Mezi begin a end napíšete, co se má stát po stisknutí OK. Zeptáte-li se programu na False, splní se příkazy mezi begin a end pokud bude stisknuto Storno.

Práce se soubory

Tak! Dialogová okna už obsluhovat umíte! Teď postupme k samotné práci s externími soubory (s těmi, které prostě nejsou součástí EXE souboru (kromě multimédií). Např. textové soubory, nebo i s vaší vlastní koncovkou). Začněme otevřením souboru:

Nejprve vám uvedu příklad a potom popíšu jeho části:

procedure TOkno.TlacitkoClick(Sender: TObject);
var
  Soubor: file of Integer;
begin
  AssignFile(Soubor, 'Číslo.int');
  Reset(Soubor);
  Read(Soubor, Cislo);
  CloseFile(Soubor);
end;

Mno, tak, máme tu nějakou proceduru. Přesněji proceduru, která se spouští po kliknutí na tlačítko Tlacitko, ale to je teď jedno. Nás zajímá její obsah! Za var máme Soubor: file of Integer; To znamená, že proměnná Soubor bude nějaký externí soubor, se kterým budeme pracovat. Nikde jinde ho ale používat nebudeme a tak ho můžeme vytvořit pouze pro tuto proceduru. file of Ineteger; samozřejmě nenapíšeme u každého souboru! Pouze u toho, který má obsahovat jedno číslo! Chceme-li třeba, aby obsahoval True, nebo False, zapíšeme file of Boolean; OK? Tak to by bylo! Teď ale dál:

AssignFile(Soubor, 'Číslo.int');

To je příkaz pro otevření souboru, který bude stejného typu jako Soubor a bude mít adresu (resp. jméno) Číslo.int! Chcete-li nahradit Soubor, můžete, ale jiná proměnná musí existovat a musí to být proměnná externího souboru! Stejně tak ani proměnná po var se vůbec nemusí jmenovat Soubor! Adresa externího souboru nemusí být Číslo.int, ale musí být mezi apostrofy. Koncovku (to je to za tečkou) můžete napsat jakoukoli. Třeba prd ;-) . Takže budete mít třeba Kukensiův.prd Tak jsme se zasmáli, že? :-D

A teď dál: Reset(Soubor); slouží k samotnému prohlédnutí souboru Soubor (pokud neexistuje, program nahlásí chybu!!!). A dostáváme se k nejhlavnější části: Read(Soubor, Cislo); Tím načteme obsah externího souboru Soubor do proměnné Cislo! Samozřejmě pokud máte Soubor: file of Integer;, musí být Cislo: Integer; Po tomto příkazu už máte obsah Souboru v Cislu a můžete pracovat pouze s Cislem! Nezapomeňte však soubor zavřít! Příliš by to nevadilo, ale proč dělat počítači problémy se zbytečně otevřenými soubory v paměti! K tomu slouží poslední příkaz CloseFile(Soubor); A to je z otevírání asi vše!

Asi vás nepřekvapí, že pro ukládání do souboru jsou skoro jiné příkazy. Budu postupovat stejně jako u předchozího bodu:

procedure TOkno.TlacitkoClick(Sender:
TObject);
var
   Soubor: file of Integer;
begin
  AssignFile(Soubor, 'Číslo.int');
  ReWrite(Soubor);
  Write(Soubor, Cislo);
  CloseFile(Soubor);
end;

Některé příkazy už znáte, že? První 4 řádky tedy přeskočím. A co ten pátý? Ten už taky znáte, že? K němu ale musím připsat poznámku: při otevírání Soubor musel existovat! Zde samozřejmě nemusí. Zde tento příkaz externí soubor Číslo.int vytvoří a pokud už existuje, pouze ho nalezne! ReWrite(Soubor); Tak na tohle si dejte pozor! Po tomto příkazu už ze souboru nic nezjistíte! On totiž smaže veškerý obsah souboru a následující příkaz Write(Soubor, Cislo); do Souboru napíše obsah Cisla. Zde opět musí být Cislo stejného typu jako Soubor (ale bez file of!). No, a zbytek už zase znáte! Takže pokročme k souboru s nápisem (textem)...

Radujete se, že jste to pochopili? Tak honem přestaňte, protože ještě nevíte vše u všech typů proměnných to takhle funguje, ale u stringu byste narazili! Jen si zkuste napsat: Soubor: file of string; Delphi vypíše chybu: [Error] Project1.pas(411): Type 'String' needs finalization - not allowed in file type, [Chyba] Project1.pas(411): Typ 'String' potřebuje zakončení - nedovoleno u typu souboru. Nevíte, jaké zakončení? Tím je myšlen maximální počet znaků! Takže když napíšte: Soubor: file of string[50];, program už chybu nenapíše. Číslo v hranaté závorce samozřejmě můžete změnit podle vlastní potřeby délky stringu. Ale POZOR! Soubory ve Windows s koncovkou txt NEJSOU soubory stringu!!!!! Další zrada, co? Neplačte, jsem tady, abych vám pomohl! :-)

Textové soubory

Soubor: TextFile;

A je to!? NE!!! TextFile může být více řádkový! Pokud zapisujete, vše je normální! Pokud ale chcete číst, narazíte! Napíšete-li totiž Read(Soubor, Memo.Text);, v Memu (viz. 6.část) se vám objeví pouze první řádek! A je tu problém!!!!! A proto vám zde napíšu vzor, podle kterého se můžete řídit, abyste neměli problémy:

procedure TOkno.TlacitkoClick(Sender:
TObject);
var
   Soubor: TextFile;
  Radek: string;
begin
  AssignFile(Soubor, 'Kniha.txt');
  Reset(Soubor);
  while not Eof(Soubor) do
  begin
    ReadLn(Soubor, Radek);
    Memo.Lines.Add(Radek);
  end;
  CloseFile(Soubor);
end;

A jdeme pitvat! První změna je proměnná Radek! To není jako jméno, ale jako řádek (klidně si to pojmenujte Mumuland, nebo jak chcete! Já zde mám proste Radek... NE Radka!:-P ). Tento string je důležitý! Budeme do něj postupně ukládat jednotlivé řádky (nebo pokud se vám líbí, tak Radky :-P ). Dále je změna pětiřádková:

while not Eof(Soubor) do
begin
  ReadLn(Soubor, Radek);
  Memo.Lines.Add(Radek);
end;

A tu si teď pořádně probereme! while not Eof(Soubor) do znamená, že dokud při načítání nenarazíme na konec externího souboru Soubor, program bude neustále opakovat příkazy mezi begin a end! Tím jsme se dostali k ReadLn(Soubor, Radek); Zde si všimněte, že příkaz Read se změnil na ReadLn, což značí, že se má číst a poté přeskočit na další řádek! Zde jsme si tedy uložili jeden řádek do stringu Radek. A v příkazu Memo.Lines.Ad­d(Radek); přidáme Radek na konec obsahu Mema! To se opakuje do té doby, dokud soubor neskončí! A tím máme probranou práci se soubory.

Úplně toho samého výsledku docílíte, když napíšete Memo.Lines.Lo­adfromfile('Kni­ha.txt'); Důvod, proč jsem vám to vysvětloval tak složitě je, že někdy budete chtít načíst textový soubor na pozadí a tedy je zbytečné tam mít memo, které používat nebudete. Ano, můžete ho skrýt, ale tímto způsobem si procvičíte práci se soubory a na jiné než textové soubory tu potom další Memo připravené nemáte.

„To je sice hezký, ale co když chci uložit třeba víc čísel do souboru?“ Jo, tak to teda opravdu se svými znalostmi (z mého návodu neumíte), ale nebojte se, hned vám to řeknu. Hlavní věcí, kterou budete muset znát je novou variantu proměnné. Před chvílí jsem vám ukázal FILE OF a teď nás čeká: ARRAY [] OF. Nebo-li POLE! Pole nějaký prostor pro ukládání. Dejme tomu, že si pro názornou ukázku budeme ukládat třeba Boolean do našeho okolí. To je nejjednodušší proměnná. Buď ano, nebo ne, že? Budeme uvažovat, že 1 Boolean se vejde na 1mm. Takových Booleanů může být spousta a tak si musíme určit limit. Minimální pořadové číslo může být třeba 0. Ale musíme zadat ještě maximální. Takže třeba 9 mm! Tudíž budeme mít 10 čísel (0, 1, 2, 3, 4, 5, 6, 7, 8 a desáté: 9) To, co jsem vám teď napsal, zapíšeme: NejakePole: array [0..9] of . Takže na úsečku 1cm se vejde 10Booleanů. Ale co když přejdeme z úsečky do obdélníku? Pak na 1 centimetr čtvereční vyjde 100 Booleanů! Pole ale musíme zapsat jinak: NejakePole: array [0..9, 0..9] of . Zde už totiž máme dva rozměry. A co když se přemístíme do prostoru? Budeme mít 3 rozměry. Takže krychli 10x10x10mm zapíšeme: NejakePole: array [0..9, 0..9, 0..9] of . Tak můžeme pokračovat dál. Třeba až k 1000 rozměrům! Ale v běžném programování asi použijeme jen tyto tři varianty. Předepsat proměnnou tedy už umíme, ale jak ji použít? Jednoduše:

NejakeCislo := NejakePole[PoradoveCislo];

NejakeCislo je Integer, NejakePole array of Integer a PoradoveCislo je pořadové číslo určitého Integeru v poli NejakePole. Takže v našem případě 0, 1, 2, 3, 4, 5, 6, 7, 8, nebo 9. Opačně to funguje stejně:

NejakePole[PoradoveCislo] := NejakeCislo;

Normální pole už použít umíme. Takže už jen stačí říci, jak ho zapsat do Souboru:

Soubor:file of array [1..24] of Integer;

Nebo třeba:

Soubor:file of array [0..99] of string[20];

A máme probráno POLE!

„Dobře, ale co když chci do souboru uložit třeba skóre ze hry a u každého skóre jméno výherce?“ No problem! Další (poslední) úskalí! Soubor musí být prostě jedna proměnná. A tak vám řeknu, jak vyrobit vlastní proměnnou! Takže: Nejprve si najděte začátek textu programu a tam

type
TForm1 = class(TForm)
private
    { Private declarations }
public
    { Public declarations }
end;

(takhle vypadá většinou pouze nový program, ale i tak věřím, že tuto část najdete! Vždyť sem už jste psali proměnné!) Zde budeme psát mezi type a TForm1 = class(TForm). Nejprve musíme typ proměnné nějak pojmenovat většinou se typy proměnných pojmenovávají na začátku s T (třeba TMaPromenna), ale není to třeba. Spíš to slouží k přehlednosti a že třeba můžeme mít proměnnou MaPromenna : TMaPromenna; A vidíte, zapisuje se stejně, jako všechny normální proměnné. Ale vraťme se zpět pod type. Opět zde ukážu příklad:

type
  TSoubor = record
    Prvni: Integer;
    Vitez: string[20];
    Druhy: Integer;
    Skoro: string[20];
    Treti: Integer;
    NicMoc: string[20];
  end;

  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

Tak takhle by měl vypadat začátek nově vytvořeného programu pouze s typem proměnné TSoubor. TSoubor můžete nahradit svým vlastním názvem, ale = record musí zůstat! Dále už píšete podproměnné. Až po end; A je to!
Můžete třeba zapsat tohle:

type
  TNeco = record
    Cislo: Integer;
    DvacetZnaku: string[20];
   end;

  TCosi = record
    Cislo: Integer;
    DvacetZnaku: string[20];
    Neco: TNeco;
   end;

    TForm1 = class(TForm)
    private
        { Private declarations }
    public
        { Public declarations }
  end;

A jak budeme s naší proměnnou pracovat? Ukažme si práci s naší ukázkovou proměnnou typu TCosi. Nejprve si vytvoříme proměnnou: Cosi: TCosi;
A teď už k samotnému zápisu:

Cosi.Cislo := 12;
Cosi.DvacetZnaku := 'Ahoj ňoumo!';
Cosi.Neco.Cislo := 15;
Cosi.Neco.DvacetZnaku := 'Jsi truhlík!';

Pochopili jste způsob zápisu? Stejně jako u objektů ve vlastní proměnné oddělujete různé položky tečkou.

Gauge

Tak jsem konečně probral většinu proměnných, takže ještě probereme 2 objekty. Konečně navštívíme položku Samples. A úplně vlevo máme GAUGE - Instalovali jste někdy nějaký program? Tak to určitě znáte takový ten rámeček s počtem procent a měnícím se proužkem barvy, která se pohybuje doprava. A to je právě GAUGE. Tak honem k položkám v Object Inspectoru:

  • BackColor - To bude asi nějaká barva! Ano. Barva pozadí. Tedy té části, která se ještě neprovedla :-)
  • BorderStyle - Opakování matka moudrosti. Zadáte-li bsSingle, bude okolo Gauge rámeček, pokud bsNone, nic okolo nebude.
  • Font - Zde nastavíte font, který se použije pro počet procent
  • ForColor - To bude asi taky nějaká barva! Ano. Barva části, která se už provedla.
  • Kind - Zde si určíte typ zobrazení:
    • gkHorizontalBar-normální pruh zleva přibývající
    • gkNeedle-něco jako ukazatel rychlosti v autě (ručička zleva přes vršek doprava)
    • gkPie-něco jako ukazatel populace (ovál, v němž je vyplněn úsek ve stylu krájení dortu)
    • gkText-pouze pozadí a počet procent
    • gkVerticalBar - pruh nepřibývá zleva, ale odspodu
  • MaxValue - Maximální hodnota (ne počet procent, ale počet jakýchsi bodů)
  • MinValue - Minimální hodnota (ne počet procent, ale počet jakýchsi bodů)
  • Progress - A zde je konečně počet bodů (ne procent), které budou splněny
  • ShowText - Zadáte, zda se má zobrazovat počet procent. Víc vám asi neřeknu. Jen že to hodně používám. Ale pojďme dál. Ke druhému objektu!

Calendar (kalendář)

Blížíme se ke konci 7.dílu návodu. Asi šestý odleva by měl být obrázek kalendáře: CALENDAR - Ve Windows v nastavení data máme také takový kalendář. V Object Inspectoru máme:

  • Day - číslo dne v měsíci, který bude zatrhnutý
  • GridLineWidth - šířka čar tabulky, oddělující od sebe dny
  • Month - číslo měsíce, podle kterého budou v kalendáři seřazeny dny (po, út, st...)
  • StartOfWeek - čím bude začínat týden (1=pondění, 2=úterý...6=sobota, ale neděle je 0!)
  • UseCurrentDate - nastavíte-li True, Day, Month a Year se nastaví na datum, které právě je. A každý den se datum změní na to, které je v počítači nastavené!
  • Year - nastavíte rok, podle kterého budou seřazeny dny

Je sice pravda, že jsem to trochu ošidil, ale i kalendář se vám může hodit!

Program

A je tu konec návodu. Takže by to chtělo skrnutí: Začněme jenom takovým zpestřením programu: Vložíme Gauge, pojmenujeme ho Ukazatel, šířku (Width) nastavíme dvakrát větší než výšku (Height), Progress na 0, MaxValue na 100, MinValue na 0 a Kind na gkNeedle. Vytvořte Boolean Doprava. Klikněte davkrát na okno a pište: Doprava := True; Teď vložíme Timer (se jménem Cas) a Interval nastavíme na 20. Klikněte na něj 2x a pište:

if Doprava then
begin
  if Ukazatel.Progress < 100 then
    Ukazatel.Progress := Ukazatel.Progress + 1 else
    Doprava := False;
end else
begin
  if Ukazatel.Progress > 0 then
    Ukazatel.Progress := Ukazatel.Progress - 1 else
    Doprava := True;
end;

A máme vytvořen zajímavý efekt. Stačí? Co? Že jsme si procvičili pouze jeden objekt? Tak jo, jedeme dál: Vytvořte CheckBox, pojmenujte ho Obsahuje a Checked nastavte na False. Dále si vytvořte Edit se jménem Napis, žádným Textem a s MaxLength 20! A můžeme pokročit k editaci vlastní proměnné: Nyní byste na začátku programu měli mít přibližně toto:

type
TForm1 = class(TForm)
Ukazatel: TGauge;
Cas: TTimer;
Obsahuje: TCheckBox;
Napis: TEdit;
procedure FormCreate(Sender: TObject);
procedure CasTimer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Doprava : Boolean;
end;

Pokud jste postupovali přesně podle návodu, mělo by to být takovéhle! Jak si můžu být jistý? Pod TForm1 = class(TForm) se totiž postupně připisují objekty, které vytvoříte. A pod objekty se píší stejným způsobem procedury (to už jistě víte :-) ). A pod public byste měli psát své proměnné! Ale k věci: Mezi type a TForm1 = class(TForm) pište:

TMujSoubor = record
Obsahuje: Boolean;
Napis: string[20];
end;

Typ proměnné už tedy nadefinován máme, teď už jen vytvořit samotnou proměnnou! Nebudu vám radit jak, jen zde vypíšu, jak má vypadat výše vypsaný začátek po úpravách:

type
TMujSoubor = record
Obsahuje: Boolean;
Napis: string[20];
end;

TForm1 = class(TForm)
   Ukazatel: TGauge;
Cas: TTimer;
   Obsahuje: TCheckBox;
Napis: TEdit;
   procedure FormCreate(Sender: TObject);
procedure CasTimer(Sender: TObject);
private
   { Private declarations }
public
   { Public declarations }
   Doprava : Boolean;
MujSoubor : TMujSoubor;
end;

Jistě jste poznali, že nová proměnná typu TMujSoubor se bude jmenovat MujSoubor. Teď se ale přemístíme zpět do grafické editace programu a vložíme další objekty: Tlačítko Otevrit (Caption bude Otevřít) a tlačítko Ulozit (Caption Uložit). Co teď? OpenDialog jménem Open a SaveDialog jménem Save. Nastavení budou mít oba dialogy stejné: DefaultExt bude kpf a v tabulce Filter do Filter Name napište Kukensius Pages File a pod Filter *.kpf A to je z důležitého (a stejného) nastavení vše.

Konečně můžeme psát program (to vás baví, že? :-) )!
Klikněte 2x na okno a do procedury připište:

MujSoubor.Obsahuje := False;
MujSoubor.Napis := '';

Klikněte dvakrát na CheckBox Obsahuje a napište:

MujSoubor.Obsahuje := Obsahuje.Checked;

Teď zase dvojitě klikněte na Edit Napis a pište:

MujSoubor.Napis := Napis.Text;

Tím bychom měli tu nudnější část odbytou a popojdeme k závěrečné: Klikněte (2x) na Ulozit a před begin připište: var Soubor: file of TMujSoubor; a za begin:

if Save.Execute then
begin
AssignFile(Soubor, Save.FileName);
ReWrite(Soubor);
Write(Soubor, MujSoubor);
CloseFile(Soubor);
end;

A u Otevrit podobně. Před begin napište to samé a za (pod) něj tohle:

if Open.Execute then
begin
  AssignFile(Soubor, Open.FileName);
  Reset(Soubor);
  Read(Soubor, MujSoubor);
  CloseFile(Soubor);
  Obsahuje.Checked := MujSoubor.Obsahuje;
  Napis.Text := MujSoubor.Napis;
end;

A program je hotov! Teď si můžete napsat něco do Editu a zaškrtnou CheckBox a uložit. Až vypnete program a znovu ho spustíte, můžete si jakýkoli soubor typu TMujSoubor s koncovkou kpf otevřít a zjistit, co jste před uložením měli napsáno v Editu a zda byl CheckBox zaškrtnutý.

...Kukensius


 

Stáhnout

Staženo 466x (215.47 kB)
Aplikace je včetně zdrojových kódů v jazyce Delphi

 

  Aktivity (1)

Článek pro vás napsal Kukensius
Avatar
Jméno: Lukáš Kučera alias Kukensius<br/> Narození: říjen 1987 (ve znamení vah)<br/> Bydliště: Jihlava, Česká Republika<br/> Studium: 1. ročník magisterského studia<br/> Škola: Vysoké učení technické v Brně<br/> Fakulta: Fakulta elektrotechniky ...

Jak se ti líbí článek?
Celkem (1 hlasů) :
55555


 


Miniatura
Všechny články v sekci
Delphi

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!