[DELPHI] 1. podstawy + kalkulator

Dzia³ po¶wiêcony programowaniu

Moderators: Frost, Luigi, HQTM-Team

User avatar
Maxoff
HQTM-Team
Posts: 3434
Joined: 2004-07-06, 18:28
Location: Poland
Contact:

Post by Maxoff »

Tak, pracuje nad tekstami. Odrobina cierpliwości, musze się zastanowić jak to przystepnie napisać.

Wracając do obrazka i problemu Znaga. Chodziło mi o umieszczenie w tle okna obrazka. Podpowiedziałem, że można to zrobić używając Image. I tak jest. Należy znaleźć Image na panelu komponentów (zakładka Additional), przenieść go na formę a nastepnie dwa razy na nim kliknąć. Otworzy się okienko ładowania obrazka.

Gdy już mamy to załatwione, to należy przesunąć go na tło (aby nie zasłaniał przycisków). Można to zrobić klikając na Image prawym przyciskiem i wybierając Send To Back.

Teraz pozostaje kwestia dopasowania obrazka do okna. W tym celu trzeba zrobić dwie rzeczy:
1. ustawić Image aby zawsze miał wielkość okna, co można łatwo rozwiązać za pomocą właściwości Align (szczególy w Helpie - musicie się nauczyć go używać)
2. druga kwestia jest taka, okienko ma powiedzmy 500x500 a obrazek 20x20, a więc nie zajmuje całej przestrzeni. Co zrobic ?? Można użyć większy obrazek ;) albo przełączyć Stretch na true :D (co to zrobi ?? )

Czekam na screeny... ćwiczene to pozwoli Wam pobawić się przysłanianiem kontrolek, dopasowywaniem rozmaru kontrolki do okna oraz helpem.

PS. Staram się jak najwięcej na początku pokazywać metod klikowych, takich aby nie trzeba było pisać kodu. Do kodu jeszcze przejdziemy a wtedy zacznie się zabawa na poważnie. Tak jak pisałem, dzisiaj sprawimy aby kalkulator zaczął działać :D

PS2. Nie wiem czy to już pisałem, nauka programowania czy zapoznanie się z środowiskiem wymaga dużo własnej pracy. Mile widziane są róznego rodzaju eksperymenty i sprawdzanie co do czego służy :D Jeśli coś robiliście i Wam nie wyszło, to piszcze a wspólnie rozwiążemy problem. Niedugło stworzę odpowiedni dział Programowanie oraz całą strukturę, wtedy będzie łatwiej.
... You only have to know how to prepare query, google will do the rest ...
... My software ...
... Guide to Punctuation ...
User avatar
[*CzApLa*]
Fantastic Order Of Lords
Posts: 1169
Joined: 2004-07-15, 19:12
Contact:

Post by [*CzApLa*] »

Ja zrobie te ćwiczenia jak mi Delphi odpali bo uruchamiam i pisze delphi nie odpowiada i musze z 20 razy zresetowac komp aż mi wejdzie, ja wam pokarze mój experyment - prawie cały notatnik tylko coś się uszkodził i pewnie od nowa go zrobić musze :|
Jak odpale delphi to będe zadowolony :D
Maxoff nie musisz się śpieszyć, mamy czas (zanim 20 razy zresetuje komp a to zajmie gdzieś z 5 min to troche potrwa :D)
Nie dyskutuj nigdy z głupcem - najpierw Cię sprowadzi do swojego poziomu, a potem wykończy doświadczeniem.
KCP-Zmieniamy świat na plus.
KCP-(Nie)Umiemy opowiadać bajek.
bumbum
HQTM-Team
Posts: 25
Joined: 2005-01-04, 16:04

Post by bumbum »

Ej sorry za off top ale nigdzie nie mogê znale¼æ programu Borland Delphi 6.0 Personal. Wiem ¿e niby na stronce producenta jest ale i tam sobie nie radzê
User avatar
Maxoff
HQTM-Team
Posts: 3434
Joined: 2004-07-06, 18:28
Location: Poland
Contact:

