Страница 1 из 1

Почему не меняется значение метки?

СообщениеДобавлено: 11.05.2012 19:30:07
Lifter
Проблема в Lazarus.
Код: Выделить всё
procedure TForm1.Label1Click(Sender: TObject);
var i: integer;
begin
  for i:=0 to 100 do
   begin
     Label1.Caption := 'Обработано '+IntToStr(i)+' из 100 ';
     Sleep(5);
   end;
end;

Пустая форма, на ней метка Label1. Хочу, чтобы надпись на ней перебирала все значения от 0 до 100.
Программа же задумывается на пару секунд, потом пишет "Обработано 100 из 100", то есть последнее значение.
Т.е. пока крутится в цикле, значение метки не обновляется.
Как сделать, чтоб обновлялось?

UPD
Добавил прогресбар. Он движется от 0 к 100, как надо. А значение метки так и не обновляется. Только через секунду-две после того, как прогрессбар дошел до 100, появляется надпись "Обработано 100 из 100".
Код: Выделить всё
procedure TForm1.Label1Click(Sender: TObject);
var i: integer;
begin
  for i:=0 to 200 do
   begin
     Label1.Caption := 'Обработано '+IntToStr(i)+' из 200 ';
     ProgressBar1.Position := i;
     Sleep(5);
   end;
end;

Re: Почему не меняется значение метки?

СообщениеДобавлено: 11.05.2012 19:36:54
Little_Roo
Таймер поможет ?

Re: Почему не меняется значение метки?

СообщениеДобавлено: 11.05.2012 19:38:31
Brainenjii
Application.ProcessMessage перед/вместо Sleep?

Re: Почему не меняется значение метки?

СообщениеДобавлено: 11.05.2012 19:40:00
Lifter
Но прогресбар то движется! Безо всяких таймеров. А текст метки не меняется. Может какое свойство у метки надо задать?

Добавлено спустя 4 минуты 21 секунду:
Во, Application.ProcessMessage помогло!!! Спасибо!

Добавлено спустя 5 минут 16 секунд:
Ну и чисто из любопытства, почему тогда двигался прогресбар, он вроде тоже не должен был бы обновляться?

Re: Почему не меняется значение метки?

СообщениеДобавлено: 12.05.2012 08:47:28
Light13
Progressbar после изменения позиции делает перерисовку.

ProcessMessage заставляет обработать очередь сообщений.

При этом можно закрыть окно - это тоже обработается.

Можете вызывать Label1.Repaint или перед началом цикла (имхо это правильнее) повесить флаг и проверять его в onCloseQuery формы - если работаем, то не закрываемся.

Обрабатывать очередь сообщений на каждую итерацию слишком дорого. Лучше проверяйте сколько тактов прошло и через 500-1000 вызывайте ProcessMessage.