Okna w Delphi/Lazarus

Odpowiedz Nowy wątek
2011-09-03 09:49
0

Witam.
Programowałem dotąd w C/C#/Java, postanowiłem teraz dzięki projektowi Lazarus przyjrzeć się językowi Delphi.
Zacząłem zabawę z oknami. Otóż w oknie głównym zadeklarowałem sobie inne okno, które wywołuję z przycisku:

var
  oknoGlowne: ToknoGlowne;
  oDArtyste: ToknoDodajArtyste;  

A tutaj kod przycisku:

procedure ToknoGlowne.tbDodajClick(Sender: TObject);
begin
  oDArtyste:= ToknoDodajArtyste.Create(nil);
  oDArtyste.Show;
end;  

Okno oDArtyste poprawnie się wywołuje. Mam tam też przycisk do zamknięcia tego okna. Niestety, jego kod nie chce go już zamknąć:

procedure ToknoDodajArtyste.btnAnulujClick(Sender: TObject);
begin
  oknoDodajArtyste.Close;
end; 

Co takiego robię źle?

edytowany 1x, ostatnio: madmike, 2011-09-03 09:52

Pozostało 580 znaków

2011-09-03 10:02
0

Jakiś błąd, nie zamyka się?


Pozostało 580 znaków

2011-09-03 10:23
0

Po prostu się nie zamyka.

Pozostało 580 znaków

2011-09-03 10:33
0

W formie nr 2 napisz tak:

procedure ToknoDodajArtyste.btnAnulujClick(Sender: TObject);
begin
  Self.Close;
end;

Dlaczego?
Bo:
a) w pierwszej formie niepotrzebnie tworzysz dodatkowy obiekt formy (zwykle robi się sam)
b) a w formie docelowej odwołujesz się właśnie do tego obiektu automatycznie stworzonego (czyli de facto masz dwie formy dodajArtystę jednocześnie)
c) dlatego najbezpieczniej w obsłudze zdarzeń odwoływać się do aktualnej formy przez "Self"

Gdybyś szukał gdzie automatycznie tworzą się formy to znajdziesz to komendą:
Projekt \ Pokaż źródło

Przy większych projektach się to wyłącza, bo zamula program (formy tworzy się wtedy ręcznie - tak jak to zrobiłeś w ToknoGlowne.tbDodajClick).

edytowany 3x, ostatnio: vpiotr, 2011-09-03 10:38

Pozostało 580 znaków

2011-09-03 11:11
0

Dzięki, już próbuję rozwiązania. Właśnie szukałem czegoś w stylu słowa this z języków c-podobnych.

EDYCJA:

Działa!

Co do pkt a. Nie powinienem używać forma:= Tforma.create();?

edytowany 1x, ostatnio: mcywinski, 2011-09-03 11:19

Pozostało 580 znaków

2011-09-03 11:45
0

Przy dużych projektach - tak.
W Delphi / Lazarus masz dwa tryby tworzenia form:
a) automatycznie - w kodzie projektu (w Lazarus patrz "Projekt \ Pokaż źródło")
b) ręcznie - tak jak to napisałeś w ToknoGlowne.tbDodajClick

Jeśli chodzi o (b) to jest to bardziej polecana forma dla większych projektów.
Ale nawet wtedy polecałbym raczej przechowywać uchwyt / wskaźnik do formy jako atrybut formy wywołującej (żeby był schowany i powiązany z obiektem wywołującym) lub używać uchwytu automatycznie tworzonego (oknoDodajArtyste).

W przypadku (b) powinieneś zakomentować / usunąć automatyczne tworzenie w kodzie projektu.

  Application.Initialize;
  Application.CreateForm(ToknoGlowne, oknoGlowne);
  //Application.CreateForm(ToknoDodajArtyste, oknoDodajArtyste);
  Application.Run;
edytowany 3x, ostatnio: vpiotr, 2011-09-03 11:48

Pozostało 580 znaków

2011-09-03 11:56
0

