Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi ProgressBar bei LoadFromFile in TListBox (https://www.delphipraxis.net/110028-progressbar-bei-loadfromfile-tlistbox.html)

bodenheim 11. Mär 2008 22:09


ProgressBar bei LoadFromFile in TListBox
 
Hallo,
ich lade aus einer Textdatei Daten in eine TListBox.
Also nach Auswahl der Datei in einem Open Dialog

ListBox1.Items.LoadFromFile(FileName);

Funktioniert auch, aber da die txt über 1 MB groß ist, hängt er herum, bis alle Zeilen geladen sind.
Deshalb möchte ich den Ladevorgang in einer ProgressBar darstellen.

Wie machen?? Komme nicht dahinter..
Danke !


PS also Irgendwie mit Count, wenn eine neue Zeile drin ist..komme gerade nicht ganz dahinter

bodenheim 11. Mär 2008 23:06

Re: ProgressBar bei LoadFromFile in TListBox
 
Hi,
habe jetzt eine Funktion ZeilenZählen geschrieben, welche vorher die Zeilen der txt liest, also die Items

ProgressBar1.max:=ZeilenZählen(FileName);
ProgressBar1.position:=0;

ListBox1.Items.LoadFromFile(FileName);

ProgressBar1.position:=ListBox1.Items.count;

Jetzt springt er aber erst am Ende! auf 100, dazwischen während des Ladens tut sich weiter nichts
an der Progress Bar..müsste doch gehen
:wall:

calculon 11. Mär 2008 23:44

Re: ProgressBar bei LoadFromFile in TListBox
 
Hi bodenheim,

ListBox1.Items.count gibt die dir die Anzahl der Listboxeinträge zurück und ist kein "Zaehler". Überhaupt ist deine Datei, wenn dein Code bei ProgressBar1.position:=ListBox1.Items.count; ankommt bereits geladen. Die einzige Möglichkeit, die ich wüsste, ist das über AssignFile zu machen:

ungetestet:
Delphi-Quellcode:
var
  myFile : TextFile;
  text  : string;
  FileName: string;
  max, i: integer;
begin
  Filename := // dei Datei halt
  max := ZeilenZählen(FileName);
  AssignFile(myFile, FileName);
  Reset(myFile);
  progressbar1.position := 0;
  ProgressBar1.max := 100;
  i := 0;
    while not Eof(myFile) do
      begin
        ReadLn(myFile, text);
        listbox1.items.add(test);
        progressbar1.position := round((i/max) * 100);
        inc(i);
      end;
  CloseFile(myFile);
end;
alternativ: BeginUpdate und EndUpdate => Listbox wird viel schneller fertig als mit ohne ;-)

Gruß

Calculon
--

bodenheim 12. Mär 2008 00:26

Re: ProgressBar bei LoadFromFile in TListBox
 
Hallo,
ja, mit assign und readln statt loadfromfile bewegt sich die ProgressBar jetzt;
kam auch nur darauf, weil es hier stand.

http://entwickler-forum.de/showthread.php?t=4763

Danke.
Allerdings stimmt jetzt die Berechnung noch nicht..
ProgressBar endet zu spät.
Mal schaun..

bodenheim 12. Mär 2008 01:12

Re: ProgressBar bei LoadFromFile in TListBox
 
year, Problem gelöst :-D

also die Lösung besteht natürlich darin, dass man vorher auslesen muss, wieviele Zeilen die TXT hat.

Delphi-Quellcode:
function CountLines(const sFile: String): Integer;
var fInput: TextFile;
begin
  Result := 0;
  AssignFile(fInput, sFile);
  try
    ReSet(fInput);
    try
      while not EOF(fInput) do
      begin
        ReadLn(fInput);
        Inc(Result);
      end;
    finally
      CloseFile(fInput);
    end;
  except
   end;
end;

Dann setzt man diese Zeilen als Max der ProgressBar,
und mit jeder eingelesenen Zeile inc.

Auszug:

Delphi-Quellcode:
Begin
  OpenDialog1.Execute;
  FileName1 := OpenDialog1.Filename;
  f:=countlines(Filename1);
  AssignFile(myFile,Filename1);
  Reset(myFile);
 
  progressbar1.position := 0;
  i:= 0;
  ProgressBar1.max:=f;
    while not Eof(myFile) do
      begin
        ReadLn(myFile, sRecord);
        listbox1.items.add(sRecord);
        inc(i);
        progressbar1.position:=i;
      end;
