[erstmal gelöst] Suche Grid/Tree-Komponente

Rund um die LCL und andere Komponenten
Antworten
Michl
Beiträge: 2513
Registriert: Di 19. Jun 2012, 12:54

[erstmal gelöst] Suche Grid/Tree-Komponente

Beitrag von Michl »

Hallo wertes Forum,

ich habe für mich ein Log-/Statusprogramm geschrieben, womit ich eigenständig laufende Programme mitlogge. Das funktioniert soweit auch problemlos. Ich möchte nun die Auswertung dieser LogFiles komfortabler gestalten. Bei Single-Thread-Applications würde ein VirtualStringTree (siehe Bild) den Job machen. Allerdings würde ich gern die Parallelläufigkeit, wie sie im Log ist, gern auch zur Ansicht erhalten.

Ein LogFile sieht bei mir in etwa so aus:

Code: Alles auswählen

1;1;TForm1.FormCreate;Form Created
1;1;TForm1.Button2Click;Geklickt!
4636;1;TMyThread.Create;Thread mit ID[4636] wird erstellt
5868;1;TMyThread.Create;Thread mit ID[5868] wird erstellt
3584;1;TMyThread.Create;Thread mit ID[3584] wird erstellt
4504;1;TMyThread.Create;Thread mit ID[4504] wird erstellt
6732;1;TMyThread.Create;Thread mit ID[6732] wird erstellt
1;1;TForm1.Button2Click;Habe [5] Threads erstellt!
4636;2;TMyThread.Execute;Thread mit ID[4636] wird ausgeführt
4636;3;TMyThread.Execute;Thread-Execute-Schleife
5868;2;TMyThread.Execute;Thread mit ID[5868] wird ausgeführt
5868;3;TMyThread.Execute;Thread-Execute-Schleife
4636;4;TMyClass.Addiere;Addiere Zahl1[59] mit Zahl2[54]
3584;2;TMyThread.Execute;Thread mit ID[3584] wird ausgeführt
3584;3;TMyThread.Execute;Thread-Execute-Schleife
5868;4;TMyClass.Addiere;Addiere Zahl1[84] mit Zahl2[71]
4504;2;TMyThread.Execute;Thread mit ID[4504] wird ausgeführt
4504;3;TMyThread.Execute;Thread-Execute-Schleife
5868;4;TMyClass.Addiere;Zahl1[84] und Zahl2[71] ergeben zusammen[155]
4636;4;TMyClass.Addiere;Zahl1[59] und Zahl2[54] ergeben zusammen[113]
4504;4;TMyClass.Addiere;Addiere Zahl1[84] mit Zahl2[54]
4504;4;TMyClass.Addiere;Zahl1[84] und Zahl2[54] ergeben zusammen[138]
6732;2;TMyThread.Execute;Thread mit ID[6732] wird ausgeführt
6732;3;TMyThread.Execute;Thread-Execute-Schleife
3584;4;TMyClass.Addiere;Addiere Zahl1[85] mit Zahl2[60]
4636;4;TForm1.UnterProc;Eine Unterprocedure wurde gestartet, sie startet per Zufall mindestens noch 12 weitere Unterproceduren
4636;5;TForm1.UnterProc;Eine Unterprocedure wurde gestartet, sie startet per Zufall mindestens noch 11 weitere Unterproceduren
4636;6;TForm1.UnterProc;Eine Unterprocedure wurde gestartet, sie startet per Zufall mindestens noch 10 weitere Unterproceduren
4636;7;TForm1.UnterProc;Eine Unterprocedure wurde gestartet, sie startet per Zufall mindestens noch 9 weitere Unterproceduren
4636;8;TForm1.UnterProc;Eine Unterprocedure wurde gestartet, sie startet per Zufall mindestens noch 8 weitere Unterproceduren
4636;9;TForm1.UnterProc;Eine Unterprocedure wurde gestartet, sie startet per Zufall mindestens noch 5 weitere Unterproceduren
6732;4;TMyClass.Addiere;Addiere Zahl1[43] mit Zahl2[38]
5868;4;TForm1.UnterProc;Eine Unterprocedure wurde gestartet, sie startet per Zufall mindestens noch 8 weitere Unterproceduren
5868;5;TForm1.UnterProc;Eine Unterprocedure wurde gestartet, sie startet per Zufall mindestens noch 7 weitere Unterproceduren
5868;E;TForm1.UnterProc;Zufallsfehler generiert für UnterProcedure 7
...
Im ersten "ExtractWord" eines Strings ist die ThreadID eines Threads gesetzt, der nachfolgende Aufrufe dieses untergeordnet werden. Nachfolgeaufrufe erhalten eine höhere ID (im zweiten ExtractWord sichtbar). Dann Name der Methode und ein Fehler-/Hinweis-/Statustext. Die Länge der Balken (im Bild) gibt die Menge der Childs (aufgerufene Methoden und deren aufgerufenen Methoden) an.