Post by Maxoff »

Użyj Delphi 7 Pesonal, nie ma większych różnic. Kurs piszę właśnie na 7 Personal, bo 6 nie miałem pod ręką.
... You only have to know how to prepare query, google will do the rest ...
... My software ...
... Guide to Punctuation ...
User avatar
ZNag
HQTM-Team
Posts: 3526
Joined: 2004-07-15, 19:20
Location: W³oc³awek [PL]
Contact:

Post by ZNag »

Ehhhh... Wczoraj właśnie używałem funkcji image do umieszczenia zdjęcia, ale jak klikam 2 razy na obramowanie, to pojawia się tylko okno z kodem :/ Nie wiem co zrobić :(
•ZNag - Strona domowa
•Intel Core 2 Quad Q9400 2,66GHz, 4GB DDR2 800MHz (Dual Channel), ATI Radeon HD 4850 512MB, 500GB HDD + Pendrive 4GB; Samsung SyncMaster T220
User avatar
Maxoff
HQTM-Team
Posts: 3434
Joined: 2004-07-06, 18:28
Location: Poland
Contact:

Post by Maxoff »

A więc zaczynamy na poważnie...

Ogólna koncepcja prostego kalkulatora zakłada wprowadzanie danych jedynie za pomocą kliknięć w odpowiedni klawisz, wprowadzanie za pomocą klawiatury na razie zostawiamy (nie będziemy robić wszystkiego na raz).

Zaczyniemy od prostej czynnośći. Po kliknięciu 1 chcemy aby na wyświetlaczu pojawiło się 1. Gdy drugi raz kliknięmy 1 to na wyświetlaczu będzie już 11, itp.

Zasada jest taka:
0 +1 -> 1
1 +1 -> 11
11 +1 -> 11
Wszystko jest proste z wyjątkiem pierwszej sytuacji, gdy mamy zero, ale co to dla nas.

Do dzieła. Klikamy dwa razy w przycisk nr 1. Jeśli używacie tego samego programu co na początku, to wyświetli nam się procedure z ShowMessage('Witaj!'); (należy skasować tą linie). Jeśli jest to nowy program to zostanie utworzona procedura. Zanim coś napiszemy musimy sprawdzić jak nazywa się nasza kontrolka Edit (klikamy Edit na formie i odszukujemy Name w Object Inspector). U mnie jest to edtNumber (dla ułatwienie proponuję użyć tej samej nazwy w Waszym projekcie). Następnie wracamy do naszego zdarzenia (wystarczy dwa razy kliknąć w przycisk). Zaczniemy od prostej wersji, a mianowicie chcemy dopisać 1 na końcu wyświetlanego tekstu. Kod będzie wyglądał tak (na razie nie wpisujcie go):

Code: Select all

edtNumber.Text:=edtNumber.Text+'1';
Prawda, że nic skomplikowanego ?? Teraz wpiszmy kod i wyjaśnimy co poszczególne element znaczą. Zaczynami od napisania edt a następnie wciskamy Ctrl+Space (alternatywny zapis ^Space). Środowisko wyświetli mam listę istniejących kontrolek, obiektów i zmiennych, które zaczynają się od edt. Na liście prawdopodobnie będzie tylko jedna pozycja edtNumber. Zatwierdzamy ją za pomocą Entera. Jak widać, wpisywanie długich nazw nie jest trudne i nawet nie trzeba ich pamiętać. Wystarczy, że wiemy od czego się zaczyna. Prawda, że użyteczne ??

Wpisaliśmy już edtNumber, czyli nazwę naszej kontrolki. Teraz chcemy zmienić wyświetlany tekst. Jak już wspominałem, tekst w przypadku Edit przechowywany jest w polu Text. Musimy się do niego odwołać. Text jest składową kontrolki edtNumber, a w celu odwołania się do składowych używamy . (kropki). Tak więc wciskamy . (kropkę) Środowisko automatycznie wyświetli nam listę dostępnych właściwości. Aby nie bawić się w przewijanie listy wpisujemy jeszcze te, co zawęzi wybór do jedej pozycji Text. Wciskamy Enter i mamy już wpisane:

Code: Select all

edtNumber.Text
Teraz przyjżyjmy się symbolowi := Jest to przypisanie wartości. Lewej stronie przypisywa jest wartość generowana przez prawą stronę, np x:=5 przypisze zmiennej x wartość 5. edtNumber.Text:='Test'; przypisze własności Text wartość tekstową 'Test' (dla przypomnienia w Pascalu wartości zmiennych tekstowych - string - wpisujemy w apostrofach). Oczywiście błędem będzie edtNumber.Text:=5; gdyż pole Text jest typu tekst (string) a nie liczbą (integer). Aby przypisać jakąś liczbę do zmiennej tekstowej możemy ją po prostu zapisać jako '5' albo użyć specjalnej funkcji konwertującej IntToStr(liczba), czyli w tym przypadku IntToStr(5). Wynik będzie taki sam, czyli '5'. Druga metoda (z IntToStr) jest bardziej uniwersalna.

Wracając do naszego kodu. Pod pole Text chcemy podpisać starą wartość + jedynkę na końcu. A więc odczytujemy starą wartość, czyli wpisujemy edtNumber.Text (używając ^Space dla wygody) a następnie dodajemy do tego '1'. W rezultacie otrzymujemy:

Code: Select all

  edtNumber.Text:=edtNumber.Text+'1';
Bardziej uniwersalnym odpowiednikiem będzie:

Code: Select all

  edtNumber.Text:=edtNumber.Text+IntToStr(1);
Oczywiście zamiast drugiego edtNumber.Text możemy wpisać np 'Ala ma kota' (w ramach ćwiczeń proponuje sprwadzić jaki będzie efekt) a zamiast 1 możemy użyj jakiejś zmiennej liczbowej (o czym później).

Proponuję skompilować program i sprwadzić jaki będzie efekt...

Otrzymamy 011111, co nas oczywiście nie zadowala :) Musimy to poprawić. Jak to rozwiązać ??