CloseFile(myFile);

Klaus01 12. Mär 2008 02:00

Re: ProgressBar bei LoadFromFile in TListBox
 
Guten Morgen,

wenn Du es so löst, dann brauchst Du die Datei
nur einmal lesen.

Delphi-Quellcode:
Begin
  OpenDialog1.Execute;
  FileName1 := OpenDialog1.Filename;
  f:=FileSize(Filename1);
  AssignFile(myFile,Filename1);
  Reset(myFile);
 
  progressbar1.position := 0;
 
  ProgressBar1.max:=f;
  listbox1.items.BeginUpdate;
  while not Eof(myFile) do
    begin
      ReadLn(myFile, sRecord);
      listbox1.items.add(sRecord);
      progressbar1.position:=progressbar1.position+length(sRecord)+2;
    end;
  listbox1.items.EndUpdate;
  CloseFile(myFile);
[edit] noch zum sRecord 2 hinzugezählt, wegen CR und LF

Grüße
Klaus

Hansa 12. Mär 2008 02:20

Re: ProgressBar bei LoadFromFile in TListBox
 
Sauerei ! :warn: Da sucht man zu der Uhrzeit noch Textdatei wo das eventuell Sinn macht (> 10 MB) und dann findet der Kerl das selber. :mrgreen:

Delphi-Quellcode:
procedure TForm1.FormActivate(Sender: TObject);
var t : TextFile;
    zeile : string;
    i,
    ZeilenAnzahl : integer;
begin
  i := 0;
  ZeilenAnzahl := 0;
  AssignFile (t,Dateiname);
  reset (t);
  while not Eof (t) do begin
    ZeilenAnzahl := ZeilenAnzahl + 1;
    readln (t);
  end;
  CloseFile (t);
  Reset (t);
  gauge1.MaxValue := ZeilenAnzahl;
  readln (t,zeile);
  while not EOF (t) do begin
    i := i + 1;
    gauge1.Progress := i;
    Listbox1.Items.Add(IntToStr (i));
//    Application.ProcessMessages;
    readln (t,zeile);
  end;
  CloseFile (t);
end;
Allerdings würde ich die Try/Except-Orgie wenn schon, dann auch überall durchführen. :zwinker: Und (wie zu sehen) eine Gauge benutzen, statt der ProgressBar.

Allerdings auch noch eine Frage : geht das nur mit Processmessages, dass man auch während des Füll-Laufes sieht, wie die Listbox sich füllt ?

Jetzt noch roter Kasten ? :shock: Ne, geht nicht, weil keine feste Recordlänge verwendbar.

Dateiinhalt :

1

ergibt 3 Byte und nicht 1.

Dateiinhalt :

1
234

ergibt 8 Byte und nicht 2.

bodenheim 12. Mär 2008 10:08

Re: ProgressBar bei LoadFromFile in TListBox
 
gelöscht, da missverständlich.

Luckie 12. Mär 2008 10:17

Re: ProgressBar bei LoadFromFile in TListBox
 
Zitat:

Zitat von bodenheim
stimmt, Gauge ist besser.
Um dem OpenDialog noch vorher Zeit zu geben zu schliessen,
habe ich noch einen delay eingebaut;

Hä? Warum denn das?

OregonGhost 12. Mär 2008 10:48

Re: ProgressBar bei LoadFromFile in TListBox
 
Kleiner Tipp: Wenn so wenig zu laden ist, dass es eine "praktikable" (hust) Lösung darstellt, erst die Datei einzulesen und ihre Zeilen zu zählen und sie dann noch einmal einzulesen, und ein Delay einzubauen, damit man mehr vom Fortschritt sieht... Dann braucht man keine Fortschrittsanzeige. Auch das Einlesen von 10 MB sollte nicht länger als zwei Sekunden dauern, selbst wenn sie von einem langsamen Medium kommt. 500ms Delay nur um eine ProgressBar zu sehen, die sofort voll ist... ähm... nein. Hast du dich über solche Dinge in fremden Programmen noch nie geärgert? Miss einmal die Zeit, die das Laden ohne Progressbar und Delay dauert, und dann die Zeit mit.