Zur Zeit kann ich wunderbar die einzelnen Threads als Node und Nachfolgeaufrufe als deren Child gruppieren, allerdings geht dabei die Parallelläufigkeit verloren (siehe Bild). Ebenfalls Fehlertexte und besondere Hinweise (da sie mich am meisten interessieren), kann ich derzeit nur nach einem Thread oder/und im Thread-Child (und darauf verlinkt), darstellen. Günstiger wäre es, an der Stelle, wo so ein Fehler-/Hinweistext generiert wurde, die Node-Child-Folge aufzubrechen und diesen dort zu zeigen.

Kennt jemand eine Komponente, mit der ich die Nodes bzw. deren Childs so aufsplittern kann, wie sie im oben gezeigten LogText notwendig wäre?

Falls nein, wäre mein nächster Ansatz die Verwendung eines Drawgrids, in dessen erste Spalte ich die Eigenschaft der Naviagtion (wie vom TreeView) mit den Icons[+][-] nachzubilden versuchen würde. Allerdings schätze ich den Aufwand für mehrere Tage/Wochen dafür ein, bevor das einigermaßen vernünftig funktionieren würde.

Bevor ich erst in eine falsche Richtung renne, kennt jemand eine alternative Komponente, die ich mir nochmal dafür anschauen könnte?
Wenn Ihr sowas vor hättet, wie würde Euer alternativer Ansatz aussehen?
Dateianhänge
Threads.png
Zuletzt geändert von Michl am Mi 10. Dez 2014, 20:00, insgesamt 1-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Benutzeravatar
theo
Beiträge: 11327
Registriert: Mo 11. Sep 2006, 19:01

Re: Suche Grid/Tree-Komponente

Beitrag von theo »

Also ich für meinen Teil habe keine Anhnung was du willst.
Ich dachte ich sag das mal, damit du dich nicht wunderst, warum niemand antwortet. :wink:

Vielleicht stellst du deine Vorstellungen mal grafisch dar?

Nur so ins Blaue aus der Erfahrung gesagt: VirtualTreeView ist die vielseitigste Komponente die ich kenne. Wenn man die nicht hinbiegen kann, dürfte es eng werden.

Michl
Beiträge: 2513
Registriert: Di 19. Jun 2012, 12:54

Re: Suche Grid/Tree-Komponente

Beitrag von Michl »

Das dachte ich mir beinahe, hatte auch lange gezögert, ob ich frage oder nicht. Im Kopf habe ich eine recht klare Vorstellung für das was ich will. Zu beschreiben ist für mich etwas schwer, ohne den ganzen Hintergrund ebenfalls mit zu posten (was dann ein so langer Text würde, was sich bestimmt keiner durchlesen wöllte).

Generell bin ich auch schwer begeistert vom VirtualStringTree. Ich dachte auch damit die Lösung gefunden zu haben, leider (soweit ich das recherchieren konnte) gibt es keine Möglichkeit innerhalb eines aufgeklappten Trees eine Node einzufügen, die nicht Teil dieses Trees ist.

Zur Zeit, sieht es wie folgt aus (bei einem Hinweis/einer Exception habe ich eine zusätzliche Node eingefügt habe, die auf den Hinweis verlinkt):

