Zagnieżdżanie dynamicznie tworzonych paneli

Zagnieżdżanie dynamicznie tworzonych paneli
D1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 165
0

Po wciśnięciu przycisku tworzony jest PanelW, na którym jest umieszczony label i przycisk, taki sam jak ten który utworzył PanelW. Po wciśnięciu przycisku na PanelW powinien zostać stworzony dynamicznie PanelW jeszcze raz, a label który powienien mieć taką samą nazwę powinien wyświetlić inny tekst. Problem jednak, że on już istnieje i tekst na labelu jest ciągle taki sam.

W zdarzenie onClick chciałbym umieścić sprawdzanie czy PanelW już istnieje a jeśli tak to go zwolnić, żeby móc postawić od nowa. Próbowałem jak poniżej, ale nie daje to żadnego efektu, Label.Captio jest bez zmian.

Kopiuj
if FindComponent('PanelW') <> nil then
  //showmessage('istnieje');
  PanelW.Free; 
 

Po umieszczeniu ShowMessage zaobserwowałem, że warunek nie jest spełniony nigdy.

Patryk27
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 13042
2

Czy na pewno ustawiasz nazwę panelu na PanelW, czy tak tylko sobie zmienną nazwałeś?

KA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 701
1

To moze trzymaj to w jakims TObjectList? :)

JU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5046
1

Po pierwsze. Jeśli nie zrobiłeś:

Kopiuj
 
panel.Name := 'PanelW';

to niczego Ci nie znajdzie.
Po drugie samo:

panel.Free
nic Ci nie da. Owszem, zwolni pamięć, ale nie wyniluje Ci tej referencji. Jeśli obiekt musisz mieć znilowany, to używasz FreeAndNil(obj).

Po trzecie. Widzę, że masz zmienną panelW. Więc po co szukasz tej kontrolki w ten sposób? Najpewniej tworzysz ją:

Kopiuj
 
panelW:=TPanel.Create

Czyli referencję do tego masz w panelW (chyba, że jest to zmienna lokalna, ale nie wynika to z kodu, który podałeś). Więc zamiast:

Kopiuj
 
FindComponent('PanelW')

wystarczy, że zrobisz:

Kopiuj
 
if panelW <> nil
  FreeAndNil(panelW);
flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12272
0
dani17 napisał(a)

Po wciśnięciu przycisku na PanelW powinien zostać stworzony dynamicznie PanelW jeszcze raz, a label który powienien mieć taką samą nazwę powinien wyświetlić inny tekst.

Się nie da szefie - nazwa komponentu musi być unikalna w skali całego formularza.

D1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 165
0

Okej, widzę gdzie mam błąd. Ale tak na prawdę to nie rozwiązuje mojego problemu. Bo nadal nie działa to tak jak bym chciał, a nawet więcej, niby nie ma problemu nigdzie, cały kod się wykonuje ale i tak wyskakuje

Kopiuj
Project raised exception class 'EXTERNAL: SIGSEGV'

At address: 2E005D8

Kod programu w uproszczeniu:

Kopiuj
procedure TProgram.FormCreate(Sender: TObject);
begin
  PanelW := TPanel.Create(Program);
  with PanelW do
  begin
    Parent := Program;
    Width := Parent.Width;
    Height := ParentHeight;
    Color := KolorGlowny;
    Left := 0;
    Top := 0;
  end;

  LNazwa := TLabel.Create(PanelW);
  with LNazwa do
  begin
    Parent := PanelW;
    Left := 5;
    Top := 5;
    Caption := 'Jakaś nazwa';
    onClick := LabelKlik;
  end;
end;

procedure TProgram.LabelKlik(Sender: TObject);
var
  I: Integer;
  FPanel: TPanel;
begin
  Sender := FPanel;

  if PanelW <> nil then
    begin
      for I := PanelW.ControlCount - 1 downto 0 do
        PanelW.Controls[I].Free;
    end;

  PanelW := TPanel.Create(Program);
  with PanelW do
  begin
    Parent := Program;
    Width := Parent.Width;
    Height := ParentHeight;
    Color := KolorGlowny;
    Left := 0;
    Top := 0;
  end;

  LNazwa := TLabel.Create(PanelW);
  with LNazwa do
  begin
    Parent := PanelW;
    Left := 5;
    Top := 5;
    Caption := 'Jakaś nazwa';
    onClick := LabelKlik;
  end;
end;
 
Patryk27
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 13042
0

Prawdopodobnie w drugim with chciałeś jednak napisać LNazwa, a nie PanelW.

D1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 165
0

To prawda, już poprawione. Natomiast w kodzie jest prawidłowo. Błąd jedynie był przy pisaniu na forum. Mimo wszystko dalej wychodzi ten sam wyjątek.

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12272
0

@dani17 - destruktor PanelW sam zwolni komponenty w nim zagnieżdżone, więc mu w tym nie przeszkadzaj;

Poza tym jak nie wiesz gdzie wywoływany jest wyjątek to uruchom program przez IDE i (po zaistnieniu wyjątku) w okienku błędu kliknij guzik break - wtedy zostanie pokazana w edytorze linijka, która wyrzuciła wyjątek;

A tak w ogóle to nie możesz w taki sposób zwolnić komponentu, którego zdarzenie jest aktualnie wykonywane; Już ten problem był na forum poruszany;

Kopiuj
onClick := LabelKlik;

Używasz dyrektywy {$MODE DELPHI}? Małpka powinna być przed nazwą metody.

D1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 165
0

Dlatego chciałem wykorzystać Sender := A. Chociaż to był pomysł z głowy i nie wiem czy to ma jakikolwiek sens.Jeśli nie to tak jak już było pisane, trzeba będzie użyć Timera. Dyrektywę delphi mam.

flowCRANE
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Tuchów
  • Postów: 12272
0

Dlatego chciałem wykorzystać Sender := A. Chociaż to był pomysł z głowy i nie wiem czy to ma jakikolwiek sens.Jeśli nie to tak jak już było pisane, trzeba będzie użyć Timera.

Ale wiesz, że Sender posiada referencję kontrolki, której zdarzenie jest wykonywane? Jeśli przypiszesz metodę LabelKlik (co to za nazwa?) do etykiety LNazwa to w Sender będzie wskazanie na LNazwa; Nie tędy droga;

Ten problem był już poruszany niedawno (to był chyba Twój wątek), w którym @abrakadaber podał bodajże dwa rozwiązania tego problemu, poprzez wysłanie własnego komunikatu do okna i przez timer; Znajdź ten wątek i sprawdź co zostało podane;

Dyrektywę delphi mam.

Po co? Kod piszesz dla FPC, więc używaj dyrektywy {$MODE OBJFPC}; Do tej pory nie wspominałeś o kompatybilności z Delphi na poziomie kodu, więc nie jest Ci to do niczego potrzebne i będzie tylko przeszkadzać.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.