Я боролся с этим в течение дня или двух и нигде не могу найти ответ. Я думал, что этот ответ может помочь, но это не помогло.
В приведенном ниже примере кода у меня есть два компонента Timage, каждый из которых содержит «начальное изображение». При нажатии кнопки «Пуск» создаются два анонимных потока: один анимирует изображение Image1 между начальным изображением и конечным изображением, а другой делает то же самое для Image2.
Моя проблема заключается в том, что когда для логического значения KillAnimation установлено значение True, обе анимации должны останавливаться (что они и делают), но только один из потоков завершается, другой прекращает анимацию, но оставляет изображение в середине анимации.
У меня такая же проблема, если я использую предопределенный поток.
Образец приложения имеет только два изображения, реальное приложение может иметь от 15 до 24. Анонимные потоки, кажется, подходят, потому что я могу их создать, и мне не нужно беспокоиться об определении до 24 TThreads. Я надеюсь, что в этом есть смысл.
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.
Я бы подумал, что создание Transition и FloatAnimation в потоке означает, что они будут уничтожены, когда будут выполнены, потому что FreeOnTerminate имеет значение True.
Когда я пытаюсь сбросить изображения с помощью «image1.bitmap.loadfromfile», это не меняется.
Изображения представляют собой файлы png размером 170 x 170.
Что я здесь сделал не так?
Моя цель - передать TImage и файл изображения в поток, позволить ему анимироваться, пока не будет остановлено. Маловероятно, что мне понадобятся все 24 изображения для анимации, но кто знает.
Извините, если я не должен был публиковать весь код из моего примера. По крайней мере, вы можете видеть все, что происходит.
Application.HandleMessage
из потока, что неверно.Wiggle
иTheFloat
должны быть завершены кодом. Я предлагаю вам вместо этого попытаться заставить все это работать в основном потоке. - person LU RD   schedule 06.11.2017handlemessage
и не возвращается. Я на самом деле удивлен, что любой из ваших потоков вообще вышел. Действительно ли это действительно для FMX, это ваша домашняя работа, чтобы узнать! ;) - person Ken Bourassa   schedule 06.11.2017