Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Hilfeersuchen - schnelle Anzeige Textdatei in TListBox (https://www.delphipraxis.net/208037-hilfeersuchen-schnelle-anzeige-textdatei-tlistbox.html)

CaseyRyback 31. Mai 2021 11:44

Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Hallo,
bitte um einen Tip.

Aktueller Zustand....
Wir arbeiten mit C++Builder Seattle und haben eine recht große und komplexe Applikation.
Wir lesenen eine Textdatei in eine ListBox ein und das dauert bei großen Dateien zB. >10MB sehr lange. Wir lesen die Datei zeilenweise und fügen das mit Add() der Listbox hinzu. Leider gibt es standardmäßig kein ReadFromFile() oder keine Stream-Methode.

Ein Memofeld geht zwar sehr schnell aber wir müssen hinterher einzelne Zeilen einfach markieren können, in der Gesamtliste schnell blättern und mit TopIndex und ItemIndex zugreifen können bzw. bestimmte Einzelzeilen zu gegebener Zeit als markiert anzeigen.

Gibt es eine andere Komponente, mit der ich diese großen Dateien möglichst schnell einlesen kann ?
Wenn ich einen Wald- und Wieseneditor mit meinen Dateien füttere, auch mit 100MB Größe, dann ist das sofort sichtbar.

Bin für jeden Tip dankbar...
Gruß vom Bodensee
B.L.

hoika 31. Mai 2021 11:59

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Hallo,
zeig doch mal etwas Quellcode,
wie Du das Einlesen machst.
(Stichwort z.B. BeginUpdate/EndUpdate)

stifflersmom 31. Mai 2021 12:01

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Wie wäre es mit:
Delphi-Quellcode:
Listboxdieesbetrifft.Items.LoadFromFile();

CaseyRyback 31. Mai 2021 14:16

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
danke für die schnellen Antworten...

Mein Code sieht prinziell so aus...
-----schnipp
f = fopen(ncPfad.c_str(),"rt");
if (f != NULL)
{
while ( ! feof(f))
{
fgets(str,190,f);
LineStr = AnsiString(str);
LineStr = LineStr.TrimLeft();
LBNCFile->Items->Add(LineStr);
uiCount++;
-----schnipp


Items->LoadFromFile()
hab ich auch grad getestet bringt, aber nicht wirklich eine Verbesserung.

Kennt jemand eine andere Komponente ? Gerne auch etwas kostenpflichtiges ?

Gruß
C.R.

BerndS 31. Mai 2021 14:31

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Wie wäre es mit VirtualStringTree. Der ist sehr schnell und kostenlos.

TiGü 31. Mai 2021 15:55

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Code:
f = fopen(ncPfad.c_str(),"rt");
if (f != NULL)
{
   LBNCFile->Items->BeginUpdate;
   while ( ! feof(f))
   {
      fgets(str,190,f);
      LineStr = AnsiString(str);
      LineStr = LineStr.TrimLeft();
      LBNCFile->Items->Add(LineStr);
      uiCount++;
      ...
   }
   LBNCFile->Items->EndUpdate;
   ...
};

CaseyRyback 31. Mai 2021 18:02

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Hallo und danke,
BeginUpdate() und EndUpdate() haben schonmal eine Halbierung der Zeit gebracht. Danke für den Tip.

Hat jemand einen Hinweis auf eine andere Komponente ? TMemo geht sehr schnell aber wie komme ich dann an die einzelnen Textzeilen und wie könnte ich die jeweils ganze Zeile mit einem Mausklick markieren ? Editiren muß ich das nicht.

Schönen Abend
Gruß
C.R.

sakura 31. Mai 2021 18:13

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Wie oben schon erwähnt, warum nicht einfach
Code:
LBNCFile->Items->LoadFromFile(...)
?

...:cat:...

dummzeuch 31. Mai 2021 18:20

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
TStringGrid? Oder vielleicht sogar TVirtualStringGrid (gibt's doch jetzt in Delphi, oder? Falls nicht TdzVirtualStringGrid aus meiner dzlib), dann kann man den Text gleich in einer TStringList lassen.

Das kann allerdings von Hause aus keine Checkboxen, die muss man nachbauen. Ist aber recht einfach. Probier erstmal, ob es schnell genug wäre.

TurboMagic 31. Mai 2021 19:10

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Zitat:

Zitat von CaseyRyback (Beitrag 1490476)
Hallo und danke,
BeginUpdate() und EndUpdate() haben schonmal eine Halbierung der Zeit gebracht. Danke für den Tip.

Hat jemand einen Hinweis auf eine andere Komponente ? TMemo geht sehr schnell aber wie komme ich dann an die einzelnen Textzeilen und wie könnte ich die jeweils ganze Zeile mit einem Mausklick markieren ? Editiren muß ich das nicht.

Schönen Abend
Gruß
C.R.

Zumindest an die Memo Zeilen kommst du über .Linea des Memos Ran.
Das ist ein TStrings, kann also wie ein Array angesprochen werden
und hat natürlich eine .Count Eigenschaft.

Grüße
TurboMagic

CaseyRyback 1. Jun 2021 11:14

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Hallo und danke an alle,
ich werde die verschiedenen Sachen testen und schauen, ob das für unsere Anwendung geht.
Gruß
C.R.

CaseyRyback 1. Jun 2021 13:00

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
danke an alle, ich teste das und melde mich wieder...
Gruß
C.R.

BerndS 1. Jun 2021 13:11

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Statt VirtualStringtree würde auch ein einfaches TListView gehen.
Mit den Einstellungen
Delphi-Quellcode:
    DoubleBuffered = True
    OwnerData = True
    ReadOnly = True
    RowSelect = True
    ViewStyle = vsReport
    OnData = lv1Data
und
Delphi-Quellcode:
procedure TForm1.lv1Data(Sender: TObject; Item: TListItem);
begin
  if Assigned(Item) then
  begin
    Item.Caption := Succ(Item.Index).ToString;
    Item.SubItems.Add(FLines[Item.Index]);
  end;
end;
geht es sehr schnell, da die Daten nicht in das Listview geladen werden müssen.
FLines muss eine TStringList sein, die per LoadFromFile die Daten enthält.

Das Beispiel verwendet zwei Spalten, Zeilennummer und Text. Es geht auch mit einer.
Delphi-Quellcode:
procedure TForm1.lv1Data(Sender: TObject; Item: TListItem);
begin
  if Assigned(Item) then
    Item.Caption := FLines[Item.Index];
end;

Michael II 7. Jun 2021 22:41

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Uwe Raabe hat vor langer Zeit eine kurze Geschichte zum ultraschnellen Befüllen von ListBoxen geschrieben. Ist in Delphi geschrieben, hilft aber doch sicher auch bei C++? Uwe Raabe verpackt 250'000 Einträge in 20 Millisekunden. Die ganze Story findest du hier.

Neumann 8. Jun 2021 07:35

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
In Delphi gibt es seit der letzten Version die TControlList, eine sehr schnelle und einfach zu verwendende Listenkomponente.

Vielleicht die mal ansehen.

CaseyRyback 15. Jun 2021 11:08

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Danke für alle Hilfen, der Tipp mit der Virtuellen StringList klappt gut und wir haben das eingebaut.
Vielen Dank dafür....
Gruß vom Bodensee

Maekkelrajter 16. Jun 2021 10:42

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Ich habe mir mal das von Michael II genannte Beispiel von Uwe Raabe heruntergeladen und ausprobiert. Seltsamerweise lassen sich mit dem Rollbalken nicht alle 250000 Einträge anzeigen. Beim Erreichen von 65535 fängt die Anzeige wieder bei 1 an, und wenn ich dann den Rollbalken 'loslasse', springt er wieder zurück auf Anfang, bzw. die Position der letzten Anzeige (1..65535)
Wenn ich die Einträge mit den Scrolltasten Up, Down, und 'Bild auf' und 'Bild ab' durchgehe, werden alle 250000 angezeigt.
Delphi-Quellcode:
unit Unit474;

interface

uses
  System.SysUtils, System.Classes,
  Vcl.Forms, Vcl.StdCtrls, Vcl.Controls;

type
  TForm474 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ListBox1Data(Control: TWinControl; Index: Integer; var Data: string);
    function ListBox1DataFind(Control: TWinControl; FindString: string): Integer;
  private
    FListBox1Items: TStringList;
  public
    destructor Destroy; override;
  end;

var
  Form474: TForm474;

implementation

uses
  System.Diagnostics;

{$R *.dfm}

destructor TForm474.Destroy;
begin
  FListBox1Items.Free;
  inherited Destroy;
end;

procedure TForm474.FormCreate(Sender: TObject);
begin
  FListBox1Items := TStringList.Create;
end;

procedure TForm474.Button1Click(Sender: TObject);
var
  I: Integer;
  sw: TStopWatch;
begin
  sw := TStopwatch.StartNew;
  FListBox1Items.Clear;
  for I := 1 to 250000 do
    FListBox1Items.Add(I.ToString);
  ListBox1.Style := lbVirtual;
  ListBox1.Count := FListBox1Items.Count;
  Label1.Caption := sw.ElapsedMilliseconds.ToString;
end;

procedure TForm474.ListBox1Data(Control: TWinControl; Index: Integer; var Data: string);
begin
  Data := FListBox1Items[Index];
end;

function TForm474.ListBox1DataFind(Control: TWinControl; FindString: string): Integer;
begin
  Result := FListBox1Items.IndexOf(FindString);
end;

end.
Ich habe keine Eigenschaft von TListbox gefunden, mit der sich dieses Vehalten beeinflussen läßt. Es würde mich doch mal interessieren, woran das liegen könnte.

Gruß LP

Michael II 16. Jun 2021 15:52

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Hallo Maekkelrajter

das ist mindestens in 10.4.2 (ich glaub schon viel länger) generell ein "Problem"* bei Listboxen mit vielen Einträgen (und hängt nicht mit dem Lösungsansatz von Uwe Raabe zusammen).

[* in "", weil man wohl eher selten derart viele Elemente in eine Listbox quetscht. Problem, weil: Wenn's angeboten wird sollte es funktionieren.]

Der Scrollbalken verhält sich nicht wie erwartet; springt nach dem nach unten Scrollen weit nach oben; dadurch wird dann auch nicht der Teil der Liste angezeigt, den man eigentlich hätte sehen wollen.

(Mit Delphi 10.4.2, VCL Win32 und Win64 unter Microsoft Windows [Version 10.0.19043.1055] und auch mit älteren 10.0.19043 getestet.)

Gruss
Michael

TurboMagic 16. Jun 2021 23:17

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Gibt's dazu schon einen QP Eintrag?
Falls nicht, kann jemand einen erstellen?
Ist halt auch die Frage woher der Scrollbar kommt.
Wenn direkt aus Win32, dann könnte der Bug
auch dort sein.

Michael II 18. Jun 2021 13:52

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Zitat:

Zitat von TurboMagic (Beitrag 1491162)
Gibt's dazu schon einen QP Eintrag?
Falls nicht, kann jemand einen erstellen?
Ist halt auch die Frage woher der Scrollbar kommt.
Wenn direkt aus Win32, dann könnte der Bug
auch dort sein.


Nicht QP..., eher im Feedback Hub von microsoft als Feature Request für Windows 12 posten.
Die MAXWORD Grenze beim Scrollen via Rollbalken ist eine Schranke von Windows; es läuft genau gleich "komisch", wenn C++ von m$ verwendet wird.
(ListBox1.TopIndex := 70000 hingegen funktioniert problemlos.)

himitsu 18. Jun 2021 19:00

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Joar, aber sei froh, dass es erst ab 65k Probleme gibt, denn eigentlich ist war der Index "signed" und 16 Bit, also bloß bis 32k :stupid:

MSDN-Library durchsuchenLB_SETTOPINDEX

Michael II 18. Jun 2021 21:53

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Zitat:

Zitat von himitsu (Beitrag 1491245)
Joar, aber sei froh, dass es erst ab 65k Probleme gibt, denn eigentlich ist war der Index "signed" und 16 Bit, also bloß bis 32k :stupid:

MSDN-Library durchsuchenLB_SETTOPINDEX


Ja, war bei früheren Win Versionen so - aber heute funktionieren LB_SETTOPINDEX und LB_GETTOPINDEX jenseits der 64K Grenze problemlos. Nur via Scrollbalken geht's nicht; aber egal... es gibt sicher immer andere Lösungen als 1 Mio Items in einer einzigen Box.

himitsu 18. Jun 2021 23:12

AW: Hilfeersuchen - schnelle Anzeige Textdatei in TListBox
 
Aber nur weil was 32 Bit hat, muß es nicht "immer" 32 Bit können, wenn es irgendwo irgendwie verwendet wird. :angle2:
z.B. MSDN-Library durchsuchenPBM_SETRANGE vs. MSDN-Library durchsuchenPBM_SETRANGE32

Und hier wird zwar jetzt LongInt genutzt, aber es kann dennoch sein, dass eine (veraltete / nie aktualisierte) Implementation nicht vielleicht dennoch weiterhin SmallInt/Word verwendet und dann dennoch weiterhin überschlägt. :freak:


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:39 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 by Thomas Breitkreuz