delphi 是否有办法在环路中切换组件?

r1zk6ea1  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(108)

我正在尝试使用for循环动画化一个包含7个图片的下拉菜单,在for循环中的代码每次迭代后,使用不同的组件进行更改。例如,第一次运行循环时:使用imgCourses7.Top,但第二次运行循环时(当I = 1时),则应使用imgCourses6.Top

iCoursesCount := 7;
iTotalLength := (6+41)*iCoursesCount;
imgCourses7.Top := 6;
imgCourses6.Top := 6;
imgCourses5.Top := 6;
imgCourses4.Top := 6;
imgCourses3.Top := 6;
imgCourses2.Top := 6;
imgCourses1.Top := 6;
for I := 0 to iCoursesCount -1 do
begin
  while not(imgCourses7.Top = iTotalLength - 41*(I+1)) do
  begin
    imgCourses8.Top :=  imgCourses8.Top + 6;
    sleep(8);
    application.ProcessMessages;
    if imgCourses7.Top >= iTotalLength - 41*(I+1) then
    begin
      imgCourses7.Top := iTotalLength - 41*(I+1);
      break;
    end;
  end;
end;
z9smfwbn

z9smfwbn1#

就像@AndreasRejbrand在评论中说的那样,可以使用数组,例如:

var
  Images: array[0..6] of TImage;
  TargetTop: Integer;
  ...

...

Images[0] := imgCourses7;
Images[1] := imgCourses6;
Images[2] := imgCourses5;
Images[3] := imgCourses4;
Images[4] := imgCourses3;
Images[5] := imgCourses2;
Images[6] := imgCourses1;

iCoursesCount := Length(Images);
TargetTop := 6+(41*iCoursesCount);

for I := 0 to iCoursesCount-1 do begin
  Images[I].Top := 6;
end;

for I := 0 to iCoursesCount-1 do
begin
  Dec(TargetTop, 41);
  while Images[I].Top <> TargetTop do
  begin
    Images[I].Top := Images[I].Top + 6;
    Sleep(8);
    Application.ProcessMessages;
    if Images[I].Top >= TargetTop then
    begin
      Images[I].Top := TargetTop;
      Break;
    end;
  end;
end;

也就是说,你真的不应该使用每次迭代都需要Application.ProcessMessages()的休眠循环。你可以考虑使用TTimerTThread.ForceQueue()。不要不必要地阻塞主UI线程。例如:

published
  procedure FormCreate(Sender: TObject);
private
  Images: array[0..6] of TImage;
  TargetTop: Integer;
  CurrentImage: Integer;
  procedure StartAnimatingMenu;
  procedure StartAnimatingNextMenuItem;
  procedure StepAnimateCurrentMenuItem;
  ...

...

procedure TMyForm.FormCreate(Sender: TObject);
begin
  Images[0] := imgCourses7;
  Images[1] := imgCourses6;
  Images[2] := imgCourses5;
  Images[3] := imgCourses4;
  Images[4] := imgCourses3;
  Images[5] := imgCourses2;
  Images[6] := imgCourses1;
end;

procedure TMyForm.StartAnimatingMenu;
var
  I: Integer;
begin
  for I := Low(Images) to High(Images) do begin
    Images[I].Top := 6;
  end;
  TargetTop := 6+(41*Length(Images));
  CurrentImage := -1;
  StartAnimatingNextMenuItem;
end;

procedure TMyForm.StartAnimatingNextMenuItem;
begin
  Inc(CurrentImage);
  if CurrentImage < Length(Images) then
  begin
    Dec(TargetTop, 41);
    StepAnimateCurrentMenuItem;
  end;
end;

procedure TMyForm.StepAnimateCurrentMenuItem;
begin
  if Images[CurrentImage].Top <> TargetTop then
  begin
    Images[CurrentImage].Top := Images[CurrentImage].Top + 6;
    TThread.ForceQueue(nil, StepAnimateCurrentMenuItem, 8);
  end
  else if Images[CurrentImage].Top >= TargetTop then
  begin
    Images[CurrentImage].Top := TargetTop;
    StartAnimatingNextMenuItem;
  end;
end;

相关问题