我用ADOQuery1,DBGrid1做了一个查询,我现在想在点查询按钮的时候先弹出一个进度条(当然这个进度条可以是假的,只要动就可以),当数据查询完后就进度条窗口关闭!如何实现??麻烦各位给我一个详细的例子谢谢!
我已知道这个功能必须要多线程才能实现,但我不知道当点查询的时候如何创建一个新线程显示进度窗口,当数据查询完后如何销毁这个线程!!麻烦各位大哥帮我做个简单的例子,小弟谢谢了!!!

解决方案 »

  1.   

    假的?
    可以自己造一个form,放入progresss控件和timer控件,
    使用的时候
      progress.start;
      try
        
      finally
        progress.finish;
      end;
    以上是委代码。
      

  2.   


    首先
    ADOQuery1.ExecuteOptions:=[eoAsyncFetch];
    且ProgressBar1.max:=操作記錄數.
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ComCtrls, DB, ADODB, StdCtrls;type
      TForm1 = class(TForm)
        ADOQuery1: TADOQuery;
        ProgressBar1: TProgressBar;
        ADOConnection1: TADOConnection;
        btn1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure ADOQuery1FetchProgress(DataSet: TCustomADODataSet; Progress,
          MaxProgress: Integer; var EventStatus: TEventStatus);
        procedure btn1Click(Sender: TObject);
        procedure ADOQuery1FetchComplete(DataSet: TCustomADODataSet;
          const Error: Error; var EventStatus: TEventStatus);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    begin
      ADOConnection1.Connected:=True;
    end;procedure TForm1.ADOQuery1FetchProgress(DataSet: TCustomADODataSet;
      Progress, MaxProgress: Integer; var EventStatus: TEventStatus);
    begin
      ProgressBar1.Position:=Progress;
    end;procedure TForm1.btn1Click(Sender: TObject);
    begin
      ADOQuery1.Close;
      ADOQuery1.Open;
    end;procedure TForm1.ADOQuery1FetchComplete(DataSet: TCustomADODataSet;
      const Error: Error; var EventStatus: TEventStatus);
    begin
      ShowMessage('Complete');
    end;end.
      

  3.   

    用一个timer外加一个processbar搞定.很简单.给分,我可以给你做个DEMO
      

  4.   

    呵,可能各位没明白我的意思!进度条我是可以自己弄,我现在的问题是在于当显示进度条的时候而后台的查询还在继续,当查询的数据返回完后就关闭掉进度窗口!例如
    form1是主窗体,form2是进度条 如果我要做个查询
    Form2.ShowModal;
    ADOQuery1.close;
    ADOQuery1.SQL.Add('select * from test');
    ADOQuery1.open;
    Form2.close;如果按照上面的做法那就不能达到我的效果,我要的效果是当按查询按钮的时候先
    显示Form2

    ADOQuery1.close;
    ADOQuery1.SQL.Add('select * from test');
    ADOQuery1.open;
    会继续执行
    当执行完上面的语句后就
    Form2.close;
    我大概知道做法但我不知道具体该如何实现这里应该是生成一个新的线程,在这个线程里显示Form2
    ADOQuery1.close;
    ADOQuery1.SQL.Add('select * from test');
    ADOQuery1.open;
    这里应该是关闭Form2然后销毁这个线程
    以上两个地方具体我不懂该如何实现,麻烦各位帮我做个简单的例子,小弟谢谢了!!
      

  5.   

    Form2.ShowModal;
    try
      ADOQuery1.close;
      ADOQuery1.SQL.Add('select * from test');
      ADOQuery1.open;
    finally
      Form2.close; 
    end;
    你这样做有什么问题吗?
      

  6.   

    to SmallHand 
    这样做是先显示了form2,但  
    ADOQuery1.close;
    ADOQuery1.SQL.Add('select * from test');
    ADOQuery1.open;
    这一部分却没运行,也就是说程序在Form2.ShowModal的时候就停止了,必须关闭Form2窗体的时候才会继续运行查询的部分
    这一来进度窗体就没任何意义了!所以我考虑是不是要创建一个新的线程来Form2.ShowModal,这样他就不会影响到查询了,但具体我不知道该如何实现,麻烦各位帮帮忙,谢谢
      

  7.   

    不要用form2.showmodal,因为showmodal显示的窗口下,别的窗口都无法再使用~
    不用使用线程,你自己写个窗口,窗口上方个progressbar,你应该会写进度条,把查询写到这个窗口的show里,这样你show这个窗口的时候就触发查询了~
      

  8.   

    1、定义一个布尔型变量finish
    2、查询之前将进度条设为可见,并触发时钟事件
    3、在时钟里循环地递增进度条position,并判断finish是否为TRUE,
       如果为TRUE则将进度条position设为100,并将进度条隐藏,停止时钟;
       否则继续循环滚动;
    4、查询完成后将finish设为TRUE。
      最好在时钟里加Application.ProcessMessages;
      

  9.   

    1、定义一个布尔型变量finish
    2、查询之前将进度条设为可见,并触发时钟事件
    3、在时钟里循环地递增进度条position,并判断finish是否为TRUE,
       如果为TRUE则将进度条position设为100,并将进度条隐藏,停止时钟;
       否则继续循环滚动;
    4、查询完成后将finish设为TRUE。
      最好在时钟里加Application.ProcessMessages;
      

  10.   

    你这个也是可以的。只要form2:=tform2.create(self);
    Form2.Show;
    Form2.update;
    try
      ADOQuery1.close;
      ADOQuery1.SQL.Add('select * from test');
      ADOQuery1.open;
    finally
      Form2.close; 
    end;这样在Form2上加上进度条,并且当查询OK后Form2关闭。
      

  11.   

    to zhao_yong 
    我按照你的方法做,窗体是显示出来了但进度条不动,我把Form2.close去掉后发现要等到查询完毕后进度条才动,这是为何?
    下面是我的进度条窗体,帮忙看看是否有不对的地方?
    procedure TForm2.Timer1Timer(Sender: TObject);
    begin
    ProgressBar1.Position:=ProgressBar1.Position+1;
    end;procedure TForm2.FormShow(Sender: TObject);
    begin
    ProgressBar1.Max:=100;
    ProgressBar1.Min:=0;
    Timer1.Enabled:=true;
    end;
      

  12.   

    cnpack系列包里有个进度条单元,引用进来就可以showprogress(title);
    hideprogress;当然,这个进度条无法描述一个查询方法的实际进度
      

  13.   

    to try__again 
    实际上我在form2里也放了一个动画的GIF进度条,但我Form2.Show;Application.ProcessMessages;的时候显示的图片居然是不动的,和上面我说的问题是一样,要等到查询完毕后图片才会动,也就是说在查询按钮里的代码没有执行完前,from2窗体是没有响应完整的,该如何解决这个问题呢?
    各位大哥你们以前没有做过查询等待的方式吗?你们是怎么做的?麻烦告诉小弟,小弟万分感谢!!
      

  14.   

    http://www.2ccc.com/article.asp?articleid=2790
    里面有个FormWait 就是等待窗体,稍作修改便可以了
      

  15.   

    不知道我理解的对不对。
    我把代码贴一下,自己看吧。form2是主窗口
    //form2的代码
    procedure TForm1.selectbtnClick(Sender: TObject);
    begin
      form2.ShowModal;
    end;//form2的代码procedure TForm2.FormCreate(Sender: TObject);
    begin  adoquery1.ExecuteOptions:=[eoAsyncFetch];
    end;procedure TForm2.ADOQuery1FetchProgress(DataSet: TCustomADODataSet;
      Progress, MaxProgress: Integer; var EventStatus: TEventStatus);
    begin
      ProgressBar1.Max:=Maxprogress;
      ProgressBar1.Position:=progress;
      if progress=Maxprogress then begin
        sleep(2000);//由于查询时间太短加的
        //application.ProcessMessages;
        self.Close;
      end;
    end;procedure TForm2.FormActivate(Sender: TObject);
    begin
      with adoquery1 do begin
        close;
        sql.Clear;
        sql.Add('select * from clients');
        open;
      end;
    end;
      

  16.   

    to jjwang2004 
    呵,你是把查询放在了进度条窗体里了,这样一来那每个查询都必须做一个进度条这样就太繁琐了,我现在的想法是把进度条窗体做成一个独立的公共窗体,里面不写任何的查询代码,只要是查询直接调用他就可以了!那位大哥做过这样的例子给小弟一个,小弟谢谢了!!
      

  17.   

    用个TIMER就行了,还搞出了这么多方法.
      

  18.   

    to Stiven_PFan 
    能给个简单的例子吗?
      

  19.   

    这种情况,一般都用线程。我是这样处理的:
    再主程序中放一个panel,上面放进度条等控件。
    当你执行统计的时候,显示这个panil,然后起线程,再线程中执行统计,统计之后,由线程隐藏主程序中的panel(这个不走需要使用同步方法Synchronize)。
    如果需要处理后续操作,一样在线程中调用主程序的方法,使用Synchronize
      

  20.   

    楼主你弄反了,,要用线程工作的是查询动作,而不是进度条窗口,只要在查询动作中做好消息传递防止阻塞就可以了。。至于进度条,可以用TIMER让它动起来就可以了
      

  21.   

    如果只是执行
      ADOQuery1.close;
      ADOQuery1.SQL.Add('select * from test');
      ADOQuery1.open;
    应该是会很快的,无需加进度条.