AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

VirtualTreeView und icons

Ein Thema von Wishmaster · begonnen am 9. Aug 2014 · letzter Beitrag vom 28. Aug 2014
Antwort Antwort
Seite 2 von 2     12
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#11

AW: VirtualTreeView und icons

  Alt 12. Aug 2014, 01:49
ok nochmal ich habe eine DB, und jeder eintrag in der DB hat sein eigenes Icon das ich dann nach bedarf in der VTV anzeigen möchtebei.
so jetzt muss ich das icon doch irgendwie aus der DB rausholen damit ich das anzeigen kann. richtig?
so ob ich das in eine NodeRecord, ImageList oder in irgend einer anderen liste zwischenspeicher und dan per index daraf zugreife.
(und wie schon gesagt eine ImageList kommt nicht in fragen wegen limit)
der speicher (Ram) wird immer gleich ausgelastet! richtig? und ein icon wiegt ~800 bytes.
ehrlich gesagt ich sehe kein unterschied. abgesehen von ein wenig mehr arbeitsspeicher verbrauch.


aber ich möchte es richtig machen, und ich würde mich echt freuen wenn ihr mir eine kleine demo schreiben konntet.
es gibt bestimmt jemanden der mehr plan von db's un vtv's hat den ich. und zeit um mir ne demo zu schreiben.
ich freue mich über jede hilfe. So thanks in advance


by the way ich benutze die Absolute Database
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#12

AW: VirtualTreeView und icons

  Alt 12. Aug 2014, 02:44
Selbstverständlich mußt du das Icon erst mal aus der Datenbank einlesen. Mit deiner Methode, das Icon in NodeData zu speichern, verursachst du unnötige CPU-Last beim Handling mit dem VTV, was natürlich bedeutet, daß der Aufbau eines riesigen Trees wie in deinem Fall unnötig verzögert wird. So müssen z.B. die Bitmaps in NodeData beim Umsortieren ständig mitkopiert werden, was bei einer externen Liste (Generics TObjectList) nicht nötig wäre, denn die hättest du einfach nur nach dem Index sortiert, damit das gesuchte Bitmap schnell gefunden wird.

Dazu erzeugst du dir erstmal eine Klasse:
Delphi-Quellcode:
UNIT Startbilder;

INTERFACE

USES
  ExtCtrls, StdCtrls, Classes, Graphics;

TYPE
  TStartBild = Class

    PRIVATE { Private-Deklarationen }
      Var
        fBild : TImage;
        fIndex : Integer;
        
      Function GetfBild : TImage;
      Procedure SetfBild(Const Value : TImage);
      Function GetfIndex : TImage;
      Procedure SetfIndex(Const Value : TImage);

    PUBLIC { Public-Deklarationen  }

      Constructor Create();
      Destructor Destroy; override;

      Property Bild : TImage read GetfBild write SetfBild;
      Property Index : Integer read GetfIndex write SetfIndex;

  END;

IMPLEMENTATION
{ TStartBild }

Function TStartBild.GetfBild: TImage;
begin
  Result := fBild;
end;

Procedure TStartBild.SetfBild(Const Value: TImage);
begin
  fBild.Assign(Value);
end;

Function TStartBild.GetfIndex: Integer;
begin
  Result := fBild;
end;

Procedure TStartBild.SetfIndex(Const Value: Integer);
begin
  fBild.Assign(Value);
end;

Constructor TStartBild.Create;
begin
  inherited;
  fBild := TImage.Create(nil);
  fBild.Visible := False;
  fBild.AutoSize := False;
  fBild.Stretch := False;
  fBild.Proportional := False;
  fBild.Center := False;
  fBild.Width := 30; // oder wie die Größe deiner Icons eben ist
  fBild.Height := 30;
end;

Destructor TStartBild.Destroy;
begin
     fBild.Free;
  inherited;
end;

end.
Dann deklariest du in der Formular-Unit, die den VTV aufnehmen soll, eine Objektliste:
Delphi-Quellcode:
  ...
  PRIVATE { Private-Deklarationen }
    Var
      BList : Generics.Collections.TObjectList<TStartBild>;
  ...
In FormCreate und FormDestroy deines VTV-Formulars schreibst du:
Delphi-Quellcode:
Procedure TFormMain.FormCreate(Sender: TObject);
begin
  BList := TObjectList<TStartBild>.Create;
  ...
end;

Procedure TFormMain.FormDestroy(Sender: TObject);
begin
  If BList.Count > 0 Then
  BList.DeleteRange(0,BList.Count-1);
  BList.Free;
  ...
end;
Den VTV baust du in einer privaten Methode auf, die z.B. bei Programmstart aufgerufen wird. Dort gehst du deine DB-Tabelle durch und liest die entsprechenden Spalten aus. In NodeData.Index schreibst du den Index deiner Tabelle, der mit dem Index in BList korrespondiert (nicht der Listen-Index, sondern der Eintrag Index, der in der Klasse festgelegt wurde).

Nachtrag:

Probier's doch einfach mal aus: Erstelle eine Exe mit den Icons in NodeData und eine mit den Icons in einer Objektliste, wobei du jedesmal die Zeit mißt, die vergeht, wenn du
  • den Baum aufbaust
  • den Baum sortierst
  • im Baum suchst.

Geändert von Perlsau (12. Aug 2014 um 03:03 Uhr) Grund: Nachtrag
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#13

AW: VirtualTreeView und icons

  Alt 12. Aug 2014, 07:22
[QUOTE=Perlsau;1268418]Mit deiner Methode, das Icon in NodeData zu speichern, verursachst du unnötige CPU-Last beim Handling mit dem VTV, was natürlich bedeutet, daß der Aufbau eines riesigen Trees wie in deinem Fall unnötig verzögert wird. So müssen z.B. die Bitmaps in NodeData beim Umsortieren ständig mitkopiert werden,...[QUOTE] Der Speicherverbrauch wächst minimal, d.h. um 4 Byte pro Record. Deine Argumention ist daher nicht schlüssig. Einzig die eventuell redundante Instantiierung von identischen Icons könnte man verbessern. Hier würde ich einen einfachen Cache vorschlagen. Zu klären wäre nur eine Funktion, die zu einem Icon einen eindeutigen Schlüssel generiert.

Zitat:
Den VTV baust du in einer privaten Methode auf, die z.B. bei Programmstart aufgerufen wird. Dort gehst du deine DB-Tabelle durch und liest die entsprechenden Spalten aus.
Das verzögert den Programmstart unnötig. Wenn nämlich nicht alle Icons benötigt werden, d.h. vielleicht auch nicht sichtbar sind. Ein Cache macht prinzipiell das Gleiche, nur eben on demand, bzw. per lazy load.
Diese Implementierung ist somit skalierbar, d.h. sie funktioniert auch bei sehr großen Datenmengen. Hier wäre natürlich die Visualisierung anzupassen, d.h. nur die Daten zu laden und im Speicher zu halten, die gerade benötigt werden.
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#14

VirtualTreeView und TImageList

  Alt 15. Aug 2014, 03:59
Ein Testlauf mit einer TImageList bzw. ein TjvImageList ergab Folgendes:

Knapp eine Million (genau: 923.168) Icon-Bitmaps der Größe 30x30 mit 24 Bit Farbtiefe wurden problemlos in eine ImageList geladen – allerdings nur mit einem 64-Bit-Programm unter einem Win64. Da würden auch noch etliche mehr reinpassen. Bei einem 32-Bit-Programm paßten in die Imagelist lediglich 771.725 Bitmaps dieser Größe (hängt wohl auch davon ab, was sich sonst noch so im Speicher tummelt). Eine Testanwendung habe ich nun so gestaltet, daß immer nur die Bitmaps in die Imagelist geladen werden, die auch aktuell ausgewählt wurden. Ich glaube kaum, daß ein Anwender sich in einer einzigen Sitzung durch alle Baumknoten klickt, um auch nur die Grenze der Imagelist bei einer 32-Bit-Anwendung, geschweige denn bei einer 64-Bit-Anwendung zu erreichen.

