如何在delphi中显示进度条?

时间:2012-12-09 20:38:20

标签: delphi progress-bar delphi-7

  

可能重复:
  how to display progress bar?

我创建了一个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;

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

1 个答案:

答案 0 :(得分:4)

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

无论如何,如果你想为教育用户或私人需要这样做,也许上面提到的问题并不那么严重。然后你可以这样做:

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项目。添加TProgressBarTButton。在按钮的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和其他肮脏的技巧。正确的方法是将计算放在自己的线程中,如前所述。