Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Objekt TList- ich versteh kein Wort! (https://www.delphipraxis.net/123161-objekt-tlist-ich-versteh-kein-wort.html)

Sir Rufo 28. Okt 2008 20:41

Re: Objekt TList- ich versteh kein Wort!
 
hi,

die Liste ist ein Objekt vom Typ TList und muss auch irgendwo erzeugt werden, sonst kannst du nicht drauf zugreifen und genau der Fehler kommt dann.

Also
Delphi-Quellcode:
procedure TMain.FormCreate(Sender: TObject);
begin
  doublebuffered:= true;
  randomize;
  Liste := TList.Create;
end;
Wenn man sauber programmiert, dann sollte im Gegenzug beim Beenden des Formulars auch die Liste wieder entsorgt werden mit Liste.Free

cu

Oliver

ark4869 28. Okt 2008 20:43

Re: Objekt TList- ich versteh kein Wort!
 
Du wirst es nicht glauben, aber das mit dem Vernichten versteh ich jetzt :D
Die Fehlermeldungen sind aber halt trotzdem da.


Und danke für den Seitenhieb- früher war ich mal gut in Informatik ... :(


Oh Mann bin ich doof, natürlich sollt ich die Buttons auch aus dem Formular nehmen wenn ich sie ausklammer. Kein Wunder dass die Fehlermeldung kam^^ Aber Erzeugen geht trotzdem noch nicht ;)

Bah! Das mit Create hat ich am Anfang aber dann durhc neustart des Projektes hab ichs vergessen! Das create steht auch im Buch. Boah ey sowas vergessen, das versteh ich ja sogar noch ;)



Edith: Also, nach ein paar dummen Fehlern funktioniert jetzt auch vernichten, aber der löscht alles auf einmal(und aufgrund vorherigen fehlern hatte ich mir n Label eingerichtet, dass mir auf Klick die count angibt, das zeigt mir dann 0 an). D.h. ma gucken ;)#

Zweite Edith: Geeeeil! Ich habs alleine geschafft!!! :D :D :D Wie coooool! Ich liebe dieses Gefühl, etwas selbst zu schaffen(auch wenn ich den Rest ohne deine Hilfe wohl nicht hinbekommen hätte :)

Hier die Vernichten-PRozedur :D
Delphi-Quellcode:
procedure TMain.BtVernichtenClick(Sender: TObject);
var i: integer;
begin
  i := Liste.Count - 1  ;
  if Liste.Items[ i ] <> nil then
    begin
      TBewegteUhr( Liste.Items[ i ] ).Loeschen;
      Liste.Delete( i );
    end;
end;
Jetzt darf das ding nur nicht abstürzen wenn keine Uhr mehr da ist.

SirTwist 29. Okt 2008 06:10

Re: Objekt TList- ich versteh kein Wort!
 
Hi ark,

mal was grundsätzliches zu Listen. Das ist eine Datenstruktur, mit der Du mehrere (viele) Objekte verwalten kannst. Dazu unterstützt die Liste im Prinzip diese wichtigen Funktionen:
  • Liste.Add(obj) - fügt das angegebene Objekt am Ende der Liste hinzu
  • Liste.Insert(idx, obj) - fügt das angegebene Objekt an der angegebenen Position ein und verschiebt alle nachfolgenden Objekte in der Liste um eine Position nach hinten
  • Liste.Delete(idx) - löscht das Objekt mit dem angegebenen Index aus der Liste und verschiebt alle nachfolgendenen Objekte um eine Position nach vorne
  • Liste.Remove(obj) - löscht das angegebene Objekt aus der Liste und verschiebt alle nachfolgendenen Objekte um eine Position nach vorne
  • Liste.Count - liefert dir die Anzahl der Objekte in der Liste
  • Liste.Items[idx] - liefert dir das Objekt mit dem angegebenen Index zurück

Hieraus kannst Du Dir dann deine eigentlichen Funktionen zusammenbasteln. Zum Beispiel würde ein Hinzufügen so aussehen:
Delphi-Quellcode:
var uhr: TBewegteUhr;
begin
  uhr := TBewegteUhr.Create(10, 10, 75);
  uhr.Kennt(Main); // <-- hier noch die weiteren Funktionen einfügen,
                   // die Du brauchst, um die Uhr zu initialisieren
  Liste.Add(uhr);
end;
Wenn Du alle Uhren bewegen willst, geht das im Prinzip so:
Delphi-Quellcode:
var i: Integer;
  uhr: TBewegteUhr;
begin
  for i:=0 to Liste.Count-1 do begin // ganz wichtig, immer von 0 bis count-1 zählen
    uhr := TBewegteUhr(Liste[i]); // Liste[i] ist das gleiche wie Liste.Items[i], aber wir sind halt faul...
    // hier mit der Uhr irgendwas machen
  end;
end;
Und das Löschen geht dann so:
Delphi-Quellcode:
var uhr: TBewegteUhr;
begin
  uhr := TBewegteUhr(Liste[idx]);
  Liste.Remove(uhr); // Liste.Delete(idx) wäre hier genau das gleiche
  FreeAndNil(uhr); // gibt den Speicher von uhr wieder frei
end;
Soweit verständlich?

Gruß,
SirTwist

ark4869 11. Nov 2008 18:28

Re: Objekt TList- ich versteh kein Wort!
 
Hi - ich mal wieder :)
Nachdem wir das alles im unterricht besprochen haben(und durch eure Hilfe :) ) hab ich die delphiinterne TList ganz gut verstanden.
Jetzt sollen wir mtihilfe einer besonderen Klasse Liste (wir nennen sie "NRW LIst) das nochmal machen. Diese Basiert nicht auf indizes oder Arrays.
Das problem hierbei ist aber, dass ich seit geraumer Zeit die Programme nicht mehr zum Laufen kriege, schon TList hat nicht recht funktioniert, mal klappte es mal nicht ohne dass was geändert wurde.
Und das hab ich nun auch wieder mit der neuen Klasse. Erzeugen (scheint) jetzt richtig zu funktionieren(zumindestens Erzeugen am Anfang der Reihe), aber sonst nichts, und auch mein Lehrer hat (zumindest bei der alten Liste) keine Fehler entdeckt. Wahrscheinlich ist es was ganz einfaches, aber wir finden den Fehler einfach nicht.
Vllt. findet ja jemand einen Fehler, ohne das Programm vorliegen zu haben. Hier die neue Klasse und das aktuelle Hauptprogramm.

Klasse(daran sollen wir nichts ändern- bei anderen funktionierts aber- detailliert besprochen haben wir DIESE Programmierungn nicht, nur, was diese Klasse allgemein macht: mit einem Zeiger arbeiten):
Delphi-Quellcode:
unit mTList;
{ Version vom 07.11.2008 }
{ Die Klassendefinition entspricht den Vorgaben zu "TList" aus:
  "Materialien zu den zentralen Abiturprüfungen im Fach Informatik
   objektorientierter Ansatz, Delphi" NRW 2008, Seite 10: "Dokumentation
   der Klasse TList"
   Die Liste ist doppelt verkettet mit einem Dummy-Element vor und einem
   Dummy-Element hinter der Liste. }

interface

uses STDCtrls, SysUtils, Forms;

Type TListNode = class (TObject)
private
  zItem: TObject;
  zPrevious, zNext: TListNode;
protected
  constructor Create(Item: TObject; Previous, Next: TListNode); virtual;
  destructor Destroy; virtual;
  procedure SetNext (Next: TListNode);
  procedure SetPrevious (Previous: TListNode);
  procedure SetItem (Item: TObject);
  function GetPrevious: TListNode;
  function GetNext: TListNode;
  function GetItem: TObject;
public
  // TListNode ist eine Hilfsklasse für die in dieser UNIT deklarierten Klasse
  // TList. Daher werden keine öffentlichen Methoden angeboten!
end;

Type TList = class (TObject)
private
  zCurrent, zDummyVorne, zDummyHinten: TListNode;
public
  constructor Create; virtual;
  function IsEmpty: boolean; virtual;
  function IsInFrontOf: boolean; virtual;
  function IsBehind: boolean; virtual;
  procedure Next; virtual;
  procedure Previous; virtual;
  procedure ToFirst; virtual;
  procedure ToLast; virtual;
  function GetItem: TObject; virtual;
  procedure Replace (pObject: TObject); virtual;
  procedure InsertInFrontOf(pObject: TObject); virtual;
  procedure InsertBehind (pObject: TObject); virtual;
  procedure Remove; virtual;
  procedure AddList(pList: TList);
  destructor Destroy; virtual;
end;

implementation

{ ------------------------ TListNode ---------------------------------------- }

  constructor TListNode.Create(Item: TObject; Previous, Next: TListNode);
  begin
    inherited Create;
    zItem:= Item;
    zPrevious:= Previous;
    zNext:= Next;
  end;

  destructor TListNode.Destroy;
  begin
    zItem:= nil;
    zPrevious:= nil;
    zNext:= nil;
    inherited Destroy;
  end;


 
  function TListNode.GetItem: TObject;
  begin
    result:= zItem;
  end;

  procedure TListNode.SetItem(Item: TObject);
  begin
    zItem:= Item;
  end;

  function TListNode.GetPrevious;
  begin
    result:= zPrevious;
  end;

  procedure TListNode.SetPrevious(Previous: TListNode);
  begin
    zPrevious:= Previous;
  end;

  function TListNode.GetNext;
  begin
    result:= zNext;
  end;

  procedure TListNode.SetNext(Next: TListNode);
  begin
    zNext:= Next;
  end;

{ ------------------------------------ TList ------------------------------- }

  constructor TList.Create;
  begin
    inherited Create;
    zDummyVorne:= TListNode.Create(nil, nil, nil);
    zDummyHinten:= TListNode.Create(nil, zDummyVorne, nil);
    zDummyVorne.SetNext(zDummyHinten);
    zCurrent:= zDummyVorne;
  end;

  function TList.IsEmpty: boolean;
  begin
    result:= zDummyVorne.zNext = zDummyHinten;
  end;

  function TList.IsInFrontOf: boolean;
  begin
    result:= zCurrent = zDummyVorne;
  end;

  function TList.IsBehind: boolean;
  begin
    result:= zCurrent = zDummyHinten;
  end;

  procedure TList.Next;
  begin
    if not IsBehind then zCurrent:= zCurrent.GetNext;
  end;

  procedure TList.Previous;
  begin
    if not IsInFrontOf then zCurrent:= zCurrent.GetPrevious;
  end;

  procedure TList.ToFirst;
  begin
    zCurrent:= zDummyVorne.zNext;
  end;

 
  procedure TList.ToLast;
  begin
    zCurrent:= zDummyHinten.zPrevious;
  end;

  function TList.GetItem: TObject;
  begin
    result:= zCurrent.GetItem;
  end;

  procedure TList.Replace(pObject: TObject);
  begin
    if not (IsBehind or IsInFrontOf)
       then zCurrent.SetItem(pObject);
  end;

  procedure TList.InsertInFrontOf(pObject: TObject);
  var new: TListNode;
  begin
    if not IsInFrontOf
    then begin
           new:= TListNode.Create(pObject, zCurrent.zPrevious, zCurrent);
           zCurrent.zPrevious.zNext:= new;
           zCurrent.zPrevious:= new;
         end;
  end;

  procedure TList.InsertBehind(pObject: TObject);
  var new: TListNode;
  begin
    if not IsBehind
    then begin
           new:= TListNode.Create(pObject, zCurrent, zCurrent.zNext);
           zCurrent.zNext.zPrevious:= new;
           zCurrent.zNext:= new;
         end;
  end;

  procedure TList.Remove;
  var help: TListNode;
  begin
    if not (IsInFrontOf or IsBehind)
    then begin
           help:= zCurrent;
           zCurrent.zPrevious.SetNext(zCurrent.zNext);
           zCurrent.zNext.SetPrevious(zCurrent.zPrevious);
           zCurrent:= help.zNext;
           help.Destroy;
         end;
  end;

  procedure TList.AddList(pList: TList);
  begin
    (*** ist noch zu implementieren !!! ***)
  end;

  destructor TList.Destroy;
  begin
    ToFirst;
    while not IsEmpty do remove;
    zDummyVorne.Destroy;
    zDummyHinten.Destroy;
    inherited Destroy;
  end;


end.
Hier das Hauptprogramm:
Delphi-Quellcode:
unit mBewegteUhr;
{Übung 14.3 - Modifikation: West; Uhr2a --> BewegteUhr: September/Oktober 2008} 

interface

uses
  Windows, Messages, SysUtils, Graphics, Controls, Forms, Dialogs, StdCtrls,
  classes,
  mTBewegteUhr, mTList; {TBewegteUhr, TList}

type
  TMain = class(TForm)
    BtErzeugAn: TButton;
    BtVernAn: TButton;
    BtErzeugEn: TButton;
    BtVernEn: TButton;


    procedure BtVernAnClick(Sender: TObject);
    procedure BtErzeugAnClick(Sender: TObject);
    procedure BtErzeugEnClick(Sender: TObject);
   // procedure FormClose(Sender: TObject; var Action: TCloseAction);
    //procedure BtVernAnClick(Sender: TObject);
    //procedure BtVernEnClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
   


  private
    Uhr: TBewegteUhr;
    Liste : TList;
  public

    { Public-Deklarationen }
  end;

var
  Main: TMain;

implementation

{$R *.DFM} 


procedure TMain.BtErzeugAnClick(Sender: TObject);
begin
  Uhr:=TBewegteUhr.Create (Main.Width div 2, Main.Height div 2, 75) ;
  Uhr.Kennt(Main);
  Uhr.Zeigen;
  Liste.ToFirst;
  Liste.InsertInFrontOf(Uhr);


end;

procedure TMain.BtVernAnClick(Sender: TObject);
begin
  if Liste.IsEmpty = false
  then
    begin
      Liste.ToFirst;
      TBewegteUhr(Liste.GetItem).Destroy;
      Liste.Remove;
    end;

  {i := Liste.Count - 1  ;
  if i>=0 then
    begin
      TBewegteUhr( Liste.Items[ i ] ).Destroy;
      Liste.Delete( i );
    end;
  Main.Caption:= IntToStr(Liste.count); }
end;

procedure TMain.BtErzeugEnClick(Sender: TObject);
begin
  Uhr:=TBewegteUhr.Create (Main.Width div 2, Main.Height div 2, 75) ;
  Uhr.Kennt(Main);
  Uhr.Zeigen;
  Liste.ToLast;
  Liste.InsertBehind(Uhr);



end;

{procedure TMain.BtVernEnClick(Sender: TObject);
var i: integer;
begin
  i := Liste.Count - 1  ;
  if i>=0 then
    begin
      TBewegteUhr( Liste.Items[ i ] ).Destroy;
      Liste.Delete( i );
    end;
  Main.Caption:= IntToStr(Liste.count);
end;      }




{procedure TMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  BtVernichtenClick(Sender);
end; }

procedure TMain.FormCreate(Sender: TObject);
begin
  doublebuffered:= true;
  randomize;
  Liste:= TList.create;
end;





end.
Hoffe ihr könnt mir helfen :(

DeddyH 11. Nov 2008 18:41

Re: Objekt TList- ich versteh kein Wort!
 
Möglicherweise hilft es, wenn man FormCreate und die Formdeklaration ein klein wenig ändert:
Delphi-Quellcode:
type
  TMain = class(TForm)
//    Liste: TList;
    BtErzeugen: TButton;
    BtVerbergen: TButton;
    BtZeigen: TButton;
    BtVernichten: TButton;
    procedure BtErzeugenClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure BtVerbergenClick(Sender: TObject);
    procedure BtZeigenClick(Sender: TObject);
    procedure BtVernichtenClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    Uhr1 : TBewegteUhr;
    Liste: mTList.TList;
  public
    { Public-Deklarationen }
  end;

...

procedure TMain.FormCreate(Sender: TObject);
begin
  doublebuffered:= true;
  randomize;
  Liste:= mTList.TList.create;
end;
TList ist bereits in Classes definiert, daher ist der Name "ungünstig" gewählt.

ark4869 11. Nov 2008 19:07

Re: Objekt TList- ich versteh kein Wort!
 
Hi!
Geschadet hat das mTList.TList zwar nicht, aber auch nicht geholfen. Ich kann weiterhin die Uhren erzeugen, aber mehr auch nicht.

DeddyH 11. Nov 2008 19:12

Re: Objekt TList- ich versteh kein Wort!
 
Was genau funktioniert denn nicht? Eure TList ist anscheinend eine doppelt verkettete Liste in eine Klasse gepresst, nette Idee.

ark4869 11. Nov 2008 19:45

Re: Objekt TList- ich versteh kein Wort!
 
Also wie gesagt, diese arbeitet nicht wie TList mit Arrays, sondern mit einem Zeiger. Und funktionieren tut nicht das Vernichten von den Uhren. ABER: Ich hab grad festgestellt, dass ich vergessen hab, dass ich die Zeichnung der Uhr noch löschen muss- ich hab nur das Objekt zerstört. Somit funktioniert es- bis auf die letzte Uhr. Trotz Abfrage kommt dann ne Fehlermeldung
http://d.imagehost.org/0297/Fehler.jpg

Ich muss mir ne passende Abfrage ausdenken.

ED: Hab eine überflüssige Zeile weggemacht. Funktioniert. Dabei sah das vorher schon so aus und hatte da glaub ich nicht funktioniert- wobei- es ist schwer sich an alles zu erinnern^^

ED2: Jetzt muss ich nur noch hinkriegen, dass er richtig am Ende vernichtet. Also dass er zum letzten Objekt geht und das zerstört... mit den gleichen Befehlen(bis auf ToFirst) wie oben funktionierts nicht

ED3: Und mal wieder: ich glaube, ich hab nichts geändert(nur ein paar mal compiliert, nicht mal delphi neugestartet) und auf einmal funktioniert das auch. Das ist doch krank...

Kennt jemand dieses Phänomen? Das nervt ziemlich, dass das so oft is


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:54 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz