Jak właściwie korzystać z ProgressBar?

0

Wiem jak w prosty sposób używać ProgressBar, ale działa on tak, że w kodzie podaję jak szybko ma się poruszać pasek. A mnie zastanawia jak z niego skorzystać w taki sposób, że pokazuje fatyczny stan danej operacji np. mamy bardzo długi tekst, w którym należy zamienić wszystkie litery b oraz c na a.

0

Należy ustawić odpowiednią własności Min oraz Max, a później zwiększać w odpowiednim momencie własnośc Position. To co podałeś jako przykład chęci użycia TProgressBar jest nietrafione. Ponieważ to podobnie jak z wyrażeniami regularnymi i sparsowaniem wszystkich wystąpień w jakimś tekstcie. Po prostu nie jesteśmy w stanie z góry określić wartości dla własności Max. ProgressBara jeżeli nie ma być użyty on jako niby animowany pasek postępu nieokreśłonego, tylko żeby pokazać, że coś się dzieje, należało by zaprogramować jak pasek przy uruchamianiu na przykład Windows. Pomyśl logicznie. Jeżeli chciałbyś zliczyć Max i pokazać postęp zmian liter w tekstcie to było by to bardzo nieoptymalne, bo najpierw musiał byś dokonać zliczenia ilości zamian, a późnej dokonać zamiany. Spowoduje to, że operacja będzie trwała dwa razy dłużej. Przy takiej operacji nie polecam paska postępu. Co innego postęp pobierania pliku na przykład po HTTP albo kopiowania go własnym kodem. Tutaj w obu przypadkach, da się łatwo okreśłić Max i pokazać postęp. Przykład dla Synapse i HTTP w moim artykule na: Obsługa protokołu HTTP przy użyciu pakietu Synapse - poczytaj.

0
ProgressBar.min := 1
ProgressBar.Max := length(BardzoDlugiTekst);
for i := 1 to length(BardzoDlugiTekst);
begin
  if BardzoDlugiText[i] in ['b','c'] then
    ZmienionyBardzoDlugiTekst := ZmienionyBardzoDlugiTekst + 'a'
  else
    ZmienionyBardzoDlugiTekst := ZmienionyBardzoDlugiTekst + BardzoDlugiText[i];
  ProgressBar.Position := ProgressBar.Position + 1;
end; 

Baaaardzo uproszczona wersja.

0

Nie wiem z czym masz problem. Ustawiasz min na 0, maks na 100 i operujesz na procentach.
Ja głównie używam progressbarów w pętlach.

 
for i:=low(tab) to high(tab) do
begin
  progress:=Round((i/high(tab))*100);
  progressBar.Position:=progress;
  Application.ProcessMessages;
//operacje
end;
0

@babubabu - jesteś kolejnym, który nie znalazł odpowiedniej metody do inkrementowania pozycji ProgressBar :]

Zamiast ręcznej inkrementacji:

ProgressBar.Position := ProgressBar.Position + 1;

należy wykorzystać metodę StepIt:

ProgressBar.StepIt();

tylko należy pamiętać, że pozycja zwiększy się o taką wartość, jaka ustawiona jest we właściwości Step; Po to właśnie jest ta metoda, żeby ustawić skok w jednym miejscu (czyli np. w Object Inspector) i po zmianie wartości skoku nie szukać wszystkich odwołań w kodzie i nie zmieniać ich ręcznie;


@Gekas - kontrolkę tego typu można wykorzystać jeśli się wie jaka będzie wartość maksymalna; Jeśli nie można jej określić, to pasek postępu można wykorzystać jako animację oczekiwania na ukończenie operacji; Na pewno widziałeś nie raz taki ProgressBar, w którym automatycznie przewija się kilka kresek; W Delphi 7 niestety nie można ustawić animacji dla paska postępu (przynajmniej nie ma takiej właściwości), jednak w nowszych środowiskach zapewne jest taka możliwość;

Lazarus takowy posiada - jest w nim właściwość Style - standardowo jest ustawiona na pbstNormal i służy do przedstawienia zwykłego postępu przez ręczne inkrementowanie pozycji, natomiast ustawiając dla tej właściwości wartość pbstMarquee pasek zamieni się w animację; Jeśli wybierze się animowany pasek to trzeba zwrócić uwagę na to, że przy małej szerokości animacja wygląda źle, bo zbyt szybko się przewija i efekt jest beznadziejny, a szybkości animacji nie można ustawić we właściwościach; Tak że sens wykorzystania animowanego paska postępu jest wtedy, gdy jego szerokość będzie miała co najmniej 250 pikseli;

Więc jeśli chcesz wykorzystać zwykły pasek postępu do Twojego algorytmu, to zrób tak jak napisał @babubabu - Max dla paska to długość łańcucha, a inkrementacji dokonuj po każdym znaku bez względu na to, co na nich wykonujesz.

2

Wolę takie rozwiązanie:

ProgressBar.min := 0;
ProgressBar.Max := Size;
ProgressBar.Step := Size div 100;
for i := 1 to Size
begin
  ...
  if ProgressBar.Position<i then ProgressBar.StepIt;
end;

lub takie:

ProgressBar.min := 0;
ProgressBar.Max := 100;
Prc:=0;
for i := 1 to Size
begin
  ...
  
  Prc:=Prc+100;
  if Prc>=Size then
  begin
    Prc:=Prc-Size;
    ProgressBar.StepIt;
  end;
end;

Przewaga nad rozwiązaniem podanym przez @babubabu: znacznie mniej przerysowań ProgressBar'a przy dużych Size.
Drugie jest dokładniejsze ale wymaga dodatkowej zmiennej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1