Перейти к содержанию
  • Регистрация
  • 0
osvirt

Компилятор игнорирует программное изменение свойств компонентов

Вопрос

Доброе время суток.

Проблема в следующем:

Создаю пустое FM-приложение.

Кидаю кнопку и любой прямоугольный компонент(проверял на TLayout, на котором лежал TRectangle, и на TPanel).

У "прямоугольника" Visible установлено в False.

На событие кнопки OnClick вешаю обработчик:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Panel1.Visible:=true;  //TLayout.Visible:=true;
  sleep(2000);
  Panel1.Visible:=false; //TLayout.Visible:=false;
end;

Запускаю...

Происходит следующее:

По клику выполняется sleep, и только после этого быстро-быстро видимость включается/отключается. При этом, пока действует sleep, кнопка остаётся нажатой.

Получается, что часть функций выполняются как-будто по OnMouseDown, а часть по OnMouseUp.

 

В VCL приложении всё в порядке: видимость включается, программа ждёт 2 секунды, видимость отключается.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Рекомендуемые сообщения

  • 0

Слипом вы подвешиваете главный поток, поэтому кнопка остаётся нажатой. Почему не происходит прорисовка, я точно сказать не могу, но скорее всего связано с подвешенным главным потоком.

 

Чтобы ваш код заработал, можно, например, использовать "Application.ProcessMessages" (кнопка будет нажата):

procedure TForm1.Button1Click(Sender: TObject);
begin
  Panel1.Visible := True;
  Application.ProcessMessages;

  Sleep(3000);

  Panel1.Visible := False;
  Application.ProcessMessages;
end;

Или воспользоваться потоками (кнопка будет в обычном состоянии):

procedure TForm1.Button1Click(Sender: TObject);
begin

  TThread.CreateAnonymousThread(
  procedure
  begin

    TThread.Synchronize(nil,
    procedure
    begin
      Panel1.Visible := True;
    end);

    TThread.Sleep(3000);

    TThread.Synchronize(nil,
    procedure
    begin
      Panel1.Visible := False;
    end);

  end
  ).Start;

end;

Можно написать вот так (без синхронизации тоже работает, это у меня уже в привычку вошло, работу с визуальными компонентами в синхронизацию запихивать): Используйте вариант описанный выше.

procedure TForm1.Button1Click(Sender: TObject);

begin

  TThread.CreateAnonymousThread(

  procedure

  begin

    Panel1.Visible := True;

    TThread.Sleep(3000);

    Panel1.Visible := False;

  end

  ).Start;

 

end;

 

 

Возможно, есть более лучшее решение...

Изменено пользователем Andrey Yefimov
Убрал плохой вариант...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

 

 

Слипом вы подвешиваете главный поток, поэтому кнопка остаётся нажатой. Почему не происходит прорисовка, я точно сказать не могу, но скорее всего связано с подвешенным главным потоком.

На сколько я помню, События OnClick происходят после нажатия и последующего отпускания кнопки мыши на одном и том же контроле... Но никак не после нажатия, не взирая на то, что событие "Click" по сути ещё не произошло. Странно, в-общем.

 

 

 

Сделал так - покрасивше вроде. Спасибо!

Можно написать вот так (без синхронизации тоже работает, это у меня уже в привычку вошло, работу с визуальными компонентами в синхронизацию запихивать):

procedure TForm1.Button1Click(Sender: TObject);
begin

  TThread.CreateAnonymousThread(
  procedure
  begin

    Panel1.Visible := True;

    TThread.Sleep(3000);

    Panel1.Visible := False;

  end
  ).Start;

end;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

работаем с gui не из основного потока ? ну-ну... продолжайте в таком духе...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

работаем с gui не из основного потока ? ну-ну... продолжайте в таком духе...

 

Ну, в данном конкретном случае (исходя из описанной задачи) можно и без синхронизации, а вообще конечно все действия с GUI очень желательно проводить через синхронизацию (т.е. в основном потоке). Я как бы рассчитывал, что человек сам заглянет в справку и разберёт код. Возможно, вы правы и не нужно было выкладывать такой вариант...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

В реальной программе решение, выбранное первоначально, начало ругаться на неизвестные имена процедур.

 

Почитал про "Application.ProcessMessages" и воспользовался им - всё встало на свои места.

 

Еще раз спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...