Wer sich für die Testanwendung incl. zugrundeliegender Testdatenbank (gepacktes Firebird-Backup ca. 300 MB) und Source interessiert, möge mir das via PM mitteilen. Die Datenbank enthält jene 923.168 Einträge (Geodaten von OpenGeoDB oder OpenStreetMap, weiß ich gerade nicht auswendig), denen jeweils ein oben beschriebenes Bitmap (in der DB gespeichert als Jpg-Grafik) zugeordnet ist. Das Program stellt diese Einträge als Baumstruktur dar, und zwar geordnet. Zum Kompilieren werden die DevArt-Komponenten IbDac benötigt, die man sich, falls man keine Lizenz hat, testweise bei Devart herunterladen kann.
Miniaturansicht angehängter Grafiken
vtvtest.jpg  
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#15

AW: VirtualTreeView und icons

  Alt 15. Aug 2014, 06:45


Ich glaube auch nicht, das hier die Grenze jemals erreicht wird, aber wenn man es -rein theoretisch- optimieren will (weil es regnet, einem langweilig oder nur um mal zu sehen, ob es geht), dann würde man einen Cache einbauen, der die Icon-ID mit dem ImageListIndex mappt. Und wenn nun die ImageList mehr als z.B. 1000 Einträge hätte, würde man den ältesten Eintrag aus dem Cache, und das Icon aus der ImageList rausschmeißen und im Cache alle Indexe aktualisieren.
  Mit Zitat antworten Zitat
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#16

AW: VirtualTreeView und icons

  Alt 27. Aug 2014, 07:30
Hi.

entschuldigung das ich mich nicht früher gemeldet hatte, war mit arbeit beschäftigt!
und danke an alle für eure hilfe.

@Perlsau
ich hatte an so etwas ähnliches selbst gedacht wie dein code schnipsel!
das problem war, ich muss nicht nur den index zum Icon managen
sondern auch den Index zur (TStartBild = Class).
so wenn ich auf die Daten im (TStartBild) zugreifen will mus ich ja den index zu der (TStartBild = Class) Wissen.
Delphi-Quellcode:
procedure TMain_form.RecordTreeBeforeCellPaint(Sender: TBaseVirtualTree;...)
begin
 TargetCanvas.Draw(R.Left, 0, BList .Items[index].Image); //index?

end;
// Delete

 BList.Delete(index); um ein bild freizugeben

thx.
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#17

AW: VirtualTreeView und icons

  Alt 27. Aug 2014, 11:40
Da es wohl kaum soweit kommt, daß der Anwender eine Million Icons gleichzeitig darstellen will, würde ich wie oben bereits beschrieben dennoch eine TImageList verwenden, die einfach immer nur die Icons enthält, die angezeigt werden bzw. in der aktuellen Sitzung bereits angezeigt wurden. Dafür reicht die Kapazität der TImageList auf jeden Fall aus, was ich mit Hilfe des oben vorgeführten Testprogramms herausfinden konnte.
  Mit Zitat antworten Zitat
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#18

AW: VirtualTreeView und icons

  Alt 28. Aug 2014, 08:34
Hi

an diesem punkt spielt es keine rolle ob ich eine ImageList oder dein Code benutze,
solange ich die icons klein halte 16x16 (und da muss ich ich mir noch etwas ausdenken)
ich meine, ich hatte zum test eine 4 MB image/Icon in die DB gespeichert und anschließend in die VTV geladen.
nur um die auslastung zu sehen.
und da ich den benutzer die möglichkeit geben will Icons von der festplatte zu laden.
muss ich das verhindern dass er absichtlich oder aus versehen riesige bilder als icons für die VTV speichert

normalerweise hat die listen ~ 20 einträge
E-Email einstellungen
logins für skype, Steam, Online Bank ...
das programm hat aber auch die möglichkeit Bookmarks von firefox zu parsen und in die DB speichern.
und in meine fall sind das eine ganze menge.
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#19

AW: VirtualTreeView und icons

  Alt 28. Aug 2014, 11:22
Du kannst den Anwender im Programm doch darauf hinweisen, daß nur Icon-Bilder bis zu einer gewissen Größe erlaubt sind:

ShowMessage('Das Bild ist zu groß für ein Icon und wird automatisch auf die Größe 16x16 verkleinert'; Und dann erzeugst du aus dem zu großen Bild mit StretchDraw einfach ein kleineres.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:20 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz