0

可能重复:
如何显示进度条?

我创建了一个 steganalisys 应用程序,我想添加一个进度条来显示该过程的工作时间。

procedure TForm2.Button2Click(Sender: TObject);
var
   q,x,y,leastSigBit,currentPixel,newPixelValue: integer;
   pixels: PByteArray;
   bmp: TBitmap;
  begin

   memo1.lines.clear;
   Image2.Picture.Assign(Image1.Picture.Bitmap);
   bmp := Image2.Picture.Bitmap;

   for y := 0 to bmp.Height-1 do
   begin
      pixels := bmp.ScanLine[y];
      for x := 0 to bmp.Width-1 do
      begin
         currentPixel := pixels[x];
         leastSigBit := getBit(currentPixel, 0);
         newPixelValue:=setBit(newPixelValue ,7,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,6,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,5,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,4,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,3,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,2,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,1,leastSigBit);
         newPixelValue:=setBit(newPixelValue ,0,leastSigBit);
        end;

         pixels[x] := newPixelValue;
         memo1.lines.append('pixel ke ' + inttostr(x) + ',' + inttostr(y) + ' desimal ' + inttostr(currentPixel) + ' (biner ' + toBinary(currentPixel) + ') ' +
         ' desimal baru ' + inttostr(newPixelValue) + ' (biner ' + toBinary(newPixelValue) + ')');
        end;
   end;
   memo1.lines.append('All done!');
   Button4.Enabled:=True;
   Button2.Enabled:=False;
   Button1.Enabled:=False;
   Button5.Enabled:=True;
        end;

如何为该过程制作进度条?我必须把命令进度条放在哪里?

4

1 回答 1

4

做这样的事情的正确方法是在后台线程中进行计算。否则,您的 GUI 将冻结,并且您可能无法添加Abort按钮。因此,您必须学习如何使用线程(例如TThread)来正确执行此操作。然后你的代码必须是线程安全的,你应该只在线程代码和 GUI 之间以安全的方式进行通信,例如使用消息。主要思想见我之前的回答

总之,如果你是出于教育目的或私人需要,或许上面提到的问题并没有那么严重。然后你可以像这样简单地做:

procedure TForm2.Button2Click(Sender: TObject);
var
  ...
begin

  ProgressBar1.Min := 0;
  ProgressBar1.Max := bmp.Height;
  ProgressBar1.Position := 0;
  ProgressBar1.Step := 1;

  for y := 0 to bmp.Height-1 do
  begin

    for x := 0 to bmp.Width-1 do
    begin
    end;

    ProgressBar1.StepIt;
    ProgressBar1.Update;

  end;

end;

要尝试此操作,请创建一个新的 VCL 项目。添加一个TProgressBar和一个TButton。在OnClick按钮的情况下,添加以下代码:

procedure TForm1.Button1Click(Sender: TObject);
var
  i, j: integer;
begin
  ProgressBar1.Min := 0;
  ProgressBar1.Max := 100;
  ProgressBar1.Position := 0;
  ProgressBar1.Step := 1;

  for i := 0 to 99 do
  begin

    for j := 0 to 200 do
    begin
      sleep(1);
    end;

    ProgressBar1.StepIt;
    ProgressBar1.Update;

  end;
end;

但是,请务必注意这种方法的最重要的背面。应用程序在整个“计算”期间冻结。您甚至可能无法移动应用程序窗口,而且您肯定无法与其 GUI 交互。Windows 甚至可能报告程序已冻结,并为您提供终止它并发送错误报告的选项...最后,由于整个 GUI 已关闭,因此无法添加“停止计算”按钮。解决方案?肮脏的一个是使用ProcessMessages和其他肮脏的伎俩。如前所述,正确的做法是将计算放在自己的线程中。

于 2012-12-09T20:49:24.110 回答