Индикатор выполнения Delphi

Я пытаюсь сделать индикатор выполнения, который начинается с 0% и занимает 5 секунд, чтобы добраться до 100%. Индикатор выполнения начнет расти, как только будет нажата кнопка Button1. Любой совет? Я посмотрел в Google, но это не дало мне ничего хорошего в таких вещах.

Кроме того, при 0% должна быть метка с надписью Waiting..., при запуске индикатора выполнения он должен перейти к Working..., а когда это будет сделано, он должен сказать Done!.


person PuppyKevin    schedule 30.03.2009    source источник


Ответы (2)


Использование GetTickCount() и инициализация переменных:

uses Windows;

var mseconds, starttime: integer;


procedore TForm1.FormCreate()
begin
  starttime := GetTickCount();
  mseconds := 0;
  Timer1.Enabled := false;
  Label1.Caption := '';
  ProgressBar1.Position := 0;
  Label1.Caption := 'Waiting...';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin  
  ProgressBar1.Min := 0;
  ProgressBar.Max := 100;
  ProgressBar1.Position := 0;
  timer1.Enabled := True;
  Label1.Caption := 'Working...';  
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin  
  mseconds := GetTickCount() - starttime;
  if mseconds < 5000 then
    ProgressBar1.Position := Trunc(mseconds / 50)
  else begin
    ProgressBar1.Position := 100;
    Label1.Caption := 'Done!';
    Timer1.Enabled := false;
  end;
end;
person eKek0    schedule 30.03.2009
comment
В порядке. У вас было несколько ошибок, но я могу их исправить. Однако по какой-то причине, когда я нажимаю кнопку, метка меняется на «Работает...», но после этого ничего не происходит. Однако я посмотрел, не было ли чего-то не так, могло ли это быть вызвано: starttime := GetTickCount(); (читайте следующий комментарий) - person PuppyKevin; 30.03.2009
comment
и миллисекунды := время начала - GetTickCount();? - person PuppyKevin; 30.03.2009
comment
@PuppyKevin: Вы на правильном пути; если вы не видите ошибки, используйте отладчик, и вы ее найдете. Кроме того, Timer1 не отключается после завершения... - person mghie; 31.03.2009

Вы можете использовать таймер с интервалом 50 и сначала установить для него значение false.

procedure TForm1.Button1Click(Sender: TObject);
begin
  timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
const
  cnt: integer = 1;
begin
  ProgressBar1.Position := cnt;
  if cnt = 1 then Label1.Caption := 'Waiting...'
  else if cnt = 100 then begin
    Label1.Caption := 'Done!';
    Timer1.Enabled := False;
  end else
    Label1.Caption := 'Working...';
  Inc(cnt);
end;
person SimaWB    schedule 30.03.2009
comment
Одна проблема с использованием таймеров заключается в том, что нет гарантии, что это займет 5 секунд (кстати, 2,5 в вашем примере). В большинстве случаев это будет очень близкий матч. В стрессовой ситуации это может быть несколько секунд. - person Lieven Keersmaekers; 30.03.2009
comment
@Lieven: Вы правы, но влияние этого можно свести к минимуму с помощью менее тупого алгоритма: не считать тики таймера, а вычислять время, прошедшее с момента запуска в обработчике событий. Для более высокого приоритета сообщения вместо этого отправляйте WM_USER каждые 100 мс из фонового потока. - person mghie; 30.03.2009
comment
Ага. Это не идеальное решение, но основная идея верна - person Mason Wheeler; 30.03.2009
comment
Хорошо, я попробовал ваш код и столкнулся с несколькими проблемами. В моей форме есть TButton, TProgressBar, TTimer и TLabel. Я копирую и вставляю код, но он говорит, что таймер не содержит элемент «Включен». То же самое касается Tprogressbar.Position и Label1.Caption. Что я мог упустить? - person PuppyKevin; 30.03.2009
comment
Какую версию Delphi вы используете? - person SimaWB; 30.03.2009
comment
Мое приложение Turbo Delphi сообщает мне, что оно использует версию 10 Delphi. - person PuppyKevin; 30.03.2009
comment
Я не уверен, почему у вас есть ошибка. Но в сообщении об ошибке у вас есть Timer. Что такое Таймер? У вас есть Timer1: TTimer; в вашем классе формы. А также проверьте метку, индикатор выполнения и названия форм. - person SimaWB; 30.03.2009
comment
В классе формы у меня есть ProgressBar1: TProgressBar;, Button1: TButton;, Timer1: TTimer;, Label1: TLabel;. В TProgressBar, TButton, TTimer и TLabel также есть ошибка, говорящая о необъявленном идентификаторе «‹вставьте один из четырех›». - person PuppyKevin; 30.03.2009
comment
Вам также нужно будет добавить директиву {$J+}, чтобы разрешить const cnt: integer = 1; быть изменены. Для этого лучше использовать поле объекта (FCnt : integer). Также необходимо установить FCnt обратно на 1 до или после каждого запуска. - person Gerry Coll; 01.04.2009