bodenheim 12. Mär 2008 11:22

Re: ProgressBar bei LoadFromFile in TListBox
 
Zitat:

Zitat von OregonGhost
Auch das Einlesen von 10 MB sollte nicht länger als zwei Sekunden dauern,

??

ich weiss worauf ihr hinaus wollt, Problem ist so,

die Dateien sind 5-6 MB groß und wenn ich lade, hängt der Rest vom Open Dialog bis alles geladen ist.
Nutzer könnte auf die Idee kommen, das Programm sei abgestürzt.
Das dauert über 10 Sek. um die Text-Datei in die StringListBox zu laden, habe einen normalen Rechner. (??)
Also würde das nicht so lang dauern, würde ich auch keine gauge einbauen.

Edit: Habe nochmal nachgemessen, das Laden von 6 MB txt über
Delphi-Quellcode:
while not Eof(myFile) do
      begin
        ReadLn(myFile, sRecord);
        listbox1.items.add(sRecord);
        inc(i);
        gauge1.Progress := i;
      end;
dauert an dem Rechner über 15 Sek. Mit gauge oder ohne.
Mit Readln oder ReadfromFile, egal..

Danach werden die Daten dann noch in eine StringGrid geparsed..
_____________________________________

Zitat:

Zitat von OregonGhost
Delay einzubauen, damit man mehr vom Fortschritt sieht

nicht deshalb sondern weil der "Open-Dialog" sonst "hängt".

RavenIV 12. Mär 2008 11:40

Re: ProgressBar bei LoadFromFile in TListBox
 
Zitat:

Zitat von bodenheim
Zitat:

Zitat von OregonGhost
Delay einzubauen, damit man mehr vom Fortschritt sieht

nicht deshalb sondern weil der "Open-Dialog" sonst "hängt".

versuch es mal so:
Delphi-Quellcode:
if OpenDialog.Execute(...) then
begin
  // hier alles, was nach dem OpenDialog passieren soll
end;
Das OpenDialog.Execute kommt erst zurück, wenn der OpenDialog geschlossen wird.
Der Rückgabe wert ist True, wenn OK gedrückt wird. Sonst ist er False.

bodenheim 12. Mär 2008 11:43

Re: ProgressBar bei LoadFromFile in TListBox
 
..das mit dem Delay war nonsense, stimmt..
thx.

RavenIV 12. Mär 2008 11:52

Re: ProgressBar bei LoadFromFile in TListBox
 
Zitat:

Zitat von bodenheim
..das mit dem Delay war nonsense, stimmt..
thx.

Sehr gut erkannt.
Warum soll man künstlich eine Pause einbauen, wenn eh schon alles richtig läuft.
Hat ein ehemaliger Arbeitskollege von mir immer gesagt: "Kaum macht man es richtig, funktioniert es auch."

Ausserdem sind 500 ms eine Ewigkeit für einen Prozessor. Da langweilt er sich ja 495 ms lang.
Was macht er dann? Er überlegt sich so manchen Schabernack. Daher kommt es, dass die PCs sich immer so "komisch" verhalten.

OregonGhost 12. Mär 2008 11:59

Re: ProgressBar bei LoadFromFile in TListBox
 
Zitat:

Zitat von bodenheim
Edit: Habe nochmal nachgemessen, das Laden von 6 MB txt über
Delphi-Quellcode:
while not Eof(myFile) do
      begin
        ReadLn(myFile, sRecord);
        listbox1.items.add(sRecord);
        inc(i);
        gauge1.Progress := i;
      end;
dauert an dem Rechner über 15 Sek. Mit gauge oder ohne.
Mit Readln oder ReadfromFile, egal..

Auch wenn du Gauge und Listbox weglässt? Das Laden einer Textdatei darf eigentlich nicht so lange dauern. Das Füllen in die Listbox hingegen kann schonmal etwas dauern, wenn du die Daten "echt" einfüllst. Da ist ein virtuelles Control wie VirtualTreeView oder wie das heißt sicherlich besser.

DeddyH 12. Mär 2008 12:05

Re: ProgressBar bei LoadFromFile in TListBox
 
Oder einfach mal BeginUpdate und EndUpdate benutzen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:20 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