我用ADOQuery1,DBGrid1做了一个查询,我现在想在点查询按钮的时候先弹出一个进度条(当然这个进度条可以是假的,只要动就可以),当数据查询完后就进度条窗口关闭!如何实现??麻烦各位给我一个详细的例子谢谢!
我已知道这个功能必须要多线程才能实现,但我不知道当点查询的时候如何创建一个新线程显示进度窗口,当数据查询完后如何销毁这个线程!!麻烦各位大哥帮我做个简单的例子,小弟谢谢了!!!
我已知道这个功能必须要多线程才能实现,但我不知道当点查询的时候如何创建一个新线程显示进度窗口,当数据查询完后如何销毁这个线程!!麻烦各位大哥帮我做个简单的例子,小弟谢谢了!!!
可以自己造一个form,放入progresss控件和timer控件,
使用的时候
progress.start;
try
finally
progress.finish;
end;
以上是委代码。
首先
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.
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然后销毁这个线程
以上两个地方具体我不懂该如何实现,麻烦各位帮我做个简单的例子,小弟谢谢了!!
try
ADOQuery1.close;
ADOQuery1.SQL.Add('select * from test');
ADOQuery1.open;
finally
Form2.close;
end;
你这样做有什么问题吗?
这样做是先显示了form2,但
ADOQuery1.close;
ADOQuery1.SQL.Add('select * from test');
ADOQuery1.open;
这一部分却没运行,也就是说程序在Form2.ShowModal的时候就停止了,必须关闭Form2窗体的时候才会继续运行查询的部分
这一来进度窗体就没任何意义了!所以我考虑是不是要创建一个新的线程来Form2.ShowModal,这样他就不会影响到查询了,但具体我不知道该如何实现,麻烦各位帮帮忙,谢谢
不用使用线程,你自己写个窗口,窗口上方个progressbar,你应该会写进度条,把查询写到这个窗口的show里,这样你show这个窗口的时候就触发查询了~
2、查询之前将进度条设为可见,并触发时钟事件
3、在时钟里循环地递增进度条position,并判断finish是否为TRUE,
如果为TRUE则将进度条position设为100,并将进度条隐藏,停止时钟;
否则继续循环滚动;
4、查询完成后将finish设为TRUE。
最好在时钟里加Application.ProcessMessages;
2、查询之前将进度条设为可见,并触发时钟事件
3、在时钟里循环地递增进度条position,并判断finish是否为TRUE,
如果为TRUE则将进度条position设为100,并将进度条隐藏,停止时钟;
否则继续循环滚动;
4、查询完成后将finish设为TRUE。
最好在时钟里加Application.ProcessMessages;
Form2.Show;
Form2.update;
try
ADOQuery1.close;
ADOQuery1.SQL.Add('select * from test');
ADOQuery1.open;
finally
Form2.close;
end;这样在Form2上加上进度条,并且当查询OK后Form2关闭。
我按照你的方法做,窗体是显示出来了但进度条不动,我把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;
hideprogress;当然,这个进度条无法描述一个查询方法的实际进度
实际上我在form2里也放了一个动画的GIF进度条,但我Form2.Show;Application.ProcessMessages;的时候显示的图片居然是不动的,和上面我说的问题是一样,要等到查询完毕后图片才会动,也就是说在查询按钮里的代码没有执行完前,from2窗体是没有响应完整的,该如何解决这个问题呢?
各位大哥你们以前没有做过查询等待的方式吗?你们是怎么做的?麻烦告诉小弟,小弟万分感谢!!
里面有个FormWait 就是等待窗体,稍作修改便可以了
我把代码贴一下,自己看吧。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;
呵,你是把查询放在了进度条窗体里了,这样一来那每个查询都必须做一个进度条这样就太繁琐了,我现在的想法是把进度条窗体做成一个独立的公共窗体,里面不写任何的查询代码,只要是查询直接调用他就可以了!那位大哥做过这样的例子给小弟一个,小弟谢谢了!!
能给个简单的例子吗?
再主程序中放一个panel,上面放进度条等控件。
当你执行统计的时候,显示这个panil,然后起线程,再线程中执行统计,统计之后,由线程隐藏主程序中的panel(这个不走需要使用同步方法Synchronize)。
如果需要处理后续操作,一样在线程中调用主程序的方法,使用Synchronize
ADOQuery1.close;
ADOQuery1.SQL.Add('select * from test');
ADOQuery1.open;
应该是会很快的,无需加进度条.