Progress Animado
alguém já precisou fazer uma tela de espera animada?
Tipo o sistema vai processar algo que pode demorar alguns segundos e tu exibe um progress (como o da entrada do xp) enquanto o usuário aguarda o retorno da aplicação.
Tentei montar algo com um timer para a pintura dos painéis e as vezes nem o form é exibido a tempo. Tentei métodos como refresh, uptdate, repaint e ProcessMesages e nada.
Minha próxima alternativa é utilizar threads.
Alguém tem outra idéia?
obrigado
Tipo o sistema vai processar algo que pode demorar alguns segundos e tu exibe um progress (como o da entrada do xp) enquanto o usuário aguarda o retorno da aplicação.
Tentei montar algo com um timer para a pintura dos painéis e as vezes nem o form é exibido a tempo. Tentei métodos como refresh, uptdate, repaint e ProcessMesages e nada.
Minha próxima alternativa é utilizar threads.
Alguém tem outra idéia?
obrigado
Andremuller
Curtidas 0
Respostas
Vinicius2k
30/12/2004
Colega,
Vc está no caminho certo... eu esbarrei neste problema há algum tempo e dois colegas de fórum (Beepe e Vini) me ajudaram com a dica e eu montei a unit do form abaixo :
Neste unit eu estou carregando um bitmap chamado PRINTING de um arquivo de recursos (.res) dividido de forma lógica em 6 frames de 32x32 e com fundo clFuchsia :
A vantagem de utilizar um arquivo de recursos é que o bitmap é incorporado à aplicação, e como é pequeno não ´pesa´.
Os componentes que vc irá utilizar são um TTimer e um TPaintBox.
Vc vai escrever nos eventos OnCreate, OnShow e OnClose do TForm, no evento OnTimer do TTimer e no evento OnPaint do TPaintBox.
O efeito final é identico ao de um gif :
Espero ter ajudado.
T+
Vc está no caminho certo... eu esbarrei neste problema há algum tempo e dois colegas de fórum (Beepe e Vini) me ajudaram com a dica e eu montei a unit do form abaixo :
unit unt_VDOPrintProgress;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
StdCtrls, ExtCtrls;
type
Tfrm_VDOPrintProgress = class(TForm)
tim_printing: TTimer;
bvl_main: TBevel;
lbl_printing: TLabel;
ptb_printing: TPaintBox;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure tim_printingTimer(Sender: TObject);
procedure ptb_printingPaint(Sender: TObject);
private
{ Private declarations }
Frames: TBitmap;
FrameIndex: Byte;
public
{ Public declarations }
end;
var
frm_VDOPrintProgress: Tfrm_VDOPrintProgress;
implementation
{$R *.dfm}
{$R VDOPrintProgress.res}
procedure Tfrm_VDOPrintProgress.FormCreate(Sender: TObject);
begin
Frames := TBitmap.Create;
Frames.LoadFromResourceName(HInstance,´PRINTING´);
FrameIndex := 0;
end;
procedure Tfrm_VDOPrintProgress.FormShow(Sender: TObject);
begin
DoubleBuffered := True;
tim_printing.Enabled := True;
end;
procedure Tfrm_VDOPrintProgress.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Frames.Free;
end;
procedure Tfrm_VDOPrintProgress.tim_printingTimer(Sender: TObject);
begin
ptb_printing.Refresh;
if FrameIndex > 5 then FrameIndex := 0;
end;
procedure Tfrm_VDOPrintProgress.ptb_printingPaint(Sender: TObject);
begin
with ptb_printing.Canvas do
begin
Brush.Color := Color;
FillRect(Bounds(0, 0, 32, 32));
BrushCopy(Bounds(0, 0, 32, 32), Frames, Bounds(FrameIndex * 32, 0, 32, 32), clFuchsia);
end;
end;
end.Neste unit eu estou carregando um bitmap chamado PRINTING de um arquivo de recursos (.res) dividido de forma lógica em 6 frames de 32x32 e com fundo clFuchsia :
A vantagem de utilizar um arquivo de recursos é que o bitmap é incorporado à aplicação, e como é pequeno não ´pesa´.
Os componentes que vc irá utilizar são um TTimer e um TPaintBox.
Vc vai escrever nos eventos OnCreate, OnShow e OnClose do TForm, no evento OnTimer do TTimer e no evento OnPaint do TPaintBox.
O efeito final é identico ao de um gif :
Espero ter ajudado.
T+
GOSTEI 0
Andremuller
30/12/2004
obrigado pela dica amigo mas está dando erro: duplicate resource(s)
quando retiro a declaração do segundo recurso não ocorre erro, mas, é claro, não carrega o bitmaç.
Primeiro tentei utilizar o res do projeto, como deu erro eu criei um res separado mas o erro persistiu.
Alguma idéia?
quando retiro a declaração do segundo recurso não ocorre erro, mas, é claro, não carrega o bitmaç.
Primeiro tentei utilizar o res do projeto, como deu erro eu criei um res separado mas o erro persistiu.
Alguma idéia?
GOSTEI 0
Vinicius2k
30/12/2004
Colega,
Vc não pode utilizar o .res do projeto porque o recurso é, simplesmente, ignorado na compilação (não sei o motivo). Então vc deve ter recebido a exceção EResNotFound.
Vc precisa do resource separado e as suas opções são:
1. Incluir a linha de acrescimo do recurso no projeto (.dpr)
2. Incluir a linha de acrescimo do recurso no próprio form.
Mas apenas uma das duas opções deve ser utilizada, caso contrário você terá o erro de duplicação de recursos. E qualquer que seja a opção, vc não terá erro.
Lembre-se de retirar o bitmap do .res da aplicação, pois ocuparia um espaço desnecessário.
T+
Vc não pode utilizar o .res do projeto porque o recurso é, simplesmente, ignorado na compilação (não sei o motivo). Então vc deve ter recebido a exceção EResNotFound.
Vc precisa do resource separado e as suas opções são:
1. Incluir a linha de acrescimo do recurso no projeto (.dpr)
...
uses
Forms,
Unit1 in ´Unit1.pas´ ;
{$R *.res}
{$R SeuArquivo.res}
begin
Application.Initialize;
...2. Incluir a linha de acrescimo do recurso no próprio form.
...
var
Form1: TForm1;
implementation
{$R *.dfm}
{$R SeuArquivo.res}
procedure TForm1...Mas apenas uma das duas opções deve ser utilizada, caso contrário você terá o erro de duplicação de recursos. E qualquer que seja a opção, vc não terá erro.
Lembre-se de retirar o bitmap do .res da aplicação, pois ocuparia um espaço desnecessário.
T+
GOSTEI 0
Andremuller
30/12/2004
o problema do res está resolvido. Deixei só no projeto e não declarei no form. Está carregando legal (não foi ignorado na compilação).
Agora acontece o primeiro problema, a imagem não inicia a animação (o forma está aparecendo).
Para testar a animação executo o seguinte código:
O negócio é que aqui na empresa utilizamos um componente proprietário que funciona nessa mesma rotina.
Agora acontece o primeiro problema, a imagem não inicia a animação (o forma está aparecendo).
Para testar a animação executo o seguinte código:
procedure TForm1.Button1Click(Sender: TObject); begin form2.show; Processa; Form2.Close; end; procedure TForm1.Processa; var i, j, h: integer; begin h := 0; for i := 0 to 10000 do for j := 0 to 200000 do inc(h); Caption := IntToStr(h); end;
O negócio é que aqui na empresa utilizamos um componente proprietário que funciona nessa mesma rotina.
GOSTEI 0
Vinicius2k
30/12/2004
Colega,
Vc teria que alterar sua procedure ´Processa´ desta forma :
Mas atenção : Esta chamada à Application.ProcessMessages comprometerá, e muito, a performance desta rotina na forma em que ela está estruturada... o processador, provavelmente, ficará em pico de 100¬ de utilização e o tempo de processamento irá crescer bastante... dependendo do que vc for fazer, é preferível não utilizar a animação.
Se o processamento da rotina for local, na minha opinião vc não deve utilizar, ou procurar outra alternativa. Como vc mesmo citou as Threads, talvez elas sejam melhor aplicáveis neste caso -- não sei lhe dizer pois não trabalho com Threads.
Se o processamento for no servidor, por exemplo, vc envia a consulta e enquanto aguarda o retorno do SGBD vc exibe a animação, não haverá comprometimento...
T+
Vc teria que alterar sua procedure ´Processa´ desta forma :
procedure TForm1.Processa; var i, j, h: integer; begin h := 0; for i := 0 to 10000 do for j := 0 to 200000 do begin inc(h); Application.ProcessMessages; end; Caption := IntToStr(h); end;
Mas atenção : Esta chamada à Application.ProcessMessages comprometerá, e muito, a performance desta rotina na forma em que ela está estruturada... o processador, provavelmente, ficará em pico de 100¬ de utilização e o tempo de processamento irá crescer bastante... dependendo do que vc for fazer, é preferível não utilizar a animação.
Se o processamento da rotina for local, na minha opinião vc não deve utilizar, ou procurar outra alternativa. Como vc mesmo citou as Threads, talvez elas sejam melhor aplicáveis neste caso -- não sei lhe dizer pois não trabalho com Threads.
Se o processamento for no servidor, por exemplo, vc envia a consulta e enquanto aguarda o retorno do SGBD vc exibe a animação, não haverá comprometimento...
T+
GOSTEI 0
Marcos Fernando
30/12/2004
Se o processamento for no servidor, por exemplo, vc envia a consulta e enquanto aguarda o retorno do SGBD vc exibe a animação, não haverá comprometimento...
mais enquanto espero o retorno minha aplicação fica congelada.
e não achei exemplos com threads e banco de dados, até fiz uma tela de testes com threads em um ProgressBar1 que fica achendo e zerando só pra mostrar que a aplicação não está congelada, mais quando eu mando abrir a tabela o ProgressBar1 para de contar
Alguém tem alguma exemplo com banco de dados e threads
Thanks
GOSTEI 0
Rafael Gomes
30/12/2004
olá amigos, aproveitando o topico, alguem saberia me dizer como fazer uma [b:bd5ea75028]barra de progressão [/b:bd5ea75028]que mostre quanto foi baixado de um [b:bd5ea75028]arquivo via ftp[/b:bd5ea75028]!?
ah, depois quando chegar no trampo posto um exemplo de barra de progressao utilizando Thread ..
ate mais
[]s
ah, depois quando chegar no trampo posto um exemplo de barra de progressao utilizando Thread ..
ate mais
[]s
GOSTEI 0
Marcos Fernando
30/12/2004
ah, depois quando chegar no trampo posto um exemplo de barra de progressao utilizando Thread ..
Só que preciso de um exemplo com Thread com banco de dados
thanks
GOSTEI 0
Rafael Gomes
30/12/2004
caro colega [b:65043e42f7]Marcos Fernando [/b:65043e42f7]... o exemplo que tinha sabe -se como sumiu de meu micro, mas hoje por sorte estava escrevendo algumas rotinas para gerar um script de inserts gigantescos, dai resolvi criar uma barrinha de progressao somente para testar ...
seria mais ou menos isso ...
aqui é a unit onde esta a thread
para chamar a thread, imagino que voce ja saiba mas fica aqui para quem nao sabe, talvez até mesmo eu esteja fazendo bobagem hehehe, se for o caso me corrijam!
aqui funcionou perfeitamente, enquanto o programa gera os inserts a barra vai subindo de acordo com o que ja foi processado ...
creio que o principio é o mesmo por exemplo se voce quisesse fazer uma rotina para inserir no banco de dados e fossem muitos registros ...
sou iniciante, caso tenha falado alguma bobagem me corrijam
espero ter ajudado,
qualquer coisa é só chamar!
[..]s
seria mais ou menos isso ...
aqui é a unit onde esta a thread
unit UProgress; interface uses classes, windows, uscript, sysutils, unit2; type TThreadBanco = class (TThread) public Constructor create; private protected procedure Execute; override; end; implementation constructor TThreadBanco.create; begin inherited Create(False); end; procedure TThreadBanco.Execute; var x: integer; begin form2.show; //aqui vai o codigo a ser executado pela thread for x:= 0 to 99999 do form2.Gauge1.progress:= x; form2.close; end; ...
para chamar a thread, imagino que voce ja saiba mas fica aqui para quem nao sabe, talvez até mesmo eu esteja fazendo bobagem hehehe, se for o caso me corrijam!
procedure TForm1.Button6Click(Sender: TObject); var T: TThreadBanco; begin T:= TThreadBanco.create; T.WaitFor; T.Free; end;
aqui funcionou perfeitamente, enquanto o programa gera os inserts a barra vai subindo de acordo com o que ja foi processado ...
creio que o principio é o mesmo por exemplo se voce quisesse fazer uma rotina para inserir no banco de dados e fossem muitos registros ...
sou iniciante, caso tenha falado alguma bobagem me corrijam
espero ter ajudado,
qualquer coisa é só chamar!
[..]s
GOSTEI 0
Marcos Fernando
30/12/2004
vc usa essa TThread para fazer informar o progresso dos registros incluidos tabela através de um script tá certo, só estou com dúvidas que se puder me esclarecer,
na sua TThread vc tem um for assim:
qual é a informação que vc pega da script para passar no for?
e como devo inicializar o script junto com o TThread?
e se fosse com um Ibdataset?
grato mesmo pela força
na sua TThread vc tem um for assim:
//aqui vai o codigo a ser executado pela thread for x:= 0 to 99999 do
qual é a informação que vc pega da script para passar no for?
e como devo inicializar o script junto com o TThread?
e se fosse com um Ibdataset?
grato mesmo pela força
GOSTEI 0
Rafael Gomes
30/12/2004
[quote:ca142f9261=´Marcos Fernando´]vc usa essa TThread para fazer informar o progresso dos registros incluidos tabela através de um script tá certo, só estou com dúvidas que se puder me esclarecer,
na sua TThread vc tem um for assim:
qual é a informação que vc pega da script para passar no for?
e como devo inicializar o script junto com o TThread?
e se fosse com um Ibdataset?
grato mesmo pela força[/quote:ca142f9261]
desculpe a demora amigo, nao havia abandonado o topico ... falta de tempo mesmo ...
pra fazer essa barra de progressao estou partindo do principio que sei quantos registros serao inseridos ...
no meu caso eu tenho todos os inserts em um arquivo texto ...
carrego o arquivo em uma TStringList e depois vou inserindo um a um ... o controle da progressao é a variavel x ....
agora a respeito do ibdataset, nunca usei ... mas creio que voce possa adaptar para usar de forma semelhante ...
vi alguem perguntando como faria para fazer uma barra de progressao durante o carregamento de uma query com muitos registro sem travar o programa ... isso eu nao sei como fazer, pq nao sei que valor pegar para saber quantos registros foram carregados e quantos ainda faltam .. nao sei se dentro desse contexto poderia usar recordcount, mas acho que nao .... vou pesquisar ... as vezes pode ate ser bobo e nao estou enxergando ... se laguem souber como fazer poste por favor!
[]ss
na sua TThread vc tem um for assim:
//aqui vai o codigo a ser executado pela thread for x:= 0 to 99999 do
qual é a informação que vc pega da script para passar no for?
e como devo inicializar o script junto com o TThread?
e se fosse com um Ibdataset?
grato mesmo pela força[/quote:ca142f9261]
desculpe a demora amigo, nao havia abandonado o topico ... falta de tempo mesmo ...
pra fazer essa barra de progressao estou partindo do principio que sei quantos registros serao inseridos ...
no meu caso eu tenho todos os inserts em um arquivo texto ...
carrego o arquivo em uma TStringList e depois vou inserindo um a um ... o controle da progressao é a variavel x ....
for x:= 0 to VariaveldoTipostringlist.count - 1 do ; begin qy.Close; qyclear; qy.sql.text:= VariaveldoTipostringlist.strings[x]; qy.Open end;
agora a respeito do ibdataset, nunca usei ... mas creio que voce possa adaptar para usar de forma semelhante ...
vi alguem perguntando como faria para fazer uma barra de progressao durante o carregamento de uma query com muitos registro sem travar o programa ... isso eu nao sei como fazer, pq nao sei que valor pegar para saber quantos registros foram carregados e quantos ainda faltam .. nao sei se dentro desse contexto poderia usar recordcount, mas acho que nao .... vou pesquisar ... as vezes pode ate ser bobo e nao estou enxergando ... se laguem souber como fazer poste por favor!
[]ss
GOSTEI 0
Marcos Fernando
30/12/2004
Grato pela atenção [b:d1b3e8618d]Rafael Gomes[/b:d1b3e8618d]
vou procurar mais a respeito, posso usar suas dicas em alguns caso, isso já ajuda muito, agora falta pouco, mais como já falei vou procurar...
Thanks
vou procurar mais a respeito, posso usar suas dicas em alguns caso, isso já ajuda muito, agora falta pouco, mais como já falei vou procurar...
Thanks
GOSTEI 0