Bardzo prosto. Po prostu, jeśli wpisany tekst po przekonwerowaniu na liczbę jest równy 0 (czyli wpisane jest '0') to zamieniamy go na '1', a jeśli nie to dopisujemy do niego '1'. W tym celu użyjemy instrukcji warunkowej:

Code: Select all

if warunek
  then akcja_gdy_warunek_jest_prawdziwy (bez średnika)
  else akcja_gdy_warunek_jest_fałszywy;
która dla osób mających styczność z Pascalem nie jest niczym nowym. Musimy jedynie uzupełnić warunek i akcje. Dla przypomnienia jeśli akcja ma więcej niż jedną instrukcję to należy dopisać przed nią begin a po niej end:

Code: Select all

if warunek
  then begin
         akcja_1;
         akcja_2; 
       end
  else akcja;
Teraz uzupełnimy szablon. Zaczniemy od warunku. Musimy spradzić czy aktualna wartośc jest równa 0 (można cały ten problem rozwiązać inaczej, ale wybrałem tą wersję aby pokazać kilka ciekawych rzeczy). A więc oczytujemy aktualną wartość i porównujemy ją do '0' (porównanie tekstu)

Code: Select all

if edtNumber.Text='0'
można także skonwertować tekst na liczbę funkcją StrToInt i porównać do zera liczbowego, czyli:

Code: Select all

if StrToInt(edtNumber.Text)=0
i przy tym rozwiązaniu pozostaniemy. Dla przypomnienia := to podstawienie wartości, a = to porównanie (dla zainteresowanych w C/C++ jest odpowiednio = i !=).
Następnie napiszemy akcje dla podmieniania zera, będzie ona bardzo prosta

