Dwie formy - przekazywanie zmienny, odwoływanie do komponentów

0

Witam

W projekcie w Lazarusie mam dwie formy.
W pierwszej w uses zadeklarowałem unit1 - bez problemu odwołuje sie do komponentów na form2 - np dodaje jakiś element do memo.

Jednak w druga stronę już mam problem... gdy wpisze po prostu

form1.label1.caption:='xxx';

krzyczy mi że identyfikator form1 nie został odnaleziony.
Natomiast gdy w uses wstawię form1 dostaję błąd:

unit2.pas(9,17) Fatal: Circular unit reference between Unit2 and Unit1

Kolejne moje pytanie tyczy się zmiennych:
czy jest możliwość aby tablica zadeklarowana w unit1 była "widoczna" w unit2 ?

Z góry dziękuje za pomoc.

0

Tragedia. Z łaski swojej przeczytaj na czym polega programowanie obiektowe, błagam. Lekcja na dziś:
Parametry konstruktorów i metod zamiast zmiennych globalnych

0

Natomiast gdy w uses wstawię form1 dostaję błąd:

Musisz wstawić do uses w sekcji implementation modułu.

czy jest możliwość aby tablica zadeklarowana w unit1 była "widoczna" w unit2 ?

Zmienne globalne.


Ale założę się, że cokolwiek robisz, można to zrobić lepiej i "poprawniej".
0
Patryk27 napisał(a)
hipekk napisał(a)

czy jest możliwość aby tablica zadeklarowana w unit1 była "widoczna" w unit2 ?

Zmienne globalne.

Tutaj nie mogę się zgodzić - lepiej w tej sytuacji jest skorzystać z właściwości klasy okna, niż kombinować z zasięgiem zmiennych; OOP i tak będzie się musiał nauczyć, więc teraz ma dobrę okazję część rzeczy przetestować;

@hipekk - więcej informacji na temat programowania obiektowego dowiesz się w dziale Kompendium - Rozdział 3: Programowanie obiektowe;

0

Przeczytałem podany artykuł, zrobiłem ćwiczenie, wydaje mi się, że zrozumiałem ogólne założenie...
a tego zdania ""lepiej w tej sytuacji jest skorzystać z właściwości klasy okna" " nadal nie rozumiem...

0
hipekk napisał(a)

a tego zdania ""lepiej w tej sytuacji jest skorzystać z właściwości klasy okna" " nadal nie rozumiem...

Więc posyłam Cię z powrotem do kursu - Programowanie obiektowe - Klasy - poczytaj o poziomach dostępu; Także poczytaj w sieci o tworzeniu pól i właściwości w klasach oraz poziomach dostępu (sekcjach);

0

W ramach nauki stworzyłem banalny projekt zawierający dwa unity:
Unit glowny :

unit glowny;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils;


type
  TKlasa = class
  public
    tablica : array[0..20] of string;
    destructor Destroy; override;
  end;

implementation

destructor TKlasa.Destroy;
begin
  inherited;
end;

end.
                 

Unit Unit1:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