Code: Alles auswählen

Thread1                                     (MainThread)
  └── Thread1 1                             (z.B. Button1Click: starte 4 mal Division)
        ├──[+] Thread1 2                    (z.B. Methode dividiere zwei Zahlen)
        ├── Thread1 2                       (z.B. Methode dividiere zwei Zahlen)
        │     ├──[+] Thread1 3              (z.B. Hole zwei Zahlen z.B. "1" und "0"
        │     └── Thread1 3                 (z.B. Dividiere "1" durch "0")
        │           └── Hinweistext Thread1 (MainThread) 3 (Methode xyz) hat Exception Division durch Null ausgelöst
        ├──[+] Thread1 2                    (...)
        └──[+] Thread1 2
Hinweistext Thread1 (MainThread) 3 (Methode xyz) hat Exception Division durch Null ausgelöst
Das ist für einen einfachen Thread gut, weil eine Methode nach der anderen abgearbeitet wird, ich kann daher sehr gut einen Baum erstellen. Nun kommt aber z.B. ein zweiter Thread hinzu, der sich mit dem ersten überlagert. Daher funktioniert diese einfache Baumstruktur nicht mehr. Ich möchte die "Gleichzeitigkeit" auch darstellen, da sie mir eben mit einem schnellen Blick ermöglichen soll, festzustellen, welcher Thread welchen Thread und in welcher Weise beeinflusst hat.

So in der Art:

Code: Alles auswählen

Thread1                                     (MainThread)
  └── Thread1 1                             (z.B. Button1Click: starte 4 mal Division)
        ├──[+] Thread1 2                    (z.B. Methode dividiere zwei Zahlen)
Thread2                                     (Alternativer Thread)
        ├── Thread1 2                       (z.B. Methode dividiere zwei Zahlen)
        │     ├──[+] Thread1 3              (z.B. Hole zwei Zahlen z.B. "1" und "0"
   └── Thread2 1
        │     └── Thread1 3                 (z.B. Dividiere "1" durch "0")
        │           └── Hinweistext Thread1 (MainThread) 3 (Methode xyz) hat Exception Division durch Null ausgelöst
        ├── Thread2 2
        ├──[+] Thread1 2                    (...)
        └──[+] Thread1 2
        ├──[+] Thread2 2
...
Wobei mir klar ist, dass das so erstmal unübersichtlich ist, wenn man aber z.B. Thread 2 einklappt, dann müssten alle Childs dieses Threads ebenfalls mit eingeklappt werden, sodaß wieder eine einfache Baumstruktur von Thread 1 entsteht. (Evtl. könnte ich das Ganze auch mit unterschiedlichen Farbnuancen ausstatten, sodaß eine bessere Übersicht möglich ist - weiss ich aber noch nicht und ist dann eher Kür)

Ich hoffe Du verstehst jetzt eher meine Wunschvorstellung? Ach ja, die Komponente sollte eine LGPL oder eine ähnliche Lizens haben.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Benutzeravatar
theo
Beiträge: 11327
Registriert: Mo 11. Sep 2006, 19:01

Re: Suche Grid/Tree-Komponente

Beitrag von theo »

Also ich kann dir da nicht helfen und verstehe wahrscheinlich auch nicht ganz. Aber du brauchst das meinetwegen nicht weiter erklären.

Ein Tree ist ein Tree ist ein Tree... :wink:

Kommt denn irgend eine Darstellung hier: http://www.soft-gems.net/index.php/cont ... ew-gallery deinen Vorstellungen nah?

Michl
Beiträge: 2513
Registriert: Di 19. Jun 2012, 12:54

Re: Suche Grid/Tree-Komponente

Beitrag von Michl »

theo hat geschrieben:Kommt denn irgend eine Darstellung hier: http://www.soft-gems.net/index.php/cont ... ew-gallery deinen Vorstellungen nah?
Ich habe sie mir eben tatsächlich alle nacheinander angesehen, doch wie Du schon schriebst "Ein Tree ist ein Tree..." kann ich das nicht mit einem VST bewerkstelligen. :cry: Daher hatte ich ja die Frage hier nach einer alternativen Möglichkeit aufgestellt.

Danke für Deine Antworten, hilft es mir doch, mich auf meinen vermeindlichen Lösungsansatz mit einem DrawGrid zu konzentrieren und nicht weiter nach Alternativen zu suchen.

Falls aber doch noch jemand ein anders geartete Idee hat, immer her damit, bin für jeden Hinweis dankbar (denn das erspart mir evtl. unnötige Arbeit) :wink:

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Suche Grid/Tree-Komponente

Beitrag von mse »

Ich würde zwei unabhängige Anzeigen machen, die eine die nach threads geordnete Baumstruktur und eine Zweite chronologisch geordnete. Dabei sollten die fokussierten Zeilen synchronisiert werden. Falls ich die Anforderung richtig verstanden habe...

wp_xyz
Beiträge: 5441
Registriert: Fr 8. Apr 2011, 09:01

Re: Suche Grid/Tree-Komponente

Beitrag von wp_xyz »

Vom Problem her ähnlich ist der ProcessMonitor von SysInternals. Hier spielt sich alles sogar nur in einem grid-ähnlichen Control ab (ListView?, VirtualTree im Grid-Modus?), wobei die einzelnen Prozesse durch verschiedene Icons optisch gekennzeichnet sind. Darüber hinaus könnte man den 1. Eintrag eines Prozesses z.B. in grüner Schrift, den letzten in roter Schrift darstellen, es gibt da viele Möglichkeiten.

Michl
Beiträge: 2513
Registriert: Di 19. Jun 2012, 12:54

Re: Suche Grid/Tree-Komponente

Beitrag von Michl »

Danke erstmal für die Brainstorm-Unterstützung :D
wp_xyz hat geschrieben:Vom Problem her ähnlich ist der ProcessMonitor von SysInternals. Hier spielt sich alles sogar nur in einem grid-ähnlichen Control ab (ListView?, VirtualTree im Grid-Modus?), wobei die einzelnen Prozesse durch verschiedene Icons optisch gekennzeichnet sind. Darüber hinaus könnte man den 1. Eintrag eines Prozesses z.B. in grüner Schrift, den letzten in roter Schrift darstellen, es gibt da viele Möglichkeiten.
Habe mir mal ein paar Bilder dazu angesehen. In einer Liste dargestellt - so habe ich zur Zeit mein Auswertungsprogramm (StatusView). Der große Nachteil mMn ist, dass dabei die Abhängigkeiten nicht so gut darstellbar sind. Speziell interessiere ich mich für Meldungen wie "Exceptions" und "TODOs", welche jetzt per VirtualStringTree schon besser für mich kenntlich zu machen sind, als in der vorherigen Version per Tabelle.
mse hat geschrieben:Ich würde zwei unabhängige Anzeigen machen, die eine die nach threads geordnete Baumstruktur und eine Zweite chronologisch geordnete. Dabei sollten die fokussierten Zeilen synchronisiert werden. Falls ich die Anforderung richtig verstanden habe...
Der Gedanke kam mir vorhin auch mal kurz (hatte ihn aber irgendwie nicht weiter verfolgt), als ich mir die VST-Bilder von theos Link angeschaut hatte. Da waren auch einige Abbildungen Tabelle - Tree.
Wenn ich nochmal so darüber nachdenke, scheint mir das eigentlich gar keine schlechte Idee. Man könnte eine Liste per Grid mit den geparsten LogEinträgen, wie wp vorschlug auf die eine Seite stellen und ein VirtualStringTree mit der jeweiligen Threadmethode synchron auf der anderen Seite darstellen. Dann könnte man per Filter Statustexte/Exceptions/Hinweise zu- oder ausblenden. Das sollte auch recht unkompliziert und schnell umsetzbar sein (weil praktisch schon vorhanden, bis auf die Synchronisierung). Danke für die Anregung :idea: :!: So wird es wohl werden :D :D :D

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten