![]() |
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 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:21 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