VirtualTreeview
VirtualTreeview
Hallo zusammen,
ich weiß gar nicht ob das VirtualTreeview überhaupt für meine zwecke das richtige ist.
ich suche ein grid welches zwei spalten hat.
erste spalte ein kleines Icon und zweite eine Beschreibung.
die Einträge müssen aufklappbar sein für weitere Eigenschaften.
nun ich denke damit bin ich ganz gut beraten. Mein Problem ist halt das ich so null Erfahrungen mit dem ding habe
wie ich die Spalten hinzufügen kann weiß ich
aber wie bekomme ich denn überhaupt Einträge darein?
aus dem wiki werde ich null schlau
http://wiki.lazarus.freepascal.org/Virt ... or_Lazarus
hat jemand für mich ein einfaches bespiel?
ich weiß gar nicht ob das VirtualTreeview überhaupt für meine zwecke das richtige ist.
ich suche ein grid welches zwei spalten hat.
erste spalte ein kleines Icon und zweite eine Beschreibung.
die Einträge müssen aufklappbar sein für weitere Eigenschaften.
nun ich denke damit bin ich ganz gut beraten. Mein Problem ist halt das ich so null Erfahrungen mit dem ding habe
wie ich die Spalten hinzufügen kann weiß ich
aber wie bekomme ich denn überhaupt Einträge darein?
aus dem wiki werde ich null schlau
http://wiki.lazarus.freepascal.org/Virt ... or_Lazarus
hat jemand für mich ein einfaches bespiel?
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1435
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: VirtualTreeview
Mit der Eigenschaft Tree.RootNodeCount kannst du die Anzahl der Einträge festlegen.
Re: VirtualTreeview
hmm
ja aber was ist wenn ich nun drei einträge haben will
wie
test1
test2
test3
gut wenn ich den tree.RootNodeCount := 3 hoch setze habe ich aber immer noch nicht die drei Einträge drin
ja aber was ist wenn ich nun drei einträge haben will
wie
test1
test2
test3
gut wenn ich den tree.RootNodeCount := 3 hoch setze habe ich aber immer noch nicht die drei Einträge drin
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1435
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: VirtualTreeview
Doch hast du,
Im Fall von dem VirtualStringTree musst du die Events onInitNode und onGetText implementieren.
In dem Package virtualtree_lcl gibt es jede Menge Demos die das zeigen.
Im Fall von dem VirtualStringTree musst du die Events onInitNode und onGetText implementieren.
In dem Package virtualtree_lcl gibt es jede Menge Demos die das zeigen.
Re: VirtualTreeview
wow ist das umständlich
kann ich ein Note für den Text nicht direkt ansprechen?
und vorallen klappt das mit dem text überhaupt nicht so wie ich mir das vorstelle
kann ich ein Note für den Text nicht direkt ansprechen?
und vorallen klappt das mit dem text überhaupt nicht so wie ich mir das vorstelle
Code: Alles auswählen
unit Main;
{$mode objfpc}{$H+}
interface
uses
Classes,
SysUtils,
db,
FileUtil,
Forms,
Controls,
Graphics,
Dialogs,
StdCtrls,
DBGrids,
ZConnection,
ZDataset,
VirtualDBGrid,
VirtualTrees;
type
{ TfrmMain }
TfrmMain = class(TForm)
Button1: TButton;
btnAdd: TButton;
dsUebersicht: TDataSource;
ProjektBaum: TVirtualStringTree;
zVerbindung: TZConnection;
zUebersicht: TZQuery;
procedure btnAddClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure ProjektBaumGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
procedure ProjektBaumInitNode(Sender: TBaseVirtualTree; ParentNode,
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
private
nCount : Integer;
public
end;
var
frmMain: TfrmMain;
implementation
{$R *.lfm}
{ TfrmMain }
procedure TfrmMain.btnAddClick(Sender: TObject);
begin
ProjektBaum.RootNodeCount := ProjektBaum.RootNodeCount + 1;
end;
procedure TfrmMain.FormShow(Sender: TObject);
begin
dsUebersicht.DataSet.First;
while not dsUebersicht.DataSet.EOF do begin
ProjektBaum.RootNodeCount := dsUebersicht.DataSet.FieldByName('ID').AsInteger;
dsUebersicht.DataSet.next;
end;
end;
procedure TfrmMain.ProjektBaumGetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: String);
begin
if (Column = 1) then begin
CellText := dsUebersicht.DataSet.FieldByName('Projektname').AsString;
end;
end;
procedure TfrmMain.ProjektBaumInitNode(Sender: TBaseVirtualTree; ParentNode,
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
end;
end.
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1435
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: VirtualTreeview
Der VirtualTreeview selbst hat keine Texte. Du musst einen Record definieren, der die Daten beinhaltet die du für jede Node zum darstellen brauchst.
Das mit dem RootnodeCount ist ja nicht dafür gedacht um den Zeilenweise zu erhöhen sondern wenn man soviele Nodes auf einmal erstellen will.
Da du die Daten aus einer Datenbank holst, reicht es aus in dem Record die ID zu speichern oder den Namen gleich mit.
In ProjektBaumGetText schreibst du dann.
Das scheint tatsächlich anfangs etwas umständlich zu sein aber dafür ist das extrem flexibel weil der Virtualtreeview keinerlei Annahmen über den Inhalt der darzustellenden Daten macht sondern alles über Events abfragt.
Ich habe für mich übrigens den VirtualTreeview etwas umgebaut weil ich immer die Instanz einer Klasse in die Trees hänge.
Dadurch spare ich mir das abholen der Daten mit Tree.GetNodeData sondern greife direkt auf Node.Data als Zeiger auf eine Klasseninstanz zu.
Das mit dem RootnodeCount ist ja nicht dafür gedacht um den Zeilenweise zu erhöhen sondern wenn man soviele Nodes auf einmal erstellen will.
Da du die Daten aus einer Datenbank holst, reicht es aus in dem Record die ID zu speichern oder den Namen gleich mit.
Code: Alles auswählen
type
PMyRec = ^TMyRec;
TMyRec = record
id : integer;
Projektname : string;
end;
procedure TfrmMain.FormShow(Sender: TObject);
var myRec : PMyRec;
begin
ProjektBaum.NodeDataSize := sizeOf(PMyRec);
dsUebersicht.DataSet.First;
while not dsUebersicht.DataSet.EOF do begin
new(myRec);
myRec^.id := dsUebersicht.DataSet.FieldByName('ID').AsInteger;
myRec^.Projektname := dsUebersicht.DataSet.FieldByName('Projektname').AsString;
ProjektBaum.AddChild(nil, myrec);
dsUebersicht.DataSet.next;
end;
end;
In ProjektBaumGetText schreibst du dann.
Code: Alles auswählen
procedure TfrmMain.ProjektBaumGetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: String);
var myRec : PMyRec;
begin
myRec := ProjektBaum.getNodeData(Node);
case Column of
-1, 0 : CellText := IntToStr(myRec^.Id);
1 : CellText := myRec^.Projektname;
end;
end;
Das scheint tatsächlich anfangs etwas umständlich zu sein aber dafür ist das extrem flexibel weil der Virtualtreeview keinerlei Annahmen über den Inhalt der darzustellenden Daten macht sondern alles über Events abfragt.
Ich habe für mich übrigens den VirtualTreeview etwas umgebaut weil ich immer die Instanz einer Klasse in die Trees hänge.
Dadurch spare ich mir das abholen der Daten mit Tree.GetNodeData sondern greife direkt auf Node.Data als Zeiger auf eine Klasseninstanz zu.
Re: VirtualTreeview
hey Fliegermichl,
ahhhh es werde licht.
Nun stellt sich aber komplett eine andere Frage
ich glaube für mein vorhaben ist das die komplettfalsche Komponente. Ich Suche ja eher was die Eigenschaften eines DB Grid hat
aber es soll halt diesen Alten muss nicht haben.
Ergo ich hätte gerne Mehrzeiligkeit in einer Zelle und es sollen Icons dargestellt werden können
gut Icons bekomme ich auch in ein DB Grid
sieht aber alles noch so alt und muffig aus
Zur zeit erzeuge ich zur Laufzeit die Ganzen Labels und Icons
das ist nur leider sehr langsam
Daher bin ich auf der suche nach einen schöneren neuen DB Grid
hast du da Ideen?
ahhhh es werde licht.
Nun stellt sich aber komplett eine andere Frage
ich glaube für mein vorhaben ist das die komplettfalsche Komponente. Ich Suche ja eher was die Eigenschaften eines DB Grid hat
aber es soll halt diesen Alten muss nicht haben.
Ergo ich hätte gerne Mehrzeiligkeit in einer Zelle und es sollen Icons dargestellt werden können
gut Icons bekomme ich auch in ein DB Grid
sieht aber alles noch so alt und muffig aus
Zur zeit erzeuge ich zur Laufzeit die Ganzen Labels und Icons
das ist nur leider sehr langsam
Daher bin ich auf der suche nach einen schöneren neuen DB Grid
hast du da Ideen?
-
- Lazarusforum e. V.
- Beiträge: 3158
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: VirtualTreeview
TT73GP7 hat geschrieben:ich glaube für mein vorhaben ist das die komplettfalsche Komponente. Ich Suche ja eher was die Eigenschaften eines DB Grid hat
aber es soll halt diesen Alten muss nicht haben.
Um welchen "Alten muss" geht es denn? Das Aussehen des Headers stelle ich auch regelmäßig auf "tsNative" um.
Ansonsten kannst du in jedem Grid (TDrawGrid, TStringGrid, TDBGrid) die Zellen selbst zeichnen (siehe z.B. auch https://stackoverflow.com/questions/267 ... ll-drawing). Wenn du sämtliche Daten in eigenen Datenstrukturen ablegst und nur wenig Text hast, nimmst du TDrawGrid und zeichnest alles selbst.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Re: VirtualTreeview
TT73GP7 hat geschrieben:ich glaube für mein vorhaben ist das die komplettfalsche Komponente. Ich Suche ja eher was die Eigenschaften eines DB Grid hat
Wieso denn DBGrid? Im ganzen Beitrag war bisher nicht die Rede, dass es hier um Datenbanken geht. Ohne Datenbank-Hintergrund nimm lieber TStringGrid, oder TValueListEditor (= TStringGrid mit nur 2 Spalten), oder TListView im Report-Style. Letzteres hat Icon-Support eingebaut.
Hier ist allerdings nichts aufklappbar.
[EDIT] Ich sehe geraden im Beispielcode weiter oben, dass du tatsächlich mit Datenbanken arbeitest. Leider kann man hier seine eigenen Beiträge nicht löschen...
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1435
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: VirtualTreeview
Der VirtualTreeview ist schon sehr gut geeignet. Über die TreeOptions kannst Du die Gridfunktionen aktivieren.
Damit die Spaltennamen sichtbar werden, muss Header->Options->hoVisible auf True gestellt werden.
Damit die Spaltennamen sichtbar werden, muss Header->Options->hoVisible auf True gestellt werden.
Re: VirtualTreeview
Ich würde auch nur noch auf ein VST zurückgreifen, es arbeitet sich damit wesentlich leichter.
OK, auch ich habe anfangs da so meine Schwierigkeiten gehabt, es ist schon eine recht "große" Komponente.
Jedoch wenn man sich dann etwas auskennt merkt man das soooo viele Vorteile vorhanden sind.
Das klassiche Tutorial zu dem VST ist für Einsteiger sicher ein guter Anfang.
ABER: So würde ich nicht mehr mit VST arbeiten. Im Tutorial wird für den NodeText immer erst ein Record(man kann auch ne Klasse/Instanz) angelegt.
In diesem dann Text abgelegt und im "onGetText" Event, erst die Node-Daten holen(zugriff auf das Record) und dann wird der Text zugewiesen.
Hierbei muss noch eine "onNodeInit" procedure bestückt werden....naja alles viel Vorbereitungsarbeit.
Ich mache das jetzt immer so, das zu einem VST eine Datenklasse gehört (man soll ja sowieso Daten und GUI-Komponenten voneinander trennen).
Also grobes Beispiel. Alle deine Datenbankeinträge (was ja auch schon wie so eine Art eigene Klasse angesehen werden kann) kannst du direkt im onGetText-Event den Node-Text zuweisen. Dabei würde aber immer wieder auf die Datenbank zugeriffen da die Nodetexte dynamisch dargestellt werden.
Du könntest als Datenklasse ein TStringlist nutzen. Alle Daten(Texte) die du anzeigen willst kommen dort "einmal" rein und dann kannst du die Texte leicht darstellen lassen.
Wenn du mehrere Zellen mit unterschiedlichem Text hast brauchst du etwas anderes als eine StringList.
Ich habe in meinen Projekten wiegesagt immer eine Daten Klasse.
EDIT:
Für diese art der Darstellung von Texten (und auch Bilder wenn man mag) spart einiges an Vorbereitungen und was am aller wichtigsten ist, du arbeitest Komponenten unabhängiger.
Du könntest das VST gegen etwas anderes ersetzen und musst dann noch noch in GUI die Ausgabe/Ansicht anpassen.
OK, auch ich habe anfangs da so meine Schwierigkeiten gehabt, es ist schon eine recht "große" Komponente.
Jedoch wenn man sich dann etwas auskennt merkt man das soooo viele Vorteile vorhanden sind.
Das klassiche Tutorial zu dem VST ist für Einsteiger sicher ein guter Anfang.
ABER: So würde ich nicht mehr mit VST arbeiten. Im Tutorial wird für den NodeText immer erst ein Record(man kann auch ne Klasse/Instanz) angelegt.
In diesem dann Text abgelegt und im "onGetText" Event, erst die Node-Daten holen(zugriff auf das Record) und dann wird der Text zugewiesen.
Hierbei muss noch eine "onNodeInit" procedure bestückt werden....naja alles viel Vorbereitungsarbeit.
Ich mache das jetzt immer so, das zu einem VST eine Datenklasse gehört (man soll ja sowieso Daten und GUI-Komponenten voneinander trennen).
Also grobes Beispiel. Alle deine Datenbankeinträge (was ja auch schon wie so eine Art eigene Klasse angesehen werden kann) kannst du direkt im onGetText-Event den Node-Text zuweisen. Dabei würde aber immer wieder auf die Datenbank zugeriffen da die Nodetexte dynamisch dargestellt werden.
Du könntest als Datenklasse ein TStringlist nutzen. Alle Daten(Texte) die du anzeigen willst kommen dort "einmal" rein und dann kannst du die Texte leicht darstellen lassen.
Code: Alles auswählen
var SL:TStringList;
procedure TfrmMain.ProjektBaumGetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: String);
begin
CellText := SL[Node^.index];
end;
Wenn du mehrere Zellen mit unterschiedlichem Text hast brauchst du etwas anderes als eine StringList.
Ich habe in meinen Projekten wiegesagt immer eine Daten Klasse.
Code: Alles auswählen
type MeineDatenklasse: TMyData;
var ObjectList: TObjectList;
procedure TfrmMain.ProjektBaumGetText(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
var CellText: String);
begin
case Column of
0 : CellText := TMyData(ObjectList.items[Node^.index]).Text_1;
1 : CellText := TMyData(ObjectList.items[Node^.index]).Text_2;
end;
// oder kürzer
with TMyData(ObjectList.items[Node^.index]) do
case Column of
0 : CellText := Text_1;
1 : CellText := Text_2;
end;
end;
EDIT:
Für diese art der Darstellung von Texten (und auch Bilder wenn man mag) spart einiges an Vorbereitungen und was am aller wichtigsten ist, du arbeitest Komponenten unabhängiger.
Du könntest das VST gegen etwas anderes ersetzen und musst dann noch noch in GUI die Ausgabe/Ansicht anpassen.
Re: VirtualTreeview
fliegermichl hat geschrieben:...
Ich habe für mich übrigens den VirtualTreeview etwas umgebaut weil ich immer die Instanz einer Klasse in die Trees hänge.
Dadurch spare ich mir das abholen der Daten mit Tree.GetNodeData sondern greife direkt auf Node.Data als Zeiger auf eine Klasseninstanz zu.
Genau so ähnlich hatte ich das auch mal versucht, da mir das "Daten holen" und Record anlegen umständlich vorkam.
Aber eben auch deine Methode hinterlegt "Zugangs-Punkte" in einem Node ab.
Also wenn du in deinem Programm was machts, was Nodes hinzufügen lässt, dann musst du in jedem neuen Node die Daten-Klasse zuweisen.
Wenn du also das VST mal austauschen musst, müsstest du dir dann wieder in der GUI Gedanken machen alles ordentlich anzeigen zu lassen,
oder wie machst du das?