![]() |
AW: Fragen zu VirtualTreeView
Zitat:
Bis bald... Thomas |
AW: Fragen zu VirtualTreeView
Moin
das kann sein, da habe ich einfach den Code aus dem Tutorial kopiert. Was mich irritiert ist das ich jedes Feld aus dem Record separat speichern muss. Kann man da den Record nicht en bloc speichern? Hans |
AW: Fragen zu VirtualTreeView
Hallo Thomas,
mir ging es um die einfachste Methode die Datei zu speichern. Es handelt sich um Fernsehserien, sprich Serie Folge Wie oft abgespielt Das ist relativ statisch, da werden die Daten eben nur selten geändert. Und da suche ich halt den bequemsten Weg. Hans |
AW: Fragen zu VirtualTreeView
Wenn man "Fernsehserien" durch "Alben" ersetzt und "Folgen" durch "Lied", hat man das Grundkonzept von meinem mp3-Player. :stupid:
Da habe mir ich zum Speichern ein eigenes Dateiformat gebastelt, welches auch nicht angepasst werden muss, wenn später mal weitere Informationen gespeichert werden sollen. Zusätzlich zur Länge und den eigentlichen String-Inhalt kommt bei mir u.a. noch eine internere "ID" hinzu, die angibt, welche Art von Info nun als nächstes kommt. Z.B. 1: Name der Serie, 2: Name der Folge, 3: Dateiname der Datei, 4: Größe der Datei, etc.pp. Dann können später weitere Datenfelder hinzugefügt werden, ohne dass ich das Dateiformat ändern muss (zwecks Abwärtskompatibilität beim Update des Programms). Das Ende der Daten für ein Objekt wird bei mir über die ID "255" gekennzeichnet. Gespeichert werden bei mir nur die Informationen zu den einzelnen Titeln (bei dir: Episoden). Die Gruppierung nach Alben (Serien) geschieht bei mir erst zur Laufzeit beim Laden der Liste. Dann ist auch leicht eine alternative Gruppierung im Treeview möglich (nach Erscheinungsjahr, Genre, Dauer, wasweißich). Das, was dir zu kompliziert vorkommt, ist also vermutlich der sinnvollere Weg. "Problem" sind halt die Strings mit variabler Länge. ;-) Nachteil bei meinem Ansatz ist nur, dass selbst kleinste Änderungen an einem einzelnen Objekt (Abspielzähler +1) ein Neuschreiben der gesamten Speicherdatei benötigen. Ein punktgenaues Ändern einzelner Stellen in der Datei ist nicht vorgesehen. |
AW: Fragen zu VirtualTreeView
Zitat:
Delphi-Quellcode:
Im TreeView Knoten "Data" auf ein TSeriesItem zeigen lassen oder den Daten-Index speichern. JSON als DB-Format. Das Serialisieren mit mORMot ist tolerant. Du kannst jeder Zeit dem Daten-Record TSeriesItem Felder hinzufügen oder sie wieder entfernen.
uses
mormot.core.base, mormot.core.json, mormot.core.os; type TSeriesItem = packed record FileName: String; SeriesName: String; EpisodeName: String; PlaybackCount: Integer; end; TSeriesItems = array of TSeriesItem; TSeriesDB = record Items: TSeriesItems; function Load(const pmcFileName: String): Boolean; procedure Save(const pmcFileName: String); end; function TSeriesDB.Load(const pmcFileName: String): Boolean; var json: RawJson; begin Result := False; json := StringFromFile(pmcFileName); if json <> '' then Result := (DynArrayLoadJson(Items, Pointer(json), TypeInfo(TSeriesItems)) <> Nil); end; procedure TSeriesDB.Save(const pmcFileName: String); var json: RawJson; begin json := DynArraySaveJson(Items, TypeInfo(TSeriesItems)); if json <> '' then FileFromString(json, pmcFileName); end; Oder klassisch mit Hilfe von TDynArray umgesetzt:
Delphi-Quellcode:
Anwendung so:
type
TSeriesDB = class(TObject) private FList: TDynArray; FItems: TSeriesItems; FItemCount: Integer; function GetItem(pmIndex: Integer): PSeriesItem; public constructor Create; destructor Destroy; override; function Add(const pmcFileName: String; const pmcSeriesName, pmcEpisodeName: String; pmPlaybackCount: Integer = 0): Integer; function Delete(pmIndex: Integer): Boolean; function LoadFromJsonFile(const pmcFileName: String): Boolean; function SaveToJsonFile(const pmcFileName: String): Boolean; property Item[pmIndex: Integer]: PSeriesItem read GetItem; property ItemCount: Integer read FItemCount; end; constructor TSeriesDB.Create; begin inherited Create; FList.Init(TypeInfo(TSeriesItems), FItems, @FItemCount); end; destructor TSeriesDB.Destroy; begin FList.Clear; inherited Destroy; end; function TSeriesDB.GetItem(pmIndex: Integer): PSeriesItem; begin if (pmIndex >= 0) and (pmIndex < FItemCount) then begin Result := @FItems[pmIndex]; end else Result := Nil; end; function TSeriesDB.Add(const pmcFileName, pmcSeriesName, pmcEpisodeName: String; pmPlaybackCount: Integer): Integer; var item: PSeriesItem; begin item := FList.NewPtr; item.FileName := pmcFileName; item.SeriesName := pmcSeriesName; item.EpisodeName := pmcEpisodeName; item.PlaybackCount := pmPlaybackCount; Result := FItemCount - 1; end; function TSeriesDB.Delete(pmIndex: Integer): Boolean; begin Result := FList.Delete(pmIndex); end; function TSeriesDB.LoadFromJsonFile(const pmcFileName: String): Boolean; var json: RawJson; begin json := StringFromFile(pmcFileName); if json <> '' then Result := (FList.LoadFromJson(Pointer(json), Nil, Nil, True) <> Nil) else Result := False; end; function TSeriesDB.SaveToJsonFile(const pmcFileName: String): Boolean; var json: RawJson; begin json := FList.SaveToJson(True, jsonHumanReadable); if json <> '' then Result := FileFromString(json, pmcFileName) else Result := False; end;
Delphi-Quellcode:
Bei Verwendung als Grid ohne filternde Funktionen reicht der Zugriff über Node Index auf die Daten aus.
procedure ...DoGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var item: PSeriesItem; begin item := FSeriesDB.Item[Node.Index]; if item <> Nil then begin case Column of 0: CellText := item.FileName; 1: CellText := item.SeriesName; 2: CellText := item.EpisodeName; 3: Celltext := item.PlaybackCount.ToString; end; end; end; begin FSeriesDB := TSeriesDB.Create; FSeriesDB.Add('X.mp4', 'X-Men', 'Folge 2'); FSeriesDB.Add('Y.mp4', 'Akte-Y', 'Folge 456'); VirtualStringTree.OnGetText := DoGetText; VirtualStringTree.RootNodeCount := FSeriesDB.ItemCount; Bis bald... Thomas |
AW: Fragen zu VirtualTreeView
Zitat:
Speichere deine Daten in einer Klassenstruktur und einer generischen Liste, dann brauchst du keine Streams. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:04 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