Code: Select all

  then edtNumber.Text:=IntToStr(1)
oraz dla dopisanie jedynki (to co robilismy wcześniej)

Code: Select all

  else edtNumber.Text:=edtNumber.Text+IntToStr(1);
Całość będzie wyglądała następująco:

Code: Select all

if StrToInt(edtNumber.Text)=0
  then edtNumber.Text:=IntToStr(1)
  else edtNumber.Text:=edtNumber.Text+IntToStr(1);
Skompilujce program i sprawdzcie czy działa...

Pozostaje dopisać takie same akcje dla pozostałych przycisków, co może być męczące. Jeśli ktoś chce to zrobić, to proszę bardzo, ja jestem na to zbyt leniwy 8) Dodatkowo kopiowanie kodu (większego niż jedna linijka) do różnych procedur jest mało efektywne, gdyż jeśli coś zmieniamy to musimy to zrobić 9 razy co nie jest wygodne. My rozwiążemy to lepiej, ale o tym napiszę gdy zrealizujecie powyższe ćwiczenie :D

[ Added: 2005-03-03, 19:00 ]
Znag wrote:ale jak klikam 2 razy na obramowanie, to pojawia się tylko okno z kodem
Reczywiście, sorry mój błąd. W starszym Delphi tak to działało, tutaj zmienili. Jednak nie stanowi to problemu, wystarczy odnaleźć w Object Inspektorze pole Picture i kliknąć ... (polecam przeglądać Object Inspektora, można znaleźć tam trochę ciekawych rzeczy).

PS. Odnosnie 9 przycisków, które mają właściwe ten sam kod, to chętnie wysłucham Waszych propozycji rozwiązania tego problemu i je skomentuje.
... You only have to know how to prepare query, google will do the rest ...
... My software ...
... Guide to Punctuation ...
User avatar
Luigi
Moderator
Posts: 475
Joined: 2004-07-15, 19:11
Location: z mm.li.pl
Contact:

Post by Luigi »

Ok ja mam -> Klik (działają klawisze 1-9)

Tylko, że nie bardzo rozumiem skąd Ci się wzięło 011111, w związku z tym nie rozumiem dalszej części... :/
Po co to jest w ogóle ?
Przecież jak wpiszemy

Code: Select all

edit1.Text:=edit1.Text+ inttostr(1);
to po kliknięciu w 1 będzie nam się jednyka pokazywać w edit1.
Jeśli klikniemy 1 dwa razy to będzie widać 11
trzy -> 111
itd.
User avatar
Maxoff
HQTM-Team
Posts: 3434
Joined: 2004-07-06, 18:28
Location: Poland
Contact:

Post by Maxoff »

Skąd, że kalkulator standardowo wyświetla 0 (a nie pusty edit), a wtedy występuje problem przeze mnie opisany.

PS. Jak rozwiązałeś problem 9 jednakowych przycisków, które robią dokładnie to samo (inna jest tylko cyfra) ??
... You only have to know how to prepare query, google will do the rest ...
... My software ...
... Guide to Punctuation ...
User avatar
Luigi
Moderator
Posts: 475
Joined: 2004-07-15, 19:11
Location: z mm.li.pl
Contact:

Post by Luigi »

Leciałem na piechotę czyli dla Button1Click:

Code: Select all

begin
edit1.Text:=edit1.Text+ inttostr(1);
end;
Button2Click:

Code: Select all

begin
edit1.Text:=edit1.Text+ inttostr(2);
end;
Button3Click:

Code: Select all

begin
edit1.Text:=edit1.Text+ inttostr(3);
end;
itd.

A co do tego 0 -> to nie mogę jakoś zrobić aby mi się to 0 wyświetliło i aby trzeba było użyć if... then... ;-)
User avatar
Maxoff
HQTM-Team
Posts: 3434
Joined: 2004-07-06, 18:28
Location: Poland
Contact:

Post by Maxoff »