Wszystko działa. Dzięki za informacje. Jak coś, to będę pytał :)

Pozostało 580 znaków

2011-09-06 17:29
0

Witam, kontynuuję pracę nad moim programem. Napotkałem kolejną przeszkodę. Zaprojektowałem sobie moduł odpowiedzialny za odczyt i zapis do plików elementowych mojego rekordu. Niestety, podczas odczytu dzieje się dziwna rzecz: Nazwa artysty (w kodzie poniżej) nie pokazuje się w listbox (zostaje dodanynowy wpis jak przy normalnym add, ale pusty), a po zamknięciu okna głównego otrzymuję błąd: Project xaudio.app raised exception class 'External: EXC_BAD_ACCESS'.

Oto poszczególne kody:

Wywołanie odczytu, dodawanie elementów

procedure TOkno_glowne.FormShow(Sender: TObject);
var
  i: integer;
  max: integer;
  art: TArtysta;
begin
  max:= xaobj.pobierz_liczbe_art();
  //Pobieranie i wyswietlanie danych
  if max <> -1 then //Plik istnieje
  begin
   for i:= 0 to max - 1 do
   begin
    art:= xaobj.pobierz_art(i);
    ListBoxArtysci.Items.Add(art.nazwa);
   end;
  end;

end;                                   

Definicja xaobj.pobierz_liczbe_art();

{ Zwraca liczbe elementow w pliku artystow
-1 zwrocone, kiedy plik artystow nie istnieje }
function pobierz_liczbe_art(): integer;
var
  liczba: integer;
begin
  if FileExists(sciezka_art) then
  begin
   Assign(p_artysci, sciezka_art);
   Reset(p_artysci);
   liczba:= FileSize(p_artysci);
   Close(p_artysci);
   pobierz_liczbe_art:= liczba;
  end
  else pobierz_liczbe_art:= -1;
end; 

Oraz funkcja pobierająca samego artystę z pliku:

//Zwraca artyste o wybranym indeksie
function pobierz_art(ind: integer): TArtysta;
var
  art: TArtysta;
begin
  Assign(p_artysci, sciezka_art);
  Reset(p_artysci);
  Seek(p_artysci, ind);
  Read(p_artysci, art);
  Close(p_artysci);
  pobierz_art:=art;
end;   
Inna sprawa -> Nowy temat. - payl 2011-09-06 17:33

Pozostało 580 znaków

2011-09-06 19:23
0

Pokaż definicję typu TArtysta, ale zakładam że nie ma tam niespodzianek. Na pierwszy rzut oka nic złego się tu nie dzieje.

Pozostało 580 znaków

2011-09-06 19:24
0

a po zamknięciu okna głównego otrzymuję błąd: Project xaudio.app raised exception class 'External: EXC_BAD_ACCESS'.

Naucz się debuggera używać, i inna sprawa - nowy temat. Ale czy jest ktoś kto jeszcze mnie tutaj słucha? Nie.


Nie pisz do mnie PM o czymś co nie dotyczy bezpośrednio mnie. | Nie rozmawiaj ze mną jeśli brak Ci kultury (wystarczy że mi brakuje) | Nie jestem zły, jestem po prostu zły.

Pozostało 580 znaków

2011-09-06 23:02
0

Wedle życzenia: Z każdym innym problemem będzie nowy temat.
Tutaj definicja TArtysty:

type
  //Definicja artysty
  TArtysta = record
   nazwa: string;
   rok_rozp: string;
   rok_zak: string;
  end;

Przy czym z zapisem nie ma on problemu, a w podobnej aplikacji konsolowej też nie miałem spacjalnie problemów z odczytem.

W kwestii debuggera: O ile w Visual Studio jego używanie było dla mnie banalnie proste, to w Lazarusie nie umiem go rozgryźć, a Twórcy IDE chyba za wszelką cenę starają się ukryć informacje o tym jak go używać/podglądać zawartość zmiennych/pól.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0