gpt4 book ai didi

delphi - 关于在Delphi中设置动画的指针的棘手事情

转载 作者:行者123 更新时间:2023-12-03 19:32:07 25 4
gpt4 key购买 nike

所以,我什至不知道如何写正确的标题。

我想做的是让进度条动画。

可以讨论如何使用计时器和循环等。

但是,我希望能够执行以下操作:


ProgressBar1.Position:= Animate(ToValue);
要么
Animate(ProgressBar1.Position,ToValue);


这可能吗?

创建从整数继承的组件无效。

我使用指针尝试了2号,并进行了此过程

procedure TForm1.Animate(ToValue: integer;  var Dest: Integer);
begin
Dest:=ToValue;
end;


它确实在进度条内部更改了位置值,
但是进度栏在外观上没有变化。

如果有人对如何执行此操作有任何想法,那就太好了。

谢谢!

最佳答案

如果您有相对较新的Delphi版本,
这是使用TTimer围绕anonymous methods的动画包装。

type
Animate = class
private
class var fTimer : TTimer;
class var fStartValue : Integer;
class var fEndValue : Integer;
class var fProc : TProc<Integer>;
class Constructor Create;
class Destructor Destroy;
class procedure OnTimer(Sender : TObject);
public
class procedure Run( aProc : TProc<Integer>;
fromValue, ToValue, AnimationDelay : Integer);
end;

class constructor Animate.Create;
begin
fTimer := TTimer.Create(nil);
fTimer.Enabled := false;
fTimer.OnTimer := Animate.OnTimer;
end;

class destructor Animate.Destroy;
begin
fTimer.Free;
end;

class procedure Animate.OnTimer(Sender: TObject);
begin
if Assigned(fProc) then
begin
if (fStartValue <= fEndValue) then
begin
fProc(fStartValue);
Inc(fStartValue);
end
else
fTimer.Enabled := false;
end;
end;

class procedure Animate.Run( aProc: TProc<Integer>;
fromValue, ToValue, AnimationDelay: Integer);
begin
fTimer.Interval := AnimationDelay;
fStartValue := fromValue;
fEndValue := ToValue;
fProc := aProc;
fTimer.Enabled := (fStartValue <= fEndValue);
end;


Animate类是在应用程序启动/停止时进行自初始化和自破坏的类。
只能激活一个动画过程。

使用这种方式:

Animate.Run(
procedure( aValue : Integer)
begin
ProgressBar1.Position := aValue;
ProgressBar1.Update;
end,
1,100,5
);




如注释中所述,以上代码使用类变量和类函数。缺点是只能激活一个动画。

这是一个更完整的动画类,您可以在其中实例化任意数量的动画。扩展的功能,可以停止/继续进行,在准备就绪时添加事件,还有更多属性。

unit AnimatePlatform;

interface

uses
System.Classes,System.SysUtils,Vcl.ExtCtrls;

type
TAnimate = class
private
fTimer : TTimer;
fLoopIx : Integer;
fEndIx : Integer;
fProc : TProc<Integer>;
fOnReady : TProc<TObject>;
procedure OnTimer(Sender : TObject);
function GetRunning : boolean;
procedure SetReady;
public
Constructor Create;
Destructor Destroy; override;
procedure Run( aProc : TProc<Integer>;
FromValue,ToValue,AnimationDelay : Integer); overload;
procedure Run( aProc : TProc<Integer>;
FromValue,ToValue,AnimationDelay : Integer;
AReadyEvent : TNotifyEvent); overload;
procedure Run( aProc : TProc<Integer>;
FromValue,ToValue,AnimationDelay : Integer;
AReadyEvent: TProc<TObject>); overload;
procedure Stop;
procedure Proceed;
property ActualLoopIx : Integer read fLoopIx write fLoopIx;
property Running : boolean read GetRunning;
property OnReady : TProc<TObject> read fOnReady write fOnReady;
end;

implementation

constructor TAnimate.Create;
begin
Inherited;
fTimer := TTimer.Create(nil);
fTimer.Enabled := false;
fTimer.OnTimer := Self.OnTimer;
fOnReady := nil;
end;

destructor TAnimate.Destroy;
begin
fTimer.Free;
Inherited;
end;

function TAnimate.GetRunning: boolean;
begin
Result := fTimer.Enabled;
end;

procedure TAnimate.OnTimer(Sender: TObject);
begin
if Assigned(fProc) then
begin
if (fLoopIx <= fEndIx) then
begin
fProc(fLoopIx);
Inc(fLoopIx);
end;
if (fLoopIx > fEndIx) then
SetReady;
end
else SetReady;
end;

procedure TAnimate.Proceed;
begin
fTimer.Enabled := true;
end;

procedure TAnimate.Run(aProc: TProc<Integer>; FromValue, ToValue,
AnimationDelay: Integer; AReadyEvent: TNotifyEvent);
begin
Run(aProc,FromValue,ToValue,AnimationDelay);
fOnReady := AReadyEvent;
end;

procedure TAnimate.Run(aProc: TProc<Integer>; FromValue, ToValue,
AnimationDelay: Integer; AReadyEvent: TProc<TObject>);
begin
Run(aProc,FromValue,ToValue,AnimationDelay);
fOnReady := AReadyEvent;
end;

procedure TAnimate.Run(aProc: TProc<Integer>; fromValue, ToValue,
AnimationDelay: Integer);
begin
fTimer.Interval := AnimationDelay;
fLoopIx := fromValue;
fEndIx := ToValue;
fProc := aProc;
fTimer.Enabled := true;
end;

procedure TAnimate.SetReady;
begin
Stop;
if Assigned(fOnReady) then
fOnReady(Self);
end;

procedure TAnimate.Stop;
begin
fTimer.Enabled := false;
end;

end.




更新:

以下是使用 TTimer的版本,而不是基于 anonymous thread的动画师:

uses
SyncObjs;

procedure AnimatedThread( aProc: TProc<Integer>;
FromValue, ToValue, AnimationDelay: Integer;
AReadyEvent: TNotifyEvent);
begin
TThread.CreateAnonymousThread(
procedure
var
i: Integer;
w : TSimpleEvent;
begin
w := TSimpleEvent.Create(Nil,False,False,'');
try
for i := FromValue to ToValue do begin
TThread.Synchronize(nil,
procedure
begin
aProc(i);
end
);
w.WaitFor(AnimationDelay);
end;
finally
w.Free;
end;
if Assigned(AReadyEvent) then
TThread.Synchronize(nil,
procedure
begin
AReadyEvent(Nil);
end
);
end
).Start;
end;

// Example call

AnimateThread(
procedure(aValue: Integer)
begin
ProgressBar1.Position := aValue;
ProgressBar1.Update;
end,
1,100,5,nil
);

关于delphi - 关于在Delphi中设置动画的指针的棘手事情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15320370/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com