![]() |
TObjectlist in TObjectList
Hallo,
ich habe da ein kleines problemchen:
Delphi-Quellcode:
und nun habe ich eine weiter tList um das object zu verwalten. das heißt so eine art Object Baum.
TStyle = record
obj1:TObjectList; ..... end; Ich möchte gerne folgendes erreichen: In unser grafik programm "ProGraphic" möchte ich genre noch ein object Kontener einbauen so wie der panel unter delphi d.h. wenn ich mehre objecte verschiebe und die auf ein anderes object verschiebe soll dieses object wo sie drauf geschoeben wurden sind sie besitzt problem: ich habe eine standart liste da sind alle drin und jetzt hat jedes object ein objl Tobjectliste wo alle objecte reinkommen sollen: der code sieht so aus:
Delphi-Quellcode:
der scheint auch zu funktionieren problem ist nur beim zeichnen muss ich auf eine funktion von TFigure drauzugreifen:
procedure TForm1.BitBtn1Click(Sender: TObject);
var i:Integer; s,s1:TStyle; begin // Beim Makierten object die neue liste installisieren if TFigure(obj.Items[SelObj]).Style.obj1 = nil then begin with TFigure(obj.Items[SelObj]).Style do obj1:=TObjectList.Create; end; for i:=obj.count-1 downto 0 do begin if (TFigure(obj.Items[i]).Style.isSel = True) and (i <> SelObj) then begin if TFigure(obj.Items[i]).Style.obj1 = nil then begin s:=TFigure(obj.Items[i]).Style; AddObj(s.Typ,TPenTool(s.objTypI),TFigure(obj.Items[i]).Style,TFigure(obj.Items[SelObj]).Style.obj1); if TFigure(obj.Items[i]).Style.obj1 <> Nil then begin TFigure(obj.Items[i]).Style.obj1.Clear; TFigure(obj.Items[i]).Style.obj1.Destroy; end; obj.OwnsObjects:=True; obj.Remove(obj.Items[i]); fEigenschaften.clbObjektListe.Items.Delete(i); end // if obj1 = nil else ShowMessage('Objete müssen leer sein,'+#13+' wenn sie verschoben werden sollen'); end; end; end;
Delphi-Quellcode:
procedure TForm1.DrawBmp; //Markierungsrahmen
var i,x: Integer; oldColor:TColor; begin Label2.Caption:=IntToStr(t); ClearBmp; if Obj.Count>0 then begin for i:=0 to Obj.Count-1 do begin if TFigure(obj.Items[i]).Style.obj1 <> NIL then begin for x:=0 to TFigure(obj.Items[i]).Style.obj1.Count-1 do begin with TFigure(Obj[i]).Style.obj1 do begin TFigure(Items[x]).Draw(bmp); // DrawStyle(TFigure(TFigure(Obj[i]).Style.obj1.Items[i])); end; end; end else begin if TFigure(Obj[i]).Style.Visible = True then begin TFigure(Obj[i]).Draw(Bmp); DrawStyle(TFigure(Obj[i])); end; //if visible end; // else end; // for end; // if obj PaintBox1.Canvas.Draw(0,0,Bmp); StatusBar1.Panels[5].Text:= 'Objekt ' + IntToStr(SelObj+1); end; und bei TFigure(Items[x].draw(bmp] kommt eine av und das programm beendet sich... kann mir jemmand sagen warum ? bzw. eine lösung geben. Währe sehr dankbar.... |
Re: TObjectlist in TObjectList
Hat keiner eine idee wie das gehen könnte ?
|
Re: TObjectlist in TObjectList
HI,
ich hab ehrlich gesagt keine richtige Idee was deine Frage an einigen Stellen betrifft: Zitat:
Um das Objekt zu verwalten? Wo ist denn das Objekt? Ein Record ist kein Objekt! Zitat:
An sich würde ich dir hier zu etwas ObjektOrientierung (OO) raten. Für eine solche "Hierachie" und soetwas wie den Bau eines Containers eignet die sich sehr gut. Du kannst einfach eine Basisklasse für alle Grafikobjekte und eine für alle "Container" schaffen. Die Klasse der Container sollte dabei von der Klasse der Grafikobjekte erben. Die hat dann einfach nur die Eigenschaft, zusätztlich Elemente zu Speichern.
Delphi-Quellcode:
So ganz grob (entschuldige, merke gerade dass meine Variablenbenennung ganz furchtbar ist, durchmischt deutsch/englisch).
type
TGrafikBasisKlasse = class(TObject) private FXPosition : Integer; FYPosition : Integer; ... protected draw; virtual; abstract; setXPosition(const x : Integer); setYPosition(const y : Integer); ... public property XPosition : Integer read FXPosition write setXPosition; property YPosition : Integer read FYPosition write setYPosition; ... end; TGrafikContainerBasisKlasse = class(TGrafikBasisKlasse) private FContainedObjects : TObjectList; protected setXPosition(const x : Integer); override; setYPosition(const Y : Integer); override; addGraphicObject(const GraphicObject : TGrafikBasisKlasse); removeGraphicObject(const GraphicObject : TGrafikBasisKlasse); public end; Natürlich soll das jeztt keine vollständige Klasse sein, müsstest du entsprechend erweitern. Wichtig ist es die grobe Struktur zu verstehen. Alle Objekte die du verwendest sollten von TGrafikBasisKlasse erben. Sind sie zu dem auch noch ein Container, erben sie entsprechend von TGrafikContainerBasisKlasse (und damit implizit auch von TGrafikBasisKlasse). Also kannst du immer den in ein TGrafikBasisKlasse Objekt casten und die hier vorgegebenen Funktionen nutzen. Wenn nun setXPosition aufgerufen wird, musst du die x Position deiner Komponente ändern und neu zeichnen. Hierzu kann jede deiner Komponenten (die du ableitest) einfach die draw Methode überschreiben, wo es sich hinzeichnet geht ja aus den gespeicherten Koordinaten hervor. Hast du einen Container (etwas dass von TGrafikContainerBasisKlasse erbt), so brauchst du hier nicht mehr zu tun, als die Methode, die diesen Container bewegt zu überschreiben. Deine überschriebene Methode ruft dann einfach ihren Vorgänger auf (schließlich muss auch dein Container an der richtigen Stelle gezeichnet werden) und muss danach nur noch alle ELemente bewegen, die in der eigenen Liste drin stehen.
Delphi-Quellcode:
Wie gesagt, es sind nur Anregungen, bei der konkreten Umsetzung musst du schauen. Wenn du es so oder ähnlich machst, denke ich solltest du kein Problem bekommen. Werde mir trotzdem gleich noch deinen Code anschauen, vielleicht sehe ich ja dort den Fehler.
TGrafikContainerBasisKlasse.setXPosition(const x : Integer);
var diffX : Integer; i : Integer; begin diffX := x - self.XPosition; inherited setXPosition(x); if self.FContainedObjects.Count > 0 then begin for i := 0 to self.FCountaindedObjects.Count - 1 do begin // eine Methode move wäre hier sinnvoller als das TGrafikBasisKlasse(self.FContainedObjects[i]).setXPosition(TGrafikBasisKlasse(self.FContainedObjects[i].XPosition) + diffX); end; // for i := 0 to self.FCountaindedObjects.Count - 1 end; // if self.FContainedObjects.Count > 0 end; Gruß Der Unwissende |
Re: TObjectlist in TObjectList
Ok,
sorry wenn ich das jetzt mal so sage, aber an deinem Code solltest du noch etwas arbeiten. Ich weiß nicht wie groß das Grafikprogramm ist oder werden soll, aber gerade bei etwas größeren Projekten zahlen sich ein paar Dinge aus. Es gibt nette (kleine) Bücher dazu, die haben so ein paar Grundregeln über guten Codestil drin. Gibt sicherlich auch online etwas.. Die sollte man (imho) berücksichtigen. Also mir hat das echt eine Menge gebracht (nicht falsch verstehen, ist wirklich als Tipp gemeint und hilft häufig Fehler zu vermeiden, Code lesbarer zu machen und auch wartbar und ist gerade bei der Arbeit von mehreren am selben Programm unabdingbar). Kurz dazu dann ein paar Worte:
Ist wirklich nicht so schlimm wie es jetzt vielleicht klingt, aber diese Kleinigkeiten machen Code schnell unübersichtlicher als er sein muss. Kommen wir zu deinem eigentlichen Problem: Zitat:
Vorteile liegen dann wirklich darin, dass du diese Klassen (die immer die Eingabe prüfen) auch woanders weiter verwenden kannst. |
Re: TObjectlist in TObjectList
also wegen dem codestyl:
ich finde der ist für mich übersichtlich aber das ist geschmacksache.... das mit den Variabeln bennung undsoweiter hast du natürlichrecht nur ich bin dazu zufaul wenn mir keine auf anhib einfallen die die funktion der variable/procedure beschreiben.... zum With: ich wollte es auch weglassen nur dann kamm ein compiler fehler: "Linkeseite kann nicht zugewisen werden." das habe ich auch nicht ganzso verstanden. und mit with hat es halt geklappt darum.... zum eigentlichen problem: ich habe mehre Objekte und jedes objekte soll in der lage sein Weiter Objekte aufzunehmen also ein "Objekt Container" wobei die objekte verschoben werden sollten in das objekte wo ich es hineinziehe.... Ich schreibe in einem team ein grafikprogramm und wenn ich es jetzt umstelle auf OOP können wir gleich von vorne anfangen das wollten wir nicht(ich schon aber)... aber warum hat das mit meiner idee nicht geklappt. Ich hatte doch eine prüfung <> nil gemacht ---- Zitat:
|
Re: TObjectlist in TObjectList
Zitat:
Zitat:
Bei euerm Grafikprogramm kommt der Punkt vielleicht nie und hätte wahrscheinlich auch weniger wilde Konsequenzen, aber wenn es an einem Feature scheitert, dass ein Kunde bezahlt hat... Also klar, man kann auch heute noch super Programme ohne OOP produzieren, aber es gibt ja Ideen hinter der (sinnvollen) Verwendung und Modellierung mit Objekten. Und mit etwas Erfahrung kann man dort sehr schön sehr mächtigen Code erzeugen (leicht erweiterbar durch Verhaltens- und Objektvererbung). Gerade wenn ihr im Team arbeitet sollten alle Variablen sofort sinnvoll benannt werden. Es blickt ab einem gewissen Punkt sonst keiner mehr durch (glaub mir, hab da so einige Erfahrung aus eben solchen vermeidbaren Fehlern, die ich mitverschuldet habe). Sind aber alles nur persönliche Erfahrungen und Meinungen, soll wirklich nur als Anregung nicht als Kritik verstanden werden. Wie gesagt, es geht auch ohne! Zitat:
Zitat:
Eine TObjectList hingegen speichern nur Instanzen von Klassen. Da jede Klasse von TObject abgeleitet ist, kannst du hier also wirklich Instanzen aller Klassen speichern (musst entsprechend nur casten). Da jedes TObject (und damit alle Nachfahren) auch einen Destruktor haben, kann sich eine TObjectList auch gleich um die freigabe der gespeicherten Objekte kümmern. Da du sagtest du hast eine weitere TList, ging ich jetzt also von zwei TList Instanzen aus, nicht zwei TObjectList Instanzen. Klingt jetzt vielleicht ein wenig kleinlich, aber es ist ein wirklich wichtiger Unterschied (was die Benutzung angeht), denn während du in einer TList einen Zeiger auf alles speichern kannst, kannst du nicht jeden Zeiger als Objekt in einer TObjectList ablegen sondern eben nur Objekte. |
Re: TObjectlist in TObjectList
Bei meiner suche bin ich auch auf diese problem gestoßen mit Tlist und TObjectList aber wir verwenden TObjectList.
was sind den objekte: Klassen Record ? ich habe das problem gefunden ist liegt an der Remove funktion von TObjectList nur ich weiß nicht wie ich es andere lösunen kann. ich zeichne in einen timer alle objekte das habe ich jetzt unterbunden..... Wenn ich den zeichnen vorgang wieder starten möchte kommt wieder die av.... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:09 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