Neste tutorial veremos como integrar o Agata Report , um poderoso gerador de relatórios escrito em PHP, brasileiro e Open Source, a um aplicativo escrito em Qt, no caso o nosso pequeno programa de exemplo. Embora o Kugar seja mais fácil de integrar a um sistema Qt por ser parte do Koffice, portanto do KDE e ser escrito em Qt, o Agata é mais completo e flexível, sendo multi banco, acessa vários bancos de dados(PostgreSql, MySql, SQLite, Oracle, DB2, MS-SQL, Informix, InterBase, Sybase, ou Frontbase e permite exportar os relatórios em formatos como PostScript, plain text, HTML, XML, PDF ou CSV (StarCalc, Excel).
Aqui, uma pequena descrição tirada do próprio manual do Agata...O Agata Report é um gerador de relatórios capaz de exporta-los em diversos formatos de arquivos. Também permite a produção de gráficos, a geração de códigos de barras, diagramas, comparações entre tabelas e cálculos, além de possibilitar a inclusão de imagens.
Ainda possibilita trabalhar com funções e parâmetros personalizados... também é multi plataforma, roda no Linux e no Windows®, outra vantagem evidente é que ele é um aplicativo independente da linguagem de programação que você usa, se seu cliente é uma pequena empresa onde o dono ou funcionários tem somente conhecimentos básicos de informática, seu sistema produzira os relatórios requeridos integrado ao Agata, mas em uma empresa de porte médio ou grande, onde geralmente encontraremos um profissional da área de informática administrando o servidor e a rede, este administrador sera capas de usar o Agata para acessar o Banco e produzir relatórios que podem não estar previstos no seu sistema.
Obs: Baixe aqui os fontes do aplicativo.
Para começar vamos voltar ao nosso aplicativo de exemplo, sistemaqt, vamos abrir novamente no QtDesigner o arquivo fClientes_Parent.ui que representa a nossa tela principal, fCad_Clientes_Parent e redimensiona-la para acrescentarmos mais um botão, este botão ira chamar uma segunda tela, necessária para configurarmos os relatórios, então ajuste o tamanho do form, coloque mais um PushButton e de-lhe o nome de botao_Agata (sem til mesmo), de-lhe o título de Agata Report.
Abaixo, janela principal com botão para o Agata Report.(Clique na imagem para ampliar).
>
Agora, vamos criar uma nova tela para configurarmos o relatório, no Designer vá em File->New->QWidget e clique no botão create, sera criada um novo objeto da classe Qwidget, ele sera nossa tela de configuração. De-lhe o nome (propriedade ObjectName) de fAnt_rel_Agata_Parent e de a propriedade WindowTitle o seguinte valor:"Relatórios Agata" e WindowModality como ApplicationModal, salve o arquivo com o nome de fAnt_rel_Agata_Parent.ui. Neste Qwidget vamos colocar dois PushButton e dois GroupBox, no primeiro GroupBox de a propriedade title o valor "Ordenar por:", coloque dois RadioButton dentro deste GroupBox e de-lhes o valor "Codigo" e "Nome" à propriedade text, respectivamente, e os nomes botao_Codigo e botao_Nome na propriedade ObjectName, respectivamente, deixe o botão "Nome" com a propriedade checked checada.
Ao segundo GroupBox de a propriedade title o valor "Formato do relatório:" e coloque quatro RadioButton neste GroupBox e de-lhes o valor "PDF" "OpenOffice" "HTML" e "TXT" a propriedade text, respectivamente, e botao_PDF, botao_SXW, botao_HTML, botao_TXT a propriedade ObjectName, respectivamente, deixe o botão "PDF" com a propriedade checked checada.
Por fim de a cada um dos PushButton a propriedade ObjectName botao_Imprimir e botao_Cancelar respectivamente e a propriedade text Imprimir e Cancelar respectivamente. Nossa tela ficara assim:
Abaixo, tela de configuração do relatório.(Clique na imagem para ampliar).
>
Use o Signal/Slot editor do designer para conectar o signal clicked() do botão cancelar com o slot close() da nossa tela.
Agora podemos abrir nosso projeto no Kdevelop para o uic gerar nossa classe baseada no arquivo do QtDesigner, abra o src.pro e em FORMS adicione o nome do arquivo que o Designer salvou no diretório do nosso projeto, fAnt_rel_Agata_Parent.ui, ficando assim:
Compile e o uic ira gerar o arquivo ui_fAnt_rel_Agata_Parent.h, que é a definição da nossa classe, porem não devemos escrever nada neste arquivo, pois cada vez que editarmos ele no Qtdesigner para alterarmos qualquer coisa, o Desiner gera outro arquivo sobre escrevendo nossas alterações, no próprio arquivo o uic coloca este comentário: "WARNING! All changes made in this file will be lost when recompiling ui file!" , o que faremos e criar uma nova classe herdada da classe que o uic criou.
No Kdevelop vá em Arquivo->Novo e ira se abrir a seguinte janela:
Abaixo, nova classe no Kdevelop.(Clique na imagem para ampliar).
>
Nomeie o arquivo como fAnt_rel_Agata, no combobox escolhi a opção C++ Header, a extensão .h ele ira colocar automaticamente, observe também que desmarquei o checkbox "Adicionar ao projeto" , esta opção fara com que o Kdevelop edite o src.pro e adicione automaticamente o arquivo criado, fAnt_rel_Agata.h a seção HEADERS do src.pro, mas prefiro faze-lo manualmente.
Repita a operação para criar mais um arquivo, desta vez escolha a opção C++ Source(.cpp) no Combobox e mantenha o mesmo nome, fAnt_rel_Agata, e deixe desmarcado o checbox "Adicionar ao projeto", clique no botão OK e então teremos os arquivos para criarmos nossa classe herdada da classe criada pelo uic a partir do arquivo gerado pelo Designer.
Inclua os dois arquivos, fAnt_rel_Agata.h e fAnt_rel_Agata.cpp no src.pro:
Abra o arquivo fAnt_rel_Agata.h no Kdevelop e vamos começar.
#ifndef FANT_REL_AGATA_H
#define FANT_REL_AGATA_H
#include <ui_fAnt_rel_Agata_Parent.h>//Para herdar da classe gerada pelo uic a partir do projeto do QTDesigner
class fAnt_rel_Agata: public QWidget,private Ui::fAnt_rel_Agata_Parent//Este é o nome da classe gerada pelo uic, se quiser abra o arquivo ui_fAnt_rel_Agata_Parent.h e no fina do arquivo encontrara a definição do namespace Ui
{
Q_OBJECT
public:
fAnt_rel_Agata(QWidget *parent = 0, const char *name = 0);
~fAnt_rel_Agata();
};
#endif
Salve e agora abra o arquivo fAnt_rel_Agata.cpp e digite o seguinte:
#include "fAnt_rel_Agata.h"
#include <QDesktopWidget>
fAnt_rel_Agata::fAnt_rel_Agata(QWidget *parent, const char *name)
{
setupUi(this);
this->setAttribute(Qt::WA_DeleteOnClose,true);//Para a janela se auto-destruir;
QRect rect = QApplication::desktop()->availableGeometry(this);
this->move(rect.center() - this->rect().center()); //para centralizar na tela.
this->setFixedSize (this->size()); //para não minimizar a janela.
}
fAnt_rel_Agata::~fAnt_rel_Agata()
{
}
Salve e compile, se não tiver erros, nossa classe esta pronta.
Agora abra o arquivo cadastro.h para declaramos nossa classe e podermos instancia-la.
Inclua na declaração de classes a seguinte linha:
class fAnt_rel_Agata;
Na declaração de slots coloque a seguinte linha:
void gera_Relatorio_Agata();
Depois abaixo da declaração de slots coloque a seguinte linha:
protected:
class fAnt_rel_Agata* fAnt_Agata;
Nosso arquivo cadastro.h ficara assim:
#ifndef CADASTRO_H
#define CADASTRO_H
#include <ui_fClientes_Parent.h>//Para herdar da classe gerada pelo uic a partir do projeto do QTDesigner
class QSqlQuery;
class QSqlQueryModel;
class QFile;
class QProcess;
class fAnt_rel_Agata;
class fCad_Clientes: public QMainWindow,private Ui::fCad_Clientes_Parent//Este é o nome da classe gerada pelo uic, se quiser abra o arquivo ui_fClientes_Parent.h e no fina do arquivo encontrara a definição do namespace Ui
{
Q_OBJECT
public:
fCad_Clientes(QWidget *parent = 0, const char *name = 0);
~fCad_Clientes();
private:
QSqlQuery* query_Clientes;//Nossa query de trabalho.
QSqlQuery* query_rel;//Para o relatório
QSqlQueryModel* model_Clientes;
QFile* arquivo;//Para gerar o arquivo do relatório.
//Para chamar o Kugar e verificar a existência de arquivos anteriores.
QProcess* exclui_Arquivo;
QProcess* cria_Arquivo;
QProcess* chama_Kugar;
private slots://Nossas funções de trabalho.
void grava_na_Tabela();
void altera_na_Tabela();
void exclui_na_Tabela();
void limpa_Tela();
void gera_Relatorio();
void gera_Relatorio_Agata();
protected:
class fAnt_rel_Agata* fAnt_Agata;
};
#endif
Agora abra o arquivo cadastro.cpp e adicione a seguinte linha nos includes:
#include "fAnt_rel_Agata.h"
depois vá até onde declaramos os SIGNAL/SLOTS para acrescentarmos a seguinte linha:
connect(botao_Agata,SIGNAL(clicked()),this,SLOT(gera_Relatorio_Agata()));
Agora vá até o fina do arquivo para definirmos a função gera_Relatorio_Agata:
void fCad_Clientes::gera_Relatorio_Agata()
{
fAnt_Agata=new fAnt_rel_Agata(this);
fAnt_Agata->show();
}
Compile e rode o programa, clique no botão Agata Report para abrirmos nossa tela:
Abaixo, tela de configuração do relatório.(Clique na imagem para ampliar).
>
Por enquanto esta janela não faz nada, então mãos a obra, vamos abrir oAgata Report e criar nossos relatórios, não vou detalhar o processo de criar relatórios de dentro do Agata pois ele tem um manual que ensina passo a passo como gerar seus relatórios, também ensina passo a passo como instalar o Agata no Linux e no Windows®:
http://www.agata.org.br/files/files//fred_agata///ManualAgata.pdf
Lembrando que o objetivo deste tutorial é ensinar a integrar o Agata através de sua api com um aplicativo escrito em Qt, para se aprofundar no uso do Agata além do manual você pode tirar duvidas se inscrevendo na lista de discussões do Agata:
http://server.codigolivre.org.br/mailman/listinfo/agata-brasil
O Agata trabalha com o conceito de projetos, cada projeto está ligado a um banco ou "database" dentro do banco de dados ao qual ele esta conectado, no nosso caso será o PostgreSql com o banco do nosso projeto, "projetoqt", dentro do projeto que o Agata cria é possível gerar quantos relatórios você quiser, você pode criar sua própria hierarquia.
Ao abrir o Agata pela primeira vez você vera a opção de se conectar ao banco, nesta opção você ira configurar a conexão do Agata ao banco e escolher um nome para o projeto, eu escolhi sistemaqt, que é o mesmo nome do projeto do sistema, lembrando que dentro do Postgre o nome do banco é projetoqt, portanto o projeto do Agata, "sistemaqt" se conecta ao banco "projetoqt" do Postgre:
Abaixo, tela de configuração da conexão do Agata.(Clique na imagem para ampliar).
>
A próxima janela é a principal do Agata, nela você ira selecionar a tabela e os campos do relatório, no nosso caso o sistema tem só uma tabela com apenas dois campos, codigo e nome. Vamos criar duas consultas à tabela dentro do Agata, uma por ordem de nome e outra por ordem de codigo e vamos salva-las com o nome de clientes_Nome.agt e clientes_Codigo.agt, respectivamente, dentro do diretório relatórios do nosso projeto.
Esta extensão .agt do Agata é um arquivo xml que é um modelo com as instruções para o Agata conectar-se ao banco, fazer a consulta e gerar o relatório, o Agata não tem um formato próprio, ele exporta para PDF, TXT, SXW, HTML, XML e outros, veja no manual. Abaixo a tela principal do Agata com a nossa consulta e a tela de visualização rápida. Consulte o manual do Agata sobre como montar a consulta, lá tem um passo a passo.
Abaixo, Agata Report, tela principal e visualização rapida do relatório.(Clique na imagem para ampliar).
>
Agora podemos começar a escrever o código para integrarmos o Agata ao nosso sistemas, pois esta janela do Agata não ira aparecer, logicamente, partimos do pressuposto de que o usuário não ira usar o Agata diretamente, nosso sistema fara isso por ele.
A api do agata consiste em scripts PHP que estão localizados no diretório /agata/api, vamos adaptar um deles para nosso uso, começando por parametriza-lo.
Abaixo, o script sample1.php que iremos usar como base:
Vamos la, na linha include_once... mudei colocando o caminho absoluto, pois no samples1 esta o caminho relativo, em $api->setReportPath comentei a linha, copiei e mudei o caminho que estava la para um parâmetro, $argv[1], o primeiro parâmetro, observe que o parâmetro é referenciado quase da mesma forma que em C e C++, este primeiro parâmetro é o caminho do modelo que criamos, clientes_Nome.agt e clientes_Codigo.agt, em $api->setFormat o formato, $argv[2], e em $api->setOutputPath, $argv[3], o caminho do diretório onde será gerado o relatório. A linha $api->setProject('sistemaqt'), sistemaqt é o nome do projeto dentro do Agata.
Observe que você poderia chamar este script da seguinte forma no console:
Parametrizamos o script senão teríamos de ter um scrip para cada relatório, poderíamos parametrizar mais ainda, como a linha $api->setLayout('default-PDF'), mas do jeito que esta é suficiente para começarmos.
Mude o nome do script de sample1.php para clientes_p.php.
Agora vamos criar um shell script para encapsular este script php, você pode achar redundante um script chamando outro, de fato você poderia chamar diretamente o script php de dentro do aplicativo Qt, porem eu parto do pressuposto de termos uma maior necessidade de controle e de que nem todo mundo que programa em C++ e Qt sabe php, mas com certeza sabe um pouco de shell script. que é proximo de C, segue abaixo um medelo de um shell scrpit que você pode usar:
Com este shell script podemos testar fatores elementares como se o php esta instalado, se os parâmetros estão corretos e o retorno da execução do script php.
Observe que a linha onde esta a chamada do php tambem pode ser parametrizada. Se você quizer compilar o aplicativo no Windows®, pode fazer um batch file para rodar a api do Agata:
O batch file e mais trabalhoso de fazer do que o shell script pois é uma linguagem mais limitada, o if por exemplo não admite que se teste duas variaveis ao mesmo tempo não tem or (||) ou and (&&) nos obrigando a usar goto e labels, o que torna a estrutura um pouco mais dificil de entender, mas este batch file que eu fiz funcionou perfeitamente no meu computador.
Alternativamente se você quiser usar no Windows® algo mais legivel eu fiz um pequeno programinha em C puro usando o mingw, este programa em C irá substituir o batch file caso você queira:
Para compilar, se você usou o mingw para compilar a Qt no Windows®, você tambem pode usa-lo para compilar este pequeno programa, basta entrar pelo prompt do DOS no diretório onde esta o fonte, no nosso caso eu nomei script.c, e digitar:gcc script.c -o script.exe.
Para editar o arquivo fonte eu usei o notpad++, tambem fiz um teste com o Code::Bloks, uma IDE open source para o mingw , assim que instalei ele já reconheceu o mingw e o tornou seu compilador default, para quem quiser é mais pratico do que a linha de comando.
Este pequeno programa em C fará o papel do batch file, sera chamado de dentro do aplicativo Qt, lembrando que no Linux não é necessario, pois o shell script é mais do que suficiente.
Você pode e deve alterar este programa C ao seu gosto, pois ele é básico e elementar.
Agora, vamos escrever o código para nosso aplicativo chamar estes scripts e passar a eles os parâmetros necessários ao relatório.
Abra novamente no Kdevelop os arquivos fAnt_rel_Agata.h e fAnt_rel_Agata.cpp para criarmos uma função que ira chamar nosso script.
No fAnt_rel_Agata.h coloque as seguintes linhas abaixo da declaração public:
private:
QButtonGroup* radio_Grupo_Ordem;
QButtonGroup* radio_grupo_Formato;
QProcess* chama_Agata;
private slots:
gera_rel_Agata();
O arquivo ficara assim:
#ifndef FANT_REL_AGATA_H
#define FANT_REL_AGATA_H
#include <ui_fAnt_rel_Agata_Parent.h>//Para herdar da classe gerada pelo uic a partir do projeto do QTDesigner
class Qprocess;
class QFile;
class QButtonGroup;
class fAnt_rel_Agata: public QWidget,private Ui::fAnt_rel_Agata_Parent//Este é o nome da classe gerada pelo uic, se quiser abra o arquivo ui_fAnt_rel_Agata_Parent.h e no fina do arquivo encontrara a definição do namespace Ui
{
Q_OBJECT
public:
fAnt_rel_Agata(QWidget *parent = 0, const char *name = 0);
~fAnt_rel_Agata();
private:
QButtonGroup* radio_Grupo_Ordem;
QButtonGroup* radio_grupo_Formato;
QProcess* chama_Agata;
QFile* arquivo;
private slots:
void gera_rel_Agata();
};
#endif
Agora vá no fAnt_rel_Agata.cpp e no constructor iremos criar dois objetos da classe QbuttonGroup para agruparmos os RadioButtons que criamos, para que eles possam trabalhar em conjunto:
radio_Grupo_Ordem=new QButtonGroup(this);//cria o QButtonGroup
radio_Grupo_Ordem->setExclusive(true);//clicou em um, desmarcou o outro
radio_Grupo_Ordem->addButton(botao_Codigo);//adiciona o RadioButton ao QbuttonGroup
radio_Grupo_Ordem->setId(botao_Codigo,0);// indice do RadioButton dentro do QbuttonGroup
radio_Grupo_Ordem->addButton(botao_Nome);
radio_Grupo_Ordem->setId(botao_Nome,1);
radio_grupo_Formato=new QButtonGroup(this);
radio_grupo_Formato->setExclusive(true);
radio_grupo_Formato->addButton(botao_PDF);
radio_grupo_Formato->setId(botao_PDF,0);
radio_grupo_Formato->addButton(botao_SXW);
radio_grupo_Formato->setId(botao_SXW,1);
radio_grupo_Formato->addButton(botao_HTML);
radio_grupo_Formato->setId(botao_HTML,2);
radio_grupo_Formato->addButton(botao_TXT);
radio_grupo_Formato->setId(botao_TXT,3);
connect(botao_Imprimir,SIGNAL(clicked()),this,SLOT(gera_rel_Agata()));//para conectar a funçaõ ao botão
chama_Agata = new QProcess(this);//para criar o objeto Qprocess
arquivo=new QFile(this);
Não se esqueca de destruir todos os objetos alocados dinamicamente:
fAnt_rel_Agata::~fAnt_rel_Agata()
{
delete chama_Agata;
delete radio_Grupo_Ordem;
delete radio_grupo_Formato;
delete arquivo;
}
Finalmente chegamos ao ponto crucial da integração do Agata ao nosso aplicativo, criar um código que ira chamar os scripts que criamos e gerar nosso relatório. Antes disso, inclua as seguintes linhas no arquivo config.txt:
[caminhos]
relatorios = /home/rodolfo/sistemaqt/relatorios
pdf = /home/rodolfo/reader7.0.9/bin/acroread
swx = /usr/bin/broffice -writer
txt = /usr/bin/kwrite
html = /usr/bin/iceweasel
Ele ficara assim:
[banco]
database = QPSQL
hostname = localhost
databasename = projetoqt
[caminhos]
relatorios = /home/rodolfo/sistemaqt/relatorios
pdf = /home/rodolfo/reader7.0.9/bin/acroread
swx = /usr/bin/broffice -writer
txt = /usr/bin/kwrite
html = /usr/bin/iceweasel
Vá agora ao final do arquivo para declararmos a função que ira gerar o relatório, vou comentar o código para que você entenda.
Clique aqui para ver o arqivo fAnt_rel_Agata.cpp completo.
Compile e teste, você terá um aplicativo Qt com capacidade de emissão de relatórios em vários formatos e ainda multi plataforma, você pode recompilar no Windows® e tera o mesmo aplicativo nos dois sistemas operacionais.
Obs: Baixe aqui os fontes do aplicativo.
Abaixo, os relatórios prontos em pdf e html:
Abaixo, tela de retorno do console.(Clique na imagem para ampliar).
>
Abaixo, relatório PDF.(Clique na imagem para ampliar).
>
Abaixo, relatório HTML.(Clique na imagem para ampliar).
>
Gostou deste tutorial?, ele foi útil para você, no seu trabalho ou nos seus estudos? De a sua opinião:
Tutorial anterior:Criando um relatório para o aplicativo com o Kugar
Próximo Tutorial: Integrando o openRPT a um aplicativo Qt
Aqui, uma pequena descrição tirada do próprio manual do Agata...O Agata Report é um gerador de relatórios capaz de exporta-los em diversos formatos de arquivos. Também permite a produção de gráficos, a geração de códigos de barras, diagramas, comparações entre tabelas e cálculos, além de possibilitar a inclusão de imagens.
Ainda possibilita trabalhar com funções e parâmetros personalizados... também é multi plataforma, roda no Linux e no Windows®, outra vantagem evidente é que ele é um aplicativo independente da linguagem de programação que você usa, se seu cliente é uma pequena empresa onde o dono ou funcionários tem somente conhecimentos básicos de informática, seu sistema produzira os relatórios requeridos integrado ao Agata, mas em uma empresa de porte médio ou grande, onde geralmente encontraremos um profissional da área de informática administrando o servidor e a rede, este administrador sera capas de usar o Agata para acessar o Banco e produzir relatórios que podem não estar previstos no seu sistema.
Obs: Baixe aqui os fontes do aplicativo.
Para começar vamos voltar ao nosso aplicativo de exemplo, sistemaqt, vamos abrir novamente no QtDesigner o arquivo fClientes_Parent.ui que representa a nossa tela principal, fCad_Clientes_Parent e redimensiona-la para acrescentarmos mais um botão, este botão ira chamar uma segunda tela, necessária para configurarmos os relatórios, então ajuste o tamanho do form, coloque mais um PushButton e de-lhe o nome de botao_Agata (sem til mesmo), de-lhe o título de Agata Report.
Abaixo, janela principal com botão para o Agata Report.(Clique na imagem para ampliar).
>
Agora, vamos criar uma nova tela para configurarmos o relatório, no Designer vá em File->New->QWidget e clique no botão create, sera criada um novo objeto da classe Qwidget, ele sera nossa tela de configuração. De-lhe o nome (propriedade ObjectName) de fAnt_rel_Agata_Parent e de a propriedade WindowTitle o seguinte valor:"Relatórios Agata" e WindowModality como ApplicationModal, salve o arquivo com o nome de fAnt_rel_Agata_Parent.ui. Neste Qwidget vamos colocar dois PushButton e dois GroupBox, no primeiro GroupBox de a propriedade title o valor "Ordenar por:", coloque dois RadioButton dentro deste GroupBox e de-lhes o valor "Codigo" e "Nome" à propriedade text, respectivamente, e os nomes botao_Codigo e botao_Nome na propriedade ObjectName, respectivamente, deixe o botão "Nome" com a propriedade checked checada.
Ao segundo GroupBox de a propriedade title o valor "Formato do relatório:" e coloque quatro RadioButton neste GroupBox e de-lhes o valor "PDF" "OpenOffice" "HTML" e "TXT" a propriedade text, respectivamente, e botao_PDF, botao_SXW, botao_HTML, botao_TXT a propriedade ObjectName, respectivamente, deixe o botão "PDF" com a propriedade checked checada.
Por fim de a cada um dos PushButton a propriedade ObjectName botao_Imprimir e botao_Cancelar respectivamente e a propriedade text Imprimir e Cancelar respectivamente. Nossa tela ficara assim:
Abaixo, tela de configuração do relatório.(Clique na imagem para ampliar).
>
Use o Signal/Slot editor do designer para conectar o signal clicked() do botão cancelar com o slot close() da nossa tela.
Agora podemos abrir nosso projeto no Kdevelop para o uic gerar nossa classe baseada no arquivo do QtDesigner, abra o src.pro e em FORMS adicione o nome do arquivo que o Designer salvou no diretório do nosso projeto, fAnt_rel_Agata_Parent.ui, ficando assim:
FORMS += fClientes_Parent.ui \
fAnt_rel_Agata_Parent.ui
SOURCES += cadastro.cpp \
main.cpp
HEADERS += cadastro.h
TEMPLATE = app
CONFIG += debug \
warn_on \
thread \
qt
TARGET = ../bin/cadastro
QT += sql
RESOURCES += icones.qrc
Compile e o uic ira gerar o arquivo ui_fAnt_rel_Agata_Parent.h, que é a definição da nossa classe, porem não devemos escrever nada neste arquivo, pois cada vez que editarmos ele no Qtdesigner para alterarmos qualquer coisa, o Desiner gera outro arquivo sobre escrevendo nossas alterações, no próprio arquivo o uic coloca este comentário: "WARNING! All changes made in this file will be lost when recompiling ui file!" , o que faremos e criar uma nova classe herdada da classe que o uic criou.
No Kdevelop vá em Arquivo->Novo e ira se abrir a seguinte janela:
Abaixo, nova classe no Kdevelop.(Clique na imagem para ampliar).
>
Nomeie o arquivo como fAnt_rel_Agata, no combobox escolhi a opção C++ Header, a extensão .h ele ira colocar automaticamente, observe também que desmarquei o checkbox "Adicionar ao projeto" , esta opção fara com que o Kdevelop edite o src.pro e adicione automaticamente o arquivo criado, fAnt_rel_Agata.h a seção HEADERS do src.pro, mas prefiro faze-lo manualmente.
Repita a operação para criar mais um arquivo, desta vez escolha a opção C++ Source(.cpp) no Combobox e mantenha o mesmo nome, fAnt_rel_Agata, e deixe desmarcado o checbox "Adicionar ao projeto", clique no botão OK e então teremos os arquivos para criarmos nossa classe herdada da classe criada pelo uic a partir do arquivo gerado pelo Designer.
Inclua os dois arquivos, fAnt_rel_Agata.h e fAnt_rel_Agata.cpp no src.pro:
TEMPLATE = app
TARGET = ../bin/cadastro
DEPENDPATH += . icones
INCLUDEPATH += .
# Input
HEADERS += cadastro.h \
fAnt_rel_Agata.h
FORMS += fClientes_Parent.ui \
fAnt_rel_Agata_Parent.ui
SOURCES += cadastro.cpp main.cpp \
fAnt_rel_Agata.cpp
RESOURCES += icones/icones.qrc
QT += sql
Abra o arquivo fAnt_rel_Agata.h no Kdevelop e vamos começar.
#ifndef FANT_REL_AGATA_H
#define FANT_REL_AGATA_H
#include <ui_fAnt_rel_Agata_Parent.h>//Para herdar da classe gerada pelo uic a partir do projeto do QTDesigner
class fAnt_rel_Agata: public QWidget,private Ui::fAnt_rel_Agata_Parent//Este é o nome da classe gerada pelo uic, se quiser abra o arquivo ui_fAnt_rel_Agata_Parent.h e no fina do arquivo encontrara a definição do namespace Ui
{
Q_OBJECT
public:
fAnt_rel_Agata(QWidget *parent = 0, const char *name = 0);
~fAnt_rel_Agata();
};
#endif
Salve e agora abra o arquivo fAnt_rel_Agata.cpp e digite o seguinte:
#include "fAnt_rel_Agata.h"
#include <QDesktopWidget>
fAnt_rel_Agata::fAnt_rel_Agata(QWidget *parent, const char *name)
{
setupUi(this);
this->setAttribute(Qt::WA_DeleteOnClose,true);//Para a janela se auto-destruir;
QRect rect = QApplication::desktop()->availableGeometry(this);
this->move(rect.center() - this->rect().center()); //para centralizar na tela.
this->setFixedSize (this->size()); //para não minimizar a janela.
}
fAnt_rel_Agata::~fAnt_rel_Agata()
{
}
Salve e compile, se não tiver erros, nossa classe esta pronta.
Agora abra o arquivo cadastro.h para declaramos nossa classe e podermos instancia-la.
Inclua na declaração de classes a seguinte linha:
class fAnt_rel_Agata;
Na declaração de slots coloque a seguinte linha:
void gera_Relatorio_Agata();
Depois abaixo da declaração de slots coloque a seguinte linha:
protected:
class fAnt_rel_Agata* fAnt_Agata;
Nosso arquivo cadastro.h ficara assim:
#ifndef CADASTRO_H
#define CADASTRO_H
#include <ui_fClientes_Parent.h>//Para herdar da classe gerada pelo uic a partir do projeto do QTDesigner
class QSqlQuery;
class QSqlQueryModel;
class QFile;
class QProcess;
class fAnt_rel_Agata;
class fCad_Clientes: public QMainWindow,private Ui::fCad_Clientes_Parent//Este é o nome da classe gerada pelo uic, se quiser abra o arquivo ui_fClientes_Parent.h e no fina do arquivo encontrara a definição do namespace Ui
{
Q_OBJECT
public:
fCad_Clientes(QWidget *parent = 0, const char *name = 0);
~fCad_Clientes();
private:
QSqlQuery* query_Clientes;//Nossa query de trabalho.
QSqlQuery* query_rel;//Para o relatório
QSqlQueryModel* model_Clientes;
QFile* arquivo;//Para gerar o arquivo do relatório.
//Para chamar o Kugar e verificar a existência de arquivos anteriores.
QProcess* exclui_Arquivo;
QProcess* cria_Arquivo;
QProcess* chama_Kugar;
private slots://Nossas funções de trabalho.
void grava_na_Tabela();
void altera_na_Tabela();
void exclui_na_Tabela();
void limpa_Tela();
void gera_Relatorio();
void gera_Relatorio_Agata();
protected:
class fAnt_rel_Agata* fAnt_Agata;
};
#endif
Agora abra o arquivo cadastro.cpp e adicione a seguinte linha nos includes:
#include "fAnt_rel_Agata.h"
depois vá até onde declaramos os SIGNAL/SLOTS para acrescentarmos a seguinte linha:
connect(botao_Agata,SIGNAL(clicked()),this,SLOT(gera_Relatorio_Agata()));
Agora vá até o fina do arquivo para definirmos a função gera_Relatorio_Agata:
void fCad_Clientes::gera_Relatorio_Agata()
{
fAnt_Agata=new fAnt_rel_Agata(this);
fAnt_Agata->show();
}
Compile e rode o programa, clique no botão Agata Report para abrirmos nossa tela:
Abaixo, tela de configuração do relatório.(Clique na imagem para ampliar).
>
Por enquanto esta janela não faz nada, então mãos a obra, vamos abrir oAgata Report e criar nossos relatórios, não vou detalhar o processo de criar relatórios de dentro do Agata pois ele tem um manual que ensina passo a passo como gerar seus relatórios, também ensina passo a passo como instalar o Agata no Linux e no Windows®:
http://www.agata.org.br/files/files//fred_agata///ManualAgata.pdf
Lembrando que o objetivo deste tutorial é ensinar a integrar o Agata através de sua api com um aplicativo escrito em Qt, para se aprofundar no uso do Agata além do manual você pode tirar duvidas se inscrevendo na lista de discussões do Agata:
http://server.codigolivre.org.br/mailman/listinfo/agata-brasil
O Agata trabalha com o conceito de projetos, cada projeto está ligado a um banco ou "database" dentro do banco de dados ao qual ele esta conectado, no nosso caso será o PostgreSql com o banco do nosso projeto, "projetoqt", dentro do projeto que o Agata cria é possível gerar quantos relatórios você quiser, você pode criar sua própria hierarquia.
Ao abrir o Agata pela primeira vez você vera a opção de se conectar ao banco, nesta opção você ira configurar a conexão do Agata ao banco e escolher um nome para o projeto, eu escolhi sistemaqt, que é o mesmo nome do projeto do sistema, lembrando que dentro do Postgre o nome do banco é projetoqt, portanto o projeto do Agata, "sistemaqt" se conecta ao banco "projetoqt" do Postgre:
Abaixo, tela de configuração da conexão do Agata.(Clique na imagem para ampliar).
>
A próxima janela é a principal do Agata, nela você ira selecionar a tabela e os campos do relatório, no nosso caso o sistema tem só uma tabela com apenas dois campos, codigo e nome. Vamos criar duas consultas à tabela dentro do Agata, uma por ordem de nome e outra por ordem de codigo e vamos salva-las com o nome de clientes_Nome.agt e clientes_Codigo.agt, respectivamente, dentro do diretório relatórios do nosso projeto.
Esta extensão .agt do Agata é um arquivo xml que é um modelo com as instruções para o Agata conectar-se ao banco, fazer a consulta e gerar o relatório, o Agata não tem um formato próprio, ele exporta para PDF, TXT, SXW, HTML, XML e outros, veja no manual. Abaixo a tela principal do Agata com a nossa consulta e a tela de visualização rápida. Consulte o manual do Agata sobre como montar a consulta, lá tem um passo a passo.
Abaixo, Agata Report, tela principal e visualização rapida do relatório.(Clique na imagem para ampliar).
>
Agora podemos começar a escrever o código para integrarmos o Agata ao nosso sistemas, pois esta janela do Agata não ira aparecer, logicamente, partimos do pressuposto de que o usuário não ira usar o Agata diretamente, nosso sistema fara isso por ele.
A api do agata consiste em scripts PHP que estão localizados no diretório /agata/api, vamos adaptar um deles para nosso uso, começando por parametriza-lo.
Abaixo, o script sample1.php que iremos usar como base:
<?
#+-----------------------------------------------------------------+
#| AGATA Report API (http://www.agata.org.br) |
#| Copyleft (l) 2004 Solis - Lajeado - RS - Brasil |
#| Licensed under GPL: http://www.fsf.org for further details |
#+-----------------------------------------------------------------+
#| Started in 2001, August, 10 |
#| Author: Pablo Dall'Oglio (pablo@dalloglio.net) |
#+-----------------------------------------------------------------+
#| Agata Report: A Database reporting tool written in PHP-GTK |
#| This file shows how to use AgataAPI to generate simple reports |
#+-----------------------------------------------------------------+
# Include AgataAPI class
include_once '/agata/classes/core/AgataAPI.class';
# Instantiate AgataAPI
$api = new AgataAPI;
$api->setLanguage('es'); //'en', 'pt', 'es', 'de', 'fr', 'it', 'se'
$api->setReportPath('/agata/reports/samples/customers.agt');
$api->setProject('sqlite');
$api->setFormat('pdf'); // 'pdf', 'txt', 'xml', 'html', 'csv', 'sxw'
$api->setOutputPath('/tmp/test.pdf');
$api->setLayout('default-PDF');
#var_dump($api->GetParameters());
#How to set parameters, if they exist
#$api->setParameter('$personCode', 4);
#$api->setParameter('$personName', "'mary'");
$ok = $api->generateReport();
if (!$ok)
{
echo $api->getError();
}
else
{
// opens file dialog
$api->fileDialog();
}
?>
Essencialmente o que temos de mudar são os caminhos de entrada e saida, que estão fixos no script, e o formato do relatório que sera gerado, se será pdt, txt etx. O script ficara assim, deixei comentadas as linha que mudaram, para efeito de comparação.
<?
#+-----------------------------------------------------------------+
#| AGATA Report API (http://www.agata.org.br) |
#| Copyleft (l) 2004 Solis - Lajeado - RS - Brasil |
#| Licensed under GPL: http://www.fsf.org for further details |
#+-----------------------------------------------------------------+
#| Started in 2001, August, 10 |
#| Author: Pablo Dall'Oglio (pablo@dalloglio.net) |
#+-----------------------------------------------------------------+
#| Agata Report: A Database reporting tool written in PHP-GTK |
#| This file shows how to use AgataAPI to generate simple reports |
#+-----------------------------------------------------------------+
# Include AgataAPI class
include_once '/home/rodolfo/Agata_Report/agata/classes/core/AgataAPI.class';
# Instantiate AgataAPI
$api = new AgataAPI;
$api->setLanguage('pt'); //'en', 'pt', 'es', 'de', 'fr', 'it', 'se'
#$api->setReportPath('/agata/reports/samples/customers.agt');
$api->setReportPath($argv[1]);
$api->setProject('sistemaqt');
#$api->setFormat('txt'); // 'pdf', 'txt', 'xml', 'html', 'csv', 'sxw'
$api->setFormat($argv[2]); // 'pdf', 'txt', 'xml', 'html', 'csv', 'sxw'
#$api->setOutputPath('/tmp/test.pdf');
$api->setOutputPath($argv[3]);
$api->setLayout('default-PDF');
#var_dump($api->GetParameters());
#How to set parameters, if they exist
#$api->setParameter('$personCode', 4);
#$api->setParameter('$personName', "'mary'");
$ok = $api->generateReport();
if (!$ok)
{
echo $api->getError();
}
else
{
// opens file dialog
//$api->fileDialog();
}
?>
Vamos la, na linha include_once... mudei colocando o caminho absoluto, pois no samples1 esta o caminho relativo, em $api->setReportPath comentei a linha, copiei e mudei o caminho que estava la para um parâmetro, $argv[1], o primeiro parâmetro, observe que o parâmetro é referenciado quase da mesma forma que em C e C++, este primeiro parâmetro é o caminho do modelo que criamos, clientes_Nome.agt e clientes_Codigo.agt, em $api->setFormat o formato, $argv[2], e em $api->setOutputPath, $argv[3], o caminho do diretório onde será gerado o relatório. A linha $api->setProject('sistemaqt'), sistemaqt é o nome do projeto dentro do Agata.
Observe que você poderia chamar este script da seguinte forma no console:
/usr/bin/php /home/sistemaqt/relatorios/sample1.php /home/sistemaqt/relatorios/clientes_Nome.agt pdf /home/sistemaqt/relatorios/clientes_Nome.pdfe ele já geraria o nosso relatório.
Parametrizamos o script senão teríamos de ter um scrip para cada relatório, poderíamos parametrizar mais ainda, como a linha $api->setLayout('default-PDF'), mas do jeito que esta é suficiente para começarmos.
Mude o nome do script de sample1.php para clientes_p.php.
Agora vamos criar um shell script para encapsular este script php, você pode achar redundante um script chamando outro, de fato você poderia chamar diretamente o script php de dentro do aplicativo Qt, porem eu parto do pressuposto de termos uma maior necessidade de controle e de que nem todo mundo que programa em C++ e Qt sabe php, mas com certeza sabe um pouco de shell script. que é proximo de C, segue abaixo um medelo de um shell scrpit que você pode usar:
#!/bin/bash
if [ -e /usr/bin/php ]; then
if [ -z $1 ] || [ -z $2 ] || [ -z $3 ];then
echo "Verifique os parâmetros do relatório";
echo "Especifique o caminho do modelo do relatório.Ex:/home/vendas/relatorios/cidades.agt...";
echo "Especifique o formato do relatório.Ex: pdf, txt, xml, html, csv, sxw";
echo "Especifique o caminho de saida do relatório.Ex: Ex:/home/vendas/relatorios/cidades.pdf";
else
echo $1 $2 $3;
if php -q /home/rodolfo/sistemaqt/relatorios/clientes_p.php $1 $2 $3; then
echo Gerando relatório;
else
echo Nâo foi possivel gerar o relatório.;
fi;
fi;
else
echo /usr/bin/php não esta instalado!;
fi;
Com este shell script podemos testar fatores elementares como se o php esta instalado, se os parâmetros estão corretos e o retorno da execução do script php.
Observe que a linha onde esta a chamada do php tambem pode ser parametrizada. Se você quizer compilar o aplicativo no Windows®, pode fazer um batch file para rodar a api do Agata:
cls
@ECHO OFF
if not exist C:\agata\php\php.exe ( goto sair1 ) else ( goto teste1 )
:sair1
echo php não instalado
exit
:teste1
if %1.==. ( goto sair2 ) else ( goto teste2 )
:sair2
echo Especifique o caminho do modelo do relatório.Ex:/home/vendas/relatorios/cidades.agt...
goto fim_Erro
:teste2
if %1=="" ( goto sair3 ) else ( goto teste3 )
:sair3
echo Especifique o caminho do modelo do relatório.Ex:/relatorios/clientes.agt...
goto fim_Erro
:teste3
echo %1
if %2.==. ( goto sair4 ) else ( goto teste4)
:sair4
echo Especifique o formato do relatório.Ex: pdf, txt, xml, html, csv, sxw
goto fim_Erro
:teste4
if %2=="" ( goto sair5 ) else ( goto teste5)
:sair5
echo Especifique o formato do relatório.Ex: pdf, txt, xml, html, csv, sxw
goto fim_Erro
:teste5
echo %2
if %3.==. ( goto sair6 ) else ( goto teste6)
:sair 6
echo Especifique o caminho de saida do relatório.Ex: Ex:/relatorios/cidades.pdf
goto fim_Erro
:teste6
if %3=="" ( goto sair7 ) else ( goto gera_Rel )
:sair7
echo Especifique o caminho de saida do relatório.Ex: Ex:/relatorios/cidades.pdf
goto fim_Erro
:gera_Rel
echo %3
php.exe C:\SistemasQT\projetoqt_QTCreator\projetoqt\relatorios\clientes_p.php %1 %2 %3
if %errorlevel%==0 ( goto fim ) else ( goto fim_Erro)
:fim_Erro
echo Não foi possivel gerar o relatório
:fim
echo Relatório gerado com sucesso
exit
O batch file e mais trabalhoso de fazer do que o shell script pois é uma linguagem mais limitada, o if por exemplo não admite que se teste duas variaveis ao mesmo tempo não tem or (||) ou and (&&) nos obrigando a usar goto e labels, o que torna a estrutura um pouco mais dificil de entender, mas este batch file que eu fiz funcionou perfeitamente no meu computador.
Alternativamente se você quiser usar no Windows® algo mais legivel eu fiz um pequeno programinha em C puro usando o mingw, este programa em C irá substituir o batch file caso você queira:
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
int acha_Arquivo (char * caminho_Arq)
{
struct stat buf;
int i = stat ( caminho_Arq, &buf );
/* Arquivo encontrado */
if ( i == 0 )
{
return 1;
}
return 0;
}
int main(int argc,char** argv)
{
if (acha_Arquivo("C:/agata/php/php.exe")==0)
{
printf("PHP não instalado");
return 1;
}
char caminho_Rel[300]="php.exe C:/SistemasQT/vendas_QTCreator/vendas/relatorios/cidades_p.php ";
if ( argc < 4 )
{
printf("Sem parametros para o relatóro");
return 1;
}
else
{
strcat(caminho_Rel,argv[1]);
strcat(caminho_Rel," ");
strcat(caminho_Rel,argv[2]);
strcat(caminho_Rel," ");
strcat(caminho_Rel ,argv[3]);
printf("Numero de parametros= %d\n",argc);
printf("%s\n",argv[1]);
printf("%s\n",argv[2]);
printf("%s\n",argv[3]);
printf("%s\n",caminho_Rel);
system(caminho_Rel);
}
return 0;
}
Para compilar, se você usou o mingw para compilar a Qt no Windows®, você tambem pode usa-lo para compilar este pequeno programa, basta entrar pelo prompt do DOS no diretório onde esta o fonte, no nosso caso eu nomei script.c, e digitar:gcc script.c -o script.exe.
Para editar o arquivo fonte eu usei o notpad++, tambem fiz um teste com o Code::Bloks, uma IDE open source para o mingw , assim que instalei ele já reconheceu o mingw e o tornou seu compilador default, para quem quiser é mais pratico do que a linha de comando.
Este pequeno programa em C fará o papel do batch file, sera chamado de dentro do aplicativo Qt, lembrando que no Linux não é necessario, pois o shell script é mais do que suficiente.
Você pode e deve alterar este programa C ao seu gosto, pois ele é básico e elementar.
Agora, vamos escrever o código para nosso aplicativo chamar estes scripts e passar a eles os parâmetros necessários ao relatório.
Abra novamente no Kdevelop os arquivos fAnt_rel_Agata.h e fAnt_rel_Agata.cpp para criarmos uma função que ira chamar nosso script.
No fAnt_rel_Agata.h coloque as seguintes linhas abaixo da declaração public:
private:
QButtonGroup* radio_Grupo_Ordem;
QButtonGroup* radio_grupo_Formato;
QProcess* chama_Agata;
private slots:
gera_rel_Agata();
O arquivo ficara assim:
#ifndef FANT_REL_AGATA_H
#define FANT_REL_AGATA_H
#include <ui_fAnt_rel_Agata_Parent.h>//Para herdar da classe gerada pelo uic a partir do projeto do QTDesigner
class Qprocess;
class QFile;
class QButtonGroup;
class fAnt_rel_Agata: public QWidget,private Ui::fAnt_rel_Agata_Parent//Este é o nome da classe gerada pelo uic, se quiser abra o arquivo ui_fAnt_rel_Agata_Parent.h e no fina do arquivo encontrara a definição do namespace Ui
{
Q_OBJECT
public:
fAnt_rel_Agata(QWidget *parent = 0, const char *name = 0);
~fAnt_rel_Agata();
private:
QButtonGroup* radio_Grupo_Ordem;
QButtonGroup* radio_grupo_Formato;
QProcess* chama_Agata;
QFile* arquivo;
private slots:
void gera_rel_Agata();
};
#endif
Agora vá no fAnt_rel_Agata.cpp e no constructor iremos criar dois objetos da classe QbuttonGroup para agruparmos os RadioButtons que criamos, para que eles possam trabalhar em conjunto:
radio_Grupo_Ordem=new QButtonGroup(this);//cria o QButtonGroup
radio_Grupo_Ordem->setExclusive(true);//clicou em um, desmarcou o outro
radio_Grupo_Ordem->addButton(botao_Codigo);//adiciona o RadioButton ao QbuttonGroup
radio_Grupo_Ordem->setId(botao_Codigo,0);// indice do RadioButton dentro do QbuttonGroup
radio_Grupo_Ordem->addButton(botao_Nome);
radio_Grupo_Ordem->setId(botao_Nome,1);
radio_grupo_Formato=new QButtonGroup(this);
radio_grupo_Formato->setExclusive(true);
radio_grupo_Formato->addButton(botao_PDF);
radio_grupo_Formato->setId(botao_PDF,0);
radio_grupo_Formato->addButton(botao_SXW);
radio_grupo_Formato->setId(botao_SXW,1);
radio_grupo_Formato->addButton(botao_HTML);
radio_grupo_Formato->setId(botao_HTML,2);
radio_grupo_Formato->addButton(botao_TXT);
radio_grupo_Formato->setId(botao_TXT,3);
connect(botao_Imprimir,SIGNAL(clicked()),this,SLOT(gera_rel_Agata()));//para conectar a funçaõ ao botão
chama_Agata = new QProcess(this);//para criar o objeto Qprocess
arquivo=new QFile(this);
Não se esqueca de destruir todos os objetos alocados dinamicamente:
fAnt_rel_Agata::~fAnt_rel_Agata()
{
delete chama_Agata;
delete radio_Grupo_Ordem;
delete radio_grupo_Formato;
delete arquivo;
}
Finalmente chegamos ao ponto crucial da integração do Agata ao nosso aplicativo, criar um código que ira chamar os scripts que criamos e gerar nosso relatório. Antes disso, inclua as seguintes linhas no arquivo config.txt:
[caminhos]
relatorios = /home/rodolfo/sistemaqt/relatorios
pdf = /home/rodolfo/reader7.0.9/bin/acroread
swx = /usr/bin/broffice -writer
txt = /usr/bin/kwrite
html = /usr/bin/iceweasel
Ele ficara assim:
[banco]
database = QPSQL
hostname = localhost
databasename = projetoqt
[caminhos]
relatorios = /home/rodolfo/sistemaqt/relatorios
pdf = /home/rodolfo/reader7.0.9/bin/acroread
swx = /usr/bin/broffice -writer
txt = /usr/bin/kwrite
html = /usr/bin/iceweasel
Vá agora ao final do arquivo para declararmos a função que ira gerar o relatório, vou comentar o código para que você entenda.
void fAnt_rel_Agata::gera_rel_Agata()
{
QString arq_Modelo,arq_Saida,form_Arq,ext_Arq;
QString caminho_Relatorios;
QString aplicativo_Saida;
//O codigo ira montar algumas strings para passar como parametro.
QString caminho=QCoreApplication::applicationDirPath();//Acha o caminho do binario, no mesmo diretório esta o arquivo config.txt
caminho.append("/config.txt");
QSettings settings(caminho,QSettings::IniFormat);//abre o arquivo de configuração.
caminho_Relatorios=settings.value("caminhos/relatorios").toString();//pega o caminho dos relatorios
switch (radio_grupo_Formato->checkedId())//testa o formato do relatório
{
case 0:
{
aplicativo_Saida=settings.value("caminhos/pdf").toString();
form_Arq="pdf";
ext_Arq="pdf";
break;
}
case 1:
{
aplicativo_Saida=settings.value("caminhos/swx").toString();
form_Arq="swx";
ext_Arq="SWX";
break;
}
case 2:
{
aplicativo_Saida=settings.value("caminhos/html").toString();
form_Arq="html";
ext_Arq="HTML";
break;
}
case 3:
{
aplicativo_Saida=settings.value("caminhos/txt").toString();
form_Arq="txt";
ext_Arq="txt";
break;
}
}
QString arq_Antigo=caminho_Relatorios;//para excluir relatórios antigos
arq_Antigo.append("/clientes.");
arq_Antigo.append(ext_Arq);
if (arquivo->exists(arq_Antigo))
{
arq_Antigo.prepend("rm ");
chama_Agata->start(arq_Antigo);
chama_Agata->waitForFinished();
}
arq_Modelo=caminho_Relatorios;
if (radio_Grupo_Ordem->checkedId()==0)//testa se é por ordem de codigo ou nome
arq_Modelo.append("/clientes_Codigo.agt ");
else
arq_Modelo.append("/clientes_Nome.agt ");
// qDebug()<<arq_Modelo;
arq_Saida=caminho_Relatorios;//monta a string que representa o arquivo gerado
arq_Saida.append("/clientes.");
arq_Saida.append(ext_Arq);
QStringList a;
a<<arq_Modelo<<form_Arq<<arq_Saida;//esta stringlist é passada como parametro
QString retorno;
chama_Agata->start("/home/rodolfo/sistemaqt/relatorios/gera_Relatorio", a);//chama o shell script com as strings como parametros.
chama_Agata->waitForFinished();
retorno=chama_Agata->readAllStandardOutput();//retorna a linha do console
QMessageBox::information(0,"Relatório de clientes",retorno);
if (radio_grupo_Formato->checkedId()==2)//No Windows é preciso esta linha para o Firefox abrir o arquivo HTML, caso contrario ele tenta acessar a internet, no Linux é indiferente
arq_Saida.prepend("file:///");
QStringList saida;
saida<<arq_Saida;
chama_Agata->start(aplicativo_Saida,saida);//para cada formato de arquivo, pdf, html, txt etc, o arquivo config.txt tem de ter o aplicativo correspondente que ira abrir o arquivo.
}
Clique aqui para ver o arqivo fAnt_rel_Agata.cpp completo.
Compile e teste, você terá um aplicativo Qt com capacidade de emissão de relatórios em vários formatos e ainda multi plataforma, você pode recompilar no Windows® e tera o mesmo aplicativo nos dois sistemas operacionais.
Obs: Baixe aqui os fontes do aplicativo.
Abaixo, os relatórios prontos em pdf e html:
Abaixo, tela de retorno do console.(Clique na imagem para ampliar).
>
Abaixo, relatório PDF.(Clique na imagem para ampliar).
>
Abaixo, relatório HTML.(Clique na imagem para ampliar).
>
Gostou deste tutorial?, ele foi útil para você, no seu trabalho ou nos seus estudos? De a sua opinião:
Tutorial anterior:Criando um relatório para o aplicativo com o Kugar
Próximo Tutorial: Integrando o openRPT a um aplicativo Qt