A co do tego 0 to nie mogę jakoś zrobić aby mi się to 0 wyświetliło i aby trzeba było użyć if... then... ;-)
Kliknij edit (kontrolke) na formie, przejdz do ObjectInspektora i wpisze w Text 0, a będziesz miał 0.
Leciałem na piechotę czyli dla Button1Click
Jestem pełen podziwu, to teraz wstaw jeszcze wszędzie ify :D

PS. Widzę, że zainteresowanie kursem zmalało... cóż tak to bywa...
... You only have to know how to prepare query, google will do the rest ...
... My software ...
... Guide to Punctuation ...
User avatar
Luigi
Moderator
Posts: 475
Joined: 2004-07-15, 19:11
Location: z mm.li.pl
Contact:

Post by Luigi »

Łaaaa buahahaha - brechtam sam z siebie -> trzeba było od razu pisać, ze to chodzi o to aby 0 było od razu w edicie wpisane ;-)
Poważnie mówiąc nie skumełem o co chodzi - teraz już wiem w czym rzecz i po co if :-)
Ide je zrobić ;-)
User avatar
ZNag
HQTM-Team
Posts: 3526
Joined: 2004-07-15, 19:20
Location: W³oc³awek [PL]
Contact:

Post by ZNag »

Maxoff wrote:Widzę, że zainteresowanie kursem zmalało... cóż tak to bywa...
Oj chyba nie zmalało ;) Co do mnie, to jestem cały czas zainteresowany :) Wczoraj się trochę z tym kodem męczyłem, ale nic dobrego z tego nie wysło (zmęczenie daje swoje ;) ). Dzisiaj się z tymi przyciskami pobawię 8)
•ZNag - Strona domowa
•Intel Core 2 Quad Q9400 2,66GHz, 4GB DDR2 800MHz (Dual Channel), ATI Radeon HD 4850 512MB, 500GB HDD + Pendrive 4GB; Samsung SyncMaster T220
User avatar
Luigi
Moderator
Posts: 475
Joined: 2004-07-15, 19:11
Location: z mm.li.pl
Contact:

Post by Luigi »

Ok - ja już mam :-)

