나는 하루 이틀 동안이 문제에 시달렸으며 아무 데나 대답을 찾을 수 없다. 나는 this answer might help라고 생각했지만 그렇지 않았다.익명 스레드 내에서 TFloatAnimation. 스레드가 죽지 않고 애니메이션이 다시 시작되지 않는다
아래 샘플 코드에는 두 개가 있습니다. Timage 구성 요소 각각에 "시작 이미지"가 들어 있습니다. 두 개의 익명 스레드가 만들어지고 "시작 버튼"을 클릭하면 이미지 1과 이미지 시작 사이에 Image1이 움직이고 다른 하나는 이미지 2에서 동일하게 작동합니다.
내 문제는 KillAnimation 부울 True로 설정하면 모두 애니메이션을 중지해야한다는 것입니다 (그들이하는)하지만 스레드 출구의 하나는, 다른 하나는 애니메이션을 중지하지만, 이미지 중간 애니메이션을 떠난다.
미리 정의 된 스레드를 사용하는 경우에도 동일한 문제가 발생합니다.
샘플 응용 프로그램에는 이미지가 두 개뿐입니다. 실제 응용 프로그램은 15에서 24 사이의 어느 곳에서나 사용할 수 있습니다. 익명 스레드는 만들 수 있고 최대 24 개의 TThread를 정의 할 필요가 없으므로 적합합니다. 나는 그것이 의미가 있기를 바랍니다.
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes,
System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Objects,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Ani, FMX.Effects,
FMX.Filter.Effects;
type
TForm1 = class(TForm)
Image1: TImage;
Image2: TImage;
BtnStop: TButton;
BtnStart: TButton;
BtnReset: TButton;
procedure BtnStopClick(Sender: TObject);
procedure BtnStartClick(Sender: TObject);
procedure BtnResetClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure createthread(TheImage: TImage; TargetBMP: String);
end;
var
Form1: TForm1;
KillAnimation: Boolean;
implementation
{$R *.fmx}
procedure TForm1.BtnStopClick(Sender: TObject);
begin
KillAnimation := true;
end;
procedure TForm1.createthread(TheImage: TImage; TargetBMP: String);
begin
{ The thread works right up until it is stopped. Even though two
threads are started only one finishes. In addition, the images
do not end up as the target image, and neither image can be
reset even if I reload them from files. }
TThread.CreateAnonymousThread(
procedure()
var
Wiggle: TWiggleTransitionEffect;
TheFloat: TFloatAnimation;
begin
TThread.NameThreadForDebugging('Animate ' + TheImage.Name);
Wiggle := TWiggleTransitionEffect.Create(Nil);
Wiggle.RandomSeed := 0.3;
Wiggle.Progress := 0;
Wiggle.Parent := TheImage;
TThread.Synchronize(TThread.CurrentThread,
procedure()
Begin
Wiggle.Target.LoadFromFile(TargetBMP)
end);
TheFloat := TFloatAnimation.Create(Nil);
TheFloat.Parent := Wiggle;
TheFloat.PropertyName := 'Progress';
TheFloat.Duration := 2;
TheFloat.AutoReverse := true;
TheFloat.Loop := true;
TheFloat.StartValue := 0;
TheFloat.StopValue := 100;
TheFloat.StartFromCurrent := false;
TheFloat.start;
while not KillAnimation do
application.handlemessage;
TheFloat.stop;
end).start;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Image1.Bitmap.LoadFromFile('c:\sample\startimage.png');
Image2.Bitmap.LoadFromFile('c:\sample\startimage.png');
end;
procedure TForm1.BtnStartClick(Sender: TObject);
begin
KillAnimation := false;
createthread(Image1, 'c:\sample\endimage.png');
createthread(Image2, 'c:\sample\endimage.png');
end;
procedure TForm1.BtnResetClick(Sender: TObject);
begin
KillAnimation := false;
Image1.Bitmap.LoadFromFile('c:\sample\startimage.png');
Image2.Bitmap.LoadFromFile('c:\sample\startimage.png');
end;
end.
나는 스레드 내에서 전환 및 FloatAnimation 만들기 FreeOnTerminate이 True이기 때문에 할 때이 파괴 될 것이라고 의미라고 생각했을 것이다.
"image1.bitmap.loadfromfile"을 사용하여 이미지를 재설정하려고 시도하면 변경되지 않습니다.
이미지는 170 x 170png 파일입니다.
내가 여기서 잘못 했습니까?
내 목표는 스레드에 TImage 및 이미지 파일을 전달하고 중지 할 때까지 움직 이도록하는 것입니다. 24 개의 이미지를 모두 애니메이션으로 만들 필요는 없지만 결코 알 수는 없습니다.
샘플에서 모든 코드를 게시해서는 안된다면 사과드립니다. 적어도 당신은 모든 일이 진행되고 있음을 볼 수 있습니다.
첫째, 권장되지 않는 GUI 컴포넌트에 직접 통화를 처리하는 스레드를 사용하여. 또한 스레드에서'Application.HandleMessage'를 호출하고 있는데 이것은 올바르지 않습니다. Wiggle과 TheFloat은 코드에 의해 완성되어야합니다. 나는이 모든 것을 메인 쓰레드에서 작동하도록 만들 것을 제안한다. –
@LURD 메인 UI 스레드 내에서 애니메이션을 시도했지만 버튼이 눌려 질 때까지 반복되는 애니메이션이 4 개 또는 5 개있을 때 버튼 등이 반응하지 않게되었습니다. Transitions 및 FloatAnimate를 비롯한 FMX 구성 요소가 스레드로부터 안전하다고 생각했습니다. 흥미롭게도 application.processMessages가 작동하지 않아 애니메이션이 재생되지 않습니다. 당신의 의견과 생각을 주셔서 감사합니다 :) – Craig
@LURD 나는 또한 2 개의 스레드가 시작되지만 1 개의 끝이라는 사실에 의아해합니다. 코드가 동일하기 때문에 조금 이상합니다. 두 애니메이션은 모두 멈추지 만 스레드는 바람에 매달려 있습니다. – Craig