uses glowny;
{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
var
  test:TKlasa;
begin
  test.create;
  test.tablica[9]:='a';

end;

end.
 

Przy uruchamianiu projektu otrzymuje błąd:
Error: Project raised exception class 'External:SIGSEGV'.

0

Czas poczytać o klasach:
Aby móc użyć klasy, musisz ją najpierw stworzyć.

0

Chyba czytałeś co piąte słowo w tym artykule. Jedno wielkie WTF! ;/ A gdzie masz chociażby tworzenie tej swojej klasy?

EDIT: @Patryk27 tym razem był o trzy minuty szybszy, ponieważ dopiero zacząłem przeglądać forum.

0

Dodałem

 test.create;

i nadal bez zmian.

Olesio ja rozumiem że Ty wiesz więcej i wszystko rozumiesz ale zauważ że to dział newbie więc jeżeli nie chcesz czytać pytań na takim poziomie to chyba bezsensu jest zaglądanie tutaj...

0

Jak niby chcesz wywołać metodę-konstruktor Create na obiekcie (zmiennej) Test, która nie jest jeszcze zainicjowana (wskazuje najprawdopodobniej na nil)?

więc jeżeli nie chcesz czytać pytań na takim poziomie to chyba bezsensu jest zaglądanie tutaj...

Ten dział jest co prawda od pomocy z kodem, ale nie od uczenia podstaw języka.

0

@hipekk: czytam wszystko w tym dziale co dotyczy Pascala / Delphi / Lazarusa / FPC i chciałbym tylko żeby ludzie jeżeli już dostaną konkretne informacje, poświęcili chwilę i się z nimi zapoznali. Sam nie wiem wszystkiego, nie uważam się według mnie i nigdy nie uważałem za guru. Ale wybacz, wystarczy wejść na: Rozdział 3 i chwila lektury, bo sam sprawdziłem czy aby ten art nie zawiera konkretnych informacji i widzę taki tekst jak cytuje poniżej. Dzial Newbie czy nie. Jednak czytania ze zrozumieniem uczy, o ile dobrze pamiętam, szkoła podstawowa. I chętnie pomagam wszystkim, jeżeli tylko zdąże przed innymi odpowiadającymi i umiem pomóc. Jednak ostatnie "doświadczenia" po lekturze odpowiedzi w wielu wątkach, nie tylko w tym dziale, pozwalają mi dojśc niestety do smutnych wniosków: dawanie gotowców należy ograniczyć do minimum, bo ludzie i tak nie umieją z nich skorzystać. Otrzymany gotowiec "generuje" masę nowych pytan. A mój drugi wniosek: ludzie jakby nie chcieli dać sobie pomóc, bo nie potrafią skorzystać z otrzymanych odnośników do konkretnych informacji i w ogóle z otrzymanych wskazówek. Tak, wiem - nie można generalizowac, ale moje pewne - może i niewielkie, ale zawsze - forumowe doświadczenie nie pozwala ustrzec się takich spostrzeżeń.

Tworzenie klasy
Oprócz zwykłej deklaracji nowej klasy należy stworzyć zmienną, która wskazywać będzie na nowy typ. Nie jest możliwe proste odwołanie się do metod danej klasy — wcześniej należy nowy obiekt utworzyć, co pozwoli na określenie przydziału pamięci. Dopiero wtedy można uzyskać pełny dostęp do funkcji, jakie oferuje nam dana klasa. Odbywa się to następująco:

procedure TMainForm.btnGenerateClick(Sender: TObject);
var
Template : TEngine;
begin
Template := TEngine.Create;
end;

0

W przykładnie podanym w Kompedium metoda create wygląda tak:

constructor TEngine.Create(FileName : String);
begin
  FFileName := FileName;  // przypisanie wartości parametru do zmiennej w sekcji private
  FFileLines := TStringList.Create; // utworzenie typu TStringList
  FFileLines.LoadFromFile(FileName); // załadowanie zawartości zmiennej z pliku
end; 

Ja w tym testowym projekcie nie potrzebuje nic takiego robić ponieważ ta testowa klasa zawiera tylko jedną tablice. Jak więc powinna wyglądać taka metoda ?

EDIT


Przy okazji :
Po wspomnianym błędzie, zatrzymuje projekt w Lazarusie lesz proces "project1.exe" nadal zostaje w systemie (nie można go zakończyć za pomocą menadżera zadań) - przez co nie mogę drugi raz uruchomić projektu z poziomu Lazarusa - konieczny jest restart - tak powinno być ?

0

Po prostu musisz wywołać konstruktor:

Test := TKlasa.Create;

tak powinno być ?

Dunnoh - jaka wersja Lazarusa?

0

Ok... coś zaczęło działać.
Dziękuję za pomoc, choć wrócę jeszcze zapewne z kolejnymi pytaniami.
A teraz będę próbował rozszerzać wykorzystanie klas (choć chyba nie do końca jednak rozumiem idee ale mam nadzieje że z czasem się to wyklaruje ;) ).
Pozdrawiam

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