Co do zainteresowania to może po prostu czasu komuś zabrakło, albo wyjechał - zobaczymy za kilka godzin ew. jutro ;P
Ja na przykład dopiero teraz mogłem się przyłączyć bo środę i czwartek miałem zawaloną :-(
User avatar
Maxoff
HQTM-Team
Posts: 3434
Joined: 2004-07-06, 18:28
Location: Poland
Contact:

Post by Maxoff »

Wracając do kontrolek i obsługi zdzarzenia kliknięcia, to najwyższy czas zrobić to porządnie. Można to zrealizowac na kilka sposobów, my przeanalizujemy dwa. Pierwszy łatwiejszy a drugi ambitniejszy (zaczniemy od tego pierwszego)

Ponieważ we wszystkich dla wszystkich 10 przycisków kod wygląda niemal identycznie, różnie się tylko cyfrą dlatego przeniesiemy ten kod do osobnej procedury, a cyfrę będziemy przekazywać jako parametr.

Budowa procedury składa się z dwóch elementów. Po pierwsze, musimy wskazać w klasie, że taka procedura istnieje (podać jej nagłówek) a następnie wpisać jej ciało.

Zacznijmy od uzupełnienia klasy. Naszą procedure nazwiemy WriteDigit i będzie ona przyjmować jeden parametr nNumber typu liczbowego (integer). Całość będzie wyglądać tak:

Code: Select all

  procedure WriteDigit(nNumber:integer);
Pozostaje kwestia wpisania tego we właściwe miejsce. Ponieważ z pocedury będziemy korszystać wewnętrzenie, dlatego dodajemy ja do sekcji private:

Code: Select all

type TMainForm=class(TForm)
   btnNum1: TButton;
   btnNum2: TButton;
   btnNum3: TButton;
   btnNum4: TButton;
   btnNum5: TButton;
   btnNum6: TButton;
   btnNum7: TButton;
   btnNum8: TButton;
   btnNum9: TButton;
   btnNum0: TButton;
   btnPlus: TButton;
   btnMinus: TButton;
   edtNumber: TEdit;
   procedure btnNum1Click(Sender: TObject);
  private
    procedure WriteDigit(nNumber:integer);
  public
end;    
Kolejny etapem jest dopisanie ciała procedury w sekcji implementation (najlepiej przed ostatnim endem), czyli:

Code: Select all

procedure TMainForm.WriteDigit(nNumber:integer);
begin
  if StrToInt(edtNumber.Text)=0 
    then edtNumber.Text:=IntToStr(nNumber) 
    else edtNumber.Text:=edtNumber.Text+IntToStr(nNumber); 
end;
Jest to dokładnie ten sam kod, który używaliśmy wcześniej. Zmieniliśmy tylko 1 na nNumber. Ponieważ procedura należy do klasy, dlatego przed jej nazwą musi znajdować się nazwa klasy oraz kropka (TMainForm.).

Pozostaje dopisać wywołanie tej procedury w zdarzeniach dla przycisków. A więc po kolei klikamy dwa razy w przyciski od 0 do 9 i wpisujemy wywołanie procedury, czyli WriteDigit(1); Tak będzie wyglądała procedura, dla przycisku nr 1:

Code: Select all

procedure TMainForm.btnNum1Click(Sender: TObject);
begin
  WriteDigit(1);
end;
Po wprowadzeniu wszystkich zmian nasz program powinnien umożliwiać wpisanywanie dowolnych liczb naturalnych. Jednak jeśli obejrzymy kod, to okaże się, że nadal mamy pewną nadmiarowość, gdyż jak się okazuje mamy 10 prawie identycznych procedur:

Code: Select all

procedure TMainForm.btnNum1Click(Sender: TObject);
begin
  WriteDigit(1);
end;

procedure TMainForm.btnNum2Click(Sender: TObject);
begin
  WriteDigit(2);
end;

procedure TMainForm.btnNum3Click(Sender: TObject);
begin
  WriteDigit(3);
end;

procedure TMainForm.btnNum4Click(Sender: TObject);
begin
  WriteDigit(4);
end;

procedure TMainForm.btnNum5Click(Sender: TObject);
begin
  WriteDigit(5);
end;

procedure TMainForm.btnNum6Click(Sender: TObject);
begin
  WriteDigit(6);
end;

procedure TMainForm.btnNum7Click(Sender: TObject);
begin
  WriteDigit(7);
end;

procedure TMainForm.btnNum8Click(Sender: TObject);
begin
  WriteDigit(8);
end;

procedure TMainForm.btnNum9Click(Sender: TObject);
begin
  WriteDigit(9);
end;

procedure TMainForm.btnNum0Click(Sender: TObject);
begin
  WriteDigit(0);
end;
Wygląda to trochę nadmiarowo, ale takie rozwiązanie jest akcepotowalne. W ramach ciekawostki pokaże niedługo, jak uprościć to do jednej procedury (może ktoś ma pomysł na rozwiązanie ??).

Poczekam aż wszyscy zainteresowani dojdą do tego miejsca, aby nikt nie miał zaległości.

[ Added: 2005-03-04, 19:35 ]
Luigi wrote:ze to chodzi o to aby 0 było od razu w edicie wpisane
Pisałem wcześniej, że należy w edicie wpisać 0. Nie czytałeś uważnie ;)
... You only have to know how to prepare query, google will do the rest ...
... My software ...
... Guide to Punctuation ...
User avatar
Luigi
Moderator
Posts: 475
Joined: 2004-07-15, 19:11
Location: z mm.li.pl
Contact:

Post by Luigi »

Czyli inaczej mówiąc to daje nam dokładnie to samo co miałem wcześniej -> z tą mała różnicą, że teraz jest zapisane w procedurze.

Zmienione.
Post Reply