![]() |
Objekt TList- ich versteh kein Wort!
Hallöle!
Momentan machen wir in Informatik(wie seit vielen Monaten) Objektorientier Programmierung und als nächste Reihe sollen Listenstrukturen kommen. Dafür sollen wir unser aktuelles Programm abändern. Dieses wäre, dass wir Uhren(analog) programmiert haben, die die Zeit anzeigen, sich bewegen und an den Rändern abprallen. Wir sollen nun so ändern, dass man beliebig viele Uhren hinzufügen kann(funktioniert ohne Liste, da er immer "Uhr1" createt), und auch, wie in einem Stack, diese wieder löschen kann. Durch dieses Createn als "Uhr1" löscht er aber, wie ich selbst rausgefunden hab(:D - es gehört zur Aufgabe rauszufinden wieso es nich klappt), nur eine der vielen Uhren, die als letztes Erzeugte. Dafür brauchen wir halt die Liste(Arrays sollen wir nicht), und unser Lehrer hat uns Seiten in unserem Wunderbaren Buch genannt, nur da ist zwar ne tolle Aufzählung mit Liste.Items und was weiß ich nicht, doch nix , wie man es anwendet. Ich find es momentan sehr kompliziert und konnt noch nichts finden, was mir helfen konnte. Ich geb mal den Code unseres Hauptprogrammes durch. Ich hab Delphi 6
Delphi-Quellcode:
Hier noch die Klasse(unterklasse ist irgendwie über der Oberklasse ^^'?):
unit mBewegteUhr;
{Übung 14.3 - Modifikation: West; Uhr2a --> BewegteUhr: September/Oktober 2008} interface uses Windows, Messages, SysUtils, Graphics, Controls, Forms, Dialogs, StdCtrls, classes, {z.B. für TList} mTBewegteUhr; {TBewegteUhr} type TMain = class(TForm) 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; public { Public-Deklarationen } end; var Main: TMain; implementation {$R *.DFM} procedure TMain.BtErzeugenClick(Sender: TObject); begin Uhr1 := TBewegteUhr.Create (Main.Width div 2, Main.Height div 2, 75); Uhr1.Kennt(Main); Uhr1.Zeigen; end; procedure TMain.BtVernichtenClick(Sender: TObject); begin if Uhr1 <> nil then begin Uhr1.Destroy; Uhr1 := nil end; end; procedure TMain.BtVerbergenClick(Sender: TObject); begin if Uhr1 <> nil then Uhr1.Loeschen; end; procedure TMain.BtZeigenClick(Sender: TObject); begin if Uhr1 <> nil then Uhr1.Zeigen; end; procedure TMain.FormClose(Sender: TObject; var Action: TCloseAction); begin BtVernichtenClick(Sender); end; procedure TMain.FormCreate(Sender: TObject); begin doublebuffered:= true; randomize; end;
Delphi-Quellcode:
Vielleicht kann mir ja jemand zumindest etwas helfen. Ich hab schon was versucht, aber aufgegeben das wär einfach nur Trial mit sehr viel Error geworden.
unit mTBewegteUhr;
{ Änderungen von West. Zeigt die 'echte' Zeit einschl. Sekunden an.} { Änderungen vom 30.08.2006 und vom 23.09.2008 Übergeben werden Mittelpunktskoordinaten und Radius. Die Uhr kann auf einem Hintergrund mit beliebiger Farbe dargestellt werden! } {Übung 14.3} interface uses Forms, {TForm} ExtCtrls, {TTimer} Graphics, {TCanvas} SysUtils; {Zeitmethoden} type TUhr = class (TObject) protected kContainer: TForm; { Formular, auf dem gezeichnet wird } zX, zY, zBreite: Integer; { Für Canvas-Methode 'Ellipse' benötigt } zXM, zYM, zRadius: Integer; { Mittelpunktskoordinaten } hZeit: TTimer; { Holt die Zeit (zum Stellen der Uhr) } zStd,zMin, zSec, SMSec: Word; procedure ZeitAnzeigen (Sender:TObject); procedure Zeichnen(color: TColor); public constructor Create(XM, YM, Radius: integer); destructor Destroy; procedure Kennt (Container: TForm); procedure Zeigen; procedure Loeschen; end; type TBewegteUhr = class(TUhr) private vx, vy: integer; procedure Bewegen (Sender:TObject); public constructor Create(XM, YM, Radius: integer); end; implementation (* ****************************** TBewegteUhr **************************** *) constructor TBewegteUhr.Create(XM, YM, Radius: integer); begin randomize; inherited create(XM, YM, Radius); vx:= -5+random(11); vy:= -5+random(11); hZeit.OnTimer:= Bewegen; hZeit.Enabled:= true; hZeit.Interval:= 30; // auch 1 ist möglich end; procedure TBewegteUhr.Bewegen(Sender:TObject); begin Loeschen; {Bei Reflexion gehen vx und vy in -vx bzw. -vy über - Impulserhaltungssatz} if zXM < zRadius then vx:= -vx; if zXM > (kContainer.ClientWidth - zRadius) then vx:= -vx; if zYM < zRadius then vy:= -vy; if zYM > (kContainer.ClientHeight - zRadius) then vy:= -vy; zXM:= zXM + vx; zYM:= zYM + vy; DecodeTime(Time, zStd, zMin, zSec, SMSec); // zStd:= 23; // nur für Testzwecke! // zMin:= 60; // nur für Testzwecke! // zSec:= 45; // nur für Testzwecke! Zeigen; end; (* alternativ bei der Reflexion: procedure TBewegteUhr.Bewegen(Sender:TObject); begin Loeschen; {Bei Reflexion gehen vx und vy in -vx bzw. -vy über - Impulserhaltungssatz} if zXM < zRadius then vx:= abs(vx); if zXM > (kContainer.ClientWidth - zRadius) then vx:= -abs(vx); if zYM < zRadius then vy:= abs(vy); if zYM > (kContainer.ClientHeight - zRadius) then vy:= -abs(vy); zXM:= zXM + vx; zYM:= zYM + vy; DecodeTime(Time, zStd, zMin, zSec, SMSec); // zStd:= 23; // nur für Testzwecke! // zMin:= 60; // nur für Testzwecke! // zSec:= 45; // nur für Testzwecke! Zeigen; end; *) (* ****************************** TUhr *********************************** *) constructor TUhr.Create (XM, YM, Radius: Integer); begin inherited Create; zXM:= XM; zYM:= YM; zRadius:= Radius; DecodeTime(Time, zStd, zMin, zSec, SMSec); // In der Online-Hilfe nachschauen! // zStd:= 23; // nur für Testzwecke! // zMin:= 60; // nur für Testzwecke! // zSec:= 45; // nur für Testzwecke! hZeit := TTimer.Create (nil); hZeit.Interval := 1000; hZeit.Enabled := False; hZeit.OnTimer := ZeitAnzeigen; end; destructor TUhr.Destroy; begin Loeschen; hZeit.Enabled := False; // muss unbedingt geschehen! hZeit.Destroy; inherited Destroy; end; procedure TUhr.Kennt (Container: TForm); begin kContainer := Container; end; procedure TUhr.Zeichnen(color: Tcolor); var StdWinkel, MinWinkel, SekWinkel: real; x, y: integer; begin with kContainer.Canvas do begin Pen.Color := color; // Brush.Color:= clWhite; Brush.Style:= bsclear; // Hintergrund in Containerfarbe Pen.Width := 2; zX := zXM - zRadius; zY := zYM + zRadius; zBreite := 2*zRadius; // Breite = Durchmesser der Uhr Ellipse (zX,zY,zX+zBreite,zY-zBreite); {großer Zeiger = Minutenzeiger} MoveTo (zXM,zYM); MinWinkel:= (zMin/60)*2*Pi; x:= zXM+Round(sin(MinWinkel)*0.9*zRadius); y:= zYM-Round(cos(MinWinkel)*0.9*zRadius); LineTo (x, y); {kleiner Zeiger = Stundenzeiger} MoveTo (zXM,zYM); if zStd >= 12 then zStd := zStd - 12; StdWinkel:= (zStd/12 + zMin/720)*2*Pi; x:= zXM+Round(sin(StdWinkel)*0.6*zRadius); y:= zYM-Round(cos(StdWinkel)*0.6*zRadius); LineTo (x, y); {Sekundenzeiger} Pen.Width := 1; MoveTo (zXM,zYM); SekWinkel:= (zSec/60)*2*Pi; x:= zXM+Round(sin(SekWinkel)*0.9*zRadius); y:= zYM-Round(cos(SekWinkel)*0.9*zRadius); LineTo (x, y); end; end; procedure TUhr.Zeigen; begin Zeichnen(clBlack); hZeit.Enabled:= true; end; procedure TUhr.ZeitAnzeigen (Sender:TObject); begin Loeschen; DecodeTime(Time, zStd, zMin, zSec, SMSec); // zStd:= 23; // nur für Testzwecke! // zMin:= 60; // nur für Testzwecke! // zSec:= 45; // nur für Testzwecke! Zeigen; end; procedure TUhr.Loeschen; begin hZeit.Enabled:= false; Zeichnen(kContainer.Color); end; end. Trotzdem mal hier, vllt. is was richtiges dabei(nur Hauptformular)
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, {z.B. für TList} mTBewegteUhr; {TBewegteUhr} 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; public { Public-Deklarationen } end; var Main: TMain; I : integer; implementation {$R *.DFM} procedure TMain.BtErzeugenClick(Sender: TObject); begin Liste.Items[I] := TBewegteUhr.Create (Main.Width div 2, Main.Height div 2, 75); Uhr1.Kennt(Main); Uhr1.Zeigen; end; procedure TMain.BtVernichtenClick(Sender: TObject); begin if Uhr1 <> nil then begin Uhr1.Destroy; Uhr1 := nil end; end; procedure TMain.BtVerbergenClick(Sender: TObject); begin if Uhr1 <> nil then Uhr1.Loeschen; end; procedure TMain.BtZeigenClick(Sender: TObject); begin if Uhr1 <> nil then Uhr1.Zeigen; end; procedure TMain.FormClose(Sender: TObject; var Action: TCloseAction); begin BtVernichtenClick(Sender); end; procedure TMain.FormCreate(Sender: TObject); begin Liste := TList.Create; Liste.First := 0 //Liste.Items [I] : Pointer; doublebuffered:= true; randomize; end; end. |
Re: Objekt TList- ich versteh kein Wort!
Hi,
ich nehme mir mal das Erzeugen raus und ändere das entsprechend ab. Der Rest muss dann natürlich analog erfolgen
Delphi-Quellcode:
cu
procedure TMain.BtErzeugenClick(Sender: TObject);
var idx : integer; begin // Objekt erzeugen und an die Liste hängen // idx hat dann die Position in der Liste idx := Liste.Add( TBewegteUhr.Create (Main.Width div 2, Main.Height div 2, 75) ); // Liste.Items[ idx ] ist vom Typ Pointer, zeigt also nur irgendwo hin // TBewegteUhr( Pointer ) sagt dem Programm, wie die Informationen an der Stelle // vom Pointer zu interpretieren sind TBewegteUhr( Liste.Items[ idx ] ).Kennt(Main); TBewegteUhr( Liste.Items[ idx ] ).Zeigen; end; Oliver |
Re: Objekt TList- ich versteh kein Wort!
Müsste idx nicht eine globale Variable sein?
Wenn ich nur Erzeugen nehme, gibts beim Buttonclick ne Fehlermeldung. Ich versuche mal den Rest wie du sagst analog zu ändern... Ich bekomme außerdem permanent beim compilieren und beim Speicher folgende Fehlermeldung: "Feld Main.Liste besitzt keine entsprechende Komponente. Soll die Deklaration entfernt werden?" |
Re: Objekt TList- ich versteh kein Wort!
Deklariere die Liste im private-Abschnitt.
|
Re: Objekt TList- ich versteh kein Wort!
Zumindest diese Fehlermeldung kommt jetzt nicht mehr. Danke schön.
Aber ich komm echt immer noch nicht klar. Weiß nicht wie ich das Vernichten machen soll, weiß einfach garnichts echt. Ich hab nicht mal Ansatz. Doch den hab ich, aber keine Ahnung ...
Delphi-Quellcode:
Hab die Variable global als posi dekliniert.
procedure TMain.BtVernichtenClick(Sender: TObject);
begin if TBewegteUhr(Liste.Items[posi]) <> nil then begin TBewegteUhr(Liste.Items[posi]).Destroy; TBewegteUhr(Liste.Items[posi]):= nil; Liste.Delete(Liste.Items[posi]); end; end; Bei dem Nil teil sagt er schon, der linken Seite kann nix zu gewiesen werden, und ich verzweifel hier. |
Re: Objekt TList- ich versteh kein Wort!
Hi,
Zitat:
Auf die anderen Uhren kann ich ja immer mit Liste.Items[ nr_von_welche_uhr_hätten_sie_denn_gerne ] (Achtung, das ist nur der Zeiger auf die Speicherstelle der Uhr) oder komplett TBewegteUhr( Liste.Items[ nr_von_welche_uhr_hätten_sie_denn_gerne ] ) zugreifen. Ausserdem hätte ich in idx immer nur den Index der zuletzt eingetragenen Uhr in der Liste und den bekomme ich auch über Liste.Count - 1 Ich gehe mal davon aus, dass ihr immer auf alle Uhren zugreifen sollt, also hier das "Vernichten"
Delphi-Quellcode:
cu
procedure TMain.BtVernichtenClick(Sender: TObject);
begin while Liste.Count > 0 do begin if Assigned( Liste.Items[ 0 ] ) then // Ist das gleiche wie Liste.Items[ 0 ] <> nil TBewegteUhr( Liste.Items[ 0 ] ).Free; Liste.Delete( 0 ); end; end; Oliver |
Re: Objekt TList- ich versteh kein Wort!
Das mit der Nummer_Blabla versteh ich absolut nicht. Wie oben gesagt denke ich ist das Löschen der Uhren wie ein Stack, immer die oberste, also weiß ich keine genaue Zahl.
Darum bezieht sich auch die Vernichtenprozedur von dir glaub ich auf was anderes...oder? Ich hasse gerade meinen Infolehrer...so eine Buchseite uns zu geben wo nix richtig erklä#rt wird. (Ich weiß dass langsam meine Fragen "dreist" werden aber bin echt verzweifelt, und verstehe gerade größtenteils Bahnhof) |
Re: Objekt TList- ich versteh kein Wort!
Zitat:
Wenn du nun mit einer Uhr etwas machen möchtest (sagen wir mal die 3. Uhr soll verschwinden), dann greifst du aif das Listenelement 2 zu mit Liste.Items[ 2 ] (denk dran, das erste Listenelement ist Liste.Items[ 0 ]). Will ich die 3. Uhr verschwinden lassen, dann mache ich das mit
Delphi-Quellcode:
Da man dieses Listenelement nun nicht mehr benutzen kann, schmeißt man es auch direkt sofort wieder aus der Liste
TBewegteUhr( Liste.Items[ 2 ] ).Free;
Delphi-Quellcode:
Liste.Delete( 3 );
Zitat:
Zitat:
hmmm, schade, wäre jetzt schön, die Buchseite mal zu sehen, sollte aber aus Urheberrechtsgründen NICHT hier ins Forum gestellt werden. cu Oliver |
Re: Objekt TList- ich versteh kein Wort!
Naja, in der Buchseite sind halt "Befehle" von TList, aber da steht nix, wie das integriert werden soll.Da steht dann zum Biespiel "Letztes Element [zeilensprung] Liste.Items[Liste.Count-1]" und das wird mir auch schon nciht klar und unter count würd ich jetzt was anderes verstehen.
Oder dein Erzeugen das steht da garnicht so. (glaub ich...?) Da steht Anhängen eines neuen Gebäudeobjektes: Liste.Add(Haus) Im Buch gehts drüberhinaus um ein Projekt was wir nie gemacht haben. Aber da steht nicht wie bei dir Haus.create. Was mich wundert bei deinem Vernichten war dass du da 0 in den eckigen klammern stehen hast... Da steht ja nicht dass das auf 0 runtermachen soll, kein index:= index-1 oder so ED: Ich hab mal (aufgrund meines Unwissens,ob ich da wieder so eine while schleife machen muss) BT Verbergen und Zeigen ausgeklammert, jetzt gibts schon beim Compilieren eine Fehlermeldung... Hier die Fehlermeldung die beim Erzeugen-BUtton-Klicken kommt: ![]() Und hier die wenn ich auslammer und compilieren: ![]() Sollt ich auch nochmal den aktullen Quellcode posten? Wenn nicht, tu ich es trotzdem... ;D
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, {z.B. für TList} mTBewegteUhr; {TBewegteUhr} type TMain = class(TForm) 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 : TList; public { Public-Deklarationen } end; var Main: TMain; implementation {$R *.DFM} procedure TMain.BtErzeugenClick(Sender: TObject); var idx : integer; begin // Objekt erzeugen und an die Liste hängen // idx hat dann die Position in der Liste idx := Liste.Add( TBewegteUhr.Create (Main.Width div 2, Main.Height div 2, 75) ); // Liste.Items[ idx ] ist vom Typ Pointer, zeigt also nur irgendwo hin // TBewegteUhr( Pointer ) sagt dem Programm, wie die Informationen an der Stelle // vom Pointer zu interpretieren sind TBewegteUhr( Liste.Items[ idx ] ).Kennt(Main); TBewegteUhr( Liste.Items[ idx ] ).Zeigen; end; procedure TMain.BtVernichtenClick(Sender: TObject); begin while Liste.Count > 0 do begin if Liste.Items[ 0 ] <> nil then begin TBewegteUhr( Liste.Items[ 0 ] ).Free; Liste.Delete( 0 ); end; end; end; {procedure TMain.BtVerbergenClick(Sender: TObject); begin if TBewegteUhr(Liste.Items[posi]) <> nil then TBewegteUhr(Liste.Items[posi]).Loeschen; end; procedure TMain.BtZeigenClick(Sender: TObject); begin if TBewegteUhr(Liste.Items[posi]) <> nil then TBewegteUhr(Liste.Items[posi]).Zeigen; end; } procedure TMain.FormClose(Sender: TObject; var Action: TCloseAction); begin BtVernichtenClick(Sender); end; procedure TMain.FormCreate(Sender: TObject); begin doublebuffered:= true; randomize; end; end. |
Re: Objekt TList- ich versteh kein Wort!
Zitat:
1. Element => Liste.Items[ 0 ] 2. Element => Liste.Items[ 1 ] 3. Element => Liste.Items[ 2 ] 4. Element => Liste.Items[ 3 ] 5. Element => Liste.Items[ 4 ] Wenn ich diese Liste nun abfrage mit Liste.Count bekomme ich als Ergebnis 5, klar ich habe ja auch 5 Elemente. Das letzte Element kann ich aber nur mit Liste.Items[ 4 ], und 4 ist nun mal 5-1 also Liste.Count - 1. Zitat:
Aber wenn ich ein Objekt der Liste hinzufügen möchte, dann muss ich das Objekt ja auch vorher erzeugen, oder?
Delphi-Quellcode:
procedure TMain.BtErzeugenClick(Sender: TObject);
var idx : integer; tmpUhr : TBewegteUhr; begin // Objekt erzeugen und an die Liste hängen // idx hat dann die Position in der Liste // Statt in einem Rutsch ... wie hier ... // idx := Liste.Add( TBewegteUhr.Create (Main.Width div 2, Main.Height div 2, 75) ); // machen wir das nun in 2 Schritten // erst mal eine Uhr erzeugen tmpUhr := TBewegteUhr.Create (Main.Width div 2, Main.Height div 2, 75); // und dann an die Liste hängen idx := Liste.Add( tmpUhr ); // Liste.Items[ idx ] ist vom Typ Pointer, zeigt also nur irgendwo hin // TBewegteUhr( Pointer ) sagt dem Programm, wie die Informationen an der Stelle // vom Pointer zu interpretieren sind TBewegteUhr( Liste.Items[ idx ] ).Kennt(Main); TBewegteUhr( Liste.Items[ idx ] ).Zeigen; end; Zitat:
Die Buchseite ist eigentlich nicht so schlecht, aber auch hier wird wie überall Transferleistung benötigt. cu Oliver |
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:
Wenn man sauber programmiert, dann sollte im Gegenzug beim Beenden des Formulars auch die Liste wieder entsorgt werden mit Liste.Free
procedure TMain.FormCreate(Sender: TObject);
begin doublebuffered:= true; randomize; Liste := TList.Create; end; cu Oliver |
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:
Jetzt darf das ding nur nicht abstürzen wenn keine Uhr mehr da ist.
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; |
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:
Hieraus kannst Du Dir dann deine eigentlichen Funktionen zusammenbasteln. Zum Beispiel würde ein Hinzufügen so aussehen:
Delphi-Quellcode:
Wenn Du alle Uhren bewegen willst, geht das im Prinzip so:
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;
Delphi-Quellcode:
Und das Löschen geht dann so:
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;
Delphi-Quellcode:
Soweit verständlich?
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; Gruß, SirTwist |
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:
Hier das Hauptprogramm:
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.
Delphi-Quellcode:
Hoffe ihr könnt mir helfen :(
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. |
Re: Objekt TList- ich versteh kein Wort!
Möglicherweise hilft es, wenn man FormCreate und die Formdeklaration ein klein wenig ändert:
Delphi-Quellcode:
TList ist bereits in Classes definiert, daher ist der Name "ungünstig" gewählt.
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; |
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. |
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.
|
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
![]() 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:48 Uhr. |
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