main.cpp: #include #include "cadastro.h" #include //Para a função "centralizarWidget" #include //Para abrirmos um arquivo texto. #include //Para dialogos de menssagem. #include //Para conexão ao banco. #include //Para o locale #include //esta função centraliza o widget na tela void centralizarWidget(QWidget *widget) { QRect rect = QApplication::desktop()->availableGeometry(widget); widget->move(rect.center() - widget->rect().center()); } int main( int argc, char ** argv ) { QTextCodec::setCodecForTr(QTextCodec:: codecForName ( "UTF-8"));//Para locale QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); QApplication a( argc, argv ); QString caminho=QCoreApplication::applicationDirPath();//Acha o caminho do binario, no mesmo diretório esta o arquivo config.txt caminho.append("/config.txt"); QString database,host,databasename,linha;//Estas três variaveis são os parâmetros da conexão QSettings settings(caminho,QSettings::IniFormat);//Abre o arquivo de configuração database=settings.value("banco/database").toString(); host=settings.value("banco/hostname").toString(); databasename=settings.value("banco/databasename").toString(); if (database=="" || host=="" || databasename=="") { QMessageBox::information(0,"Iniciando o Sistema","Não foi possivel ler o arquivo de configuração"); return 1; } else { QSqlDatabase db = QSqlDatabase::addDatabase(database);//Instacia a conexão com os parametros. db.setHostName(host); db.setDatabaseName(databasename); db.setUserName("rodolfo"); db.setPassword("%Zh*#u");//Coloque aqui seu password bool ok = db.open(); if (ok) { //Aqui vamos instanciar nossa classe de trabalho, que herda da classe gerada a partir da classe gerada pelo uic, baseada na janela que fizemos no QTDesigner fCad_Clientes * mw = new fCad_Clientes(); //Chama a função que centraliza na tela. centralizarWidget(mw); //Abre o cadastro mw->show(); } else { if (db.lastError().isValid()) QMessageBox::critical(0,"Sistema teste",db.lastError().text(),QMessageBox::Cancel); QMessageBox::information(0,"Iniciando o Sistema","Não foi possivel conectar-se ao banco de dados!"); return 1; } } return a.exec(); } cadastro.h: #ifndef CADASTRO_H #define CADASTRO_H #include //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. QSqlQueryModel* model_Clientes;//Um grid para mostrar os dados QFile* arquivo; //Para gerar o arquivo do relatório. //Para charmar o Kugar e verificar a existencia 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(); void gera_Relatorio_openRPT(); protected: class fAnt_rel_Agata* fAnt_Agata; class fAntRelOpenRPT* fAnt_openRPT; }; #endif cadastro.cpp: #include "cadastro.h" #include //Biblioteca dos componentes de acesso a tabelas no banco via SQL. #include //Para o "grid" #include // Para gerar o relatório. #include //Para chamar o Kugar #include //Para escrever no arquivo #include "fAnt_rel_Agata.h" #include "fAntRelOpenRPT.h" fCad_Clientes::fCad_Clientes(QWidget *parent, const char *name) { setupUi(this); this->setAttribute(Qt::WA_DeleteOnClose,true);//Para a janela se auto-destruir; //Conecta nossas funções aos botões. connect(botao_Incluir,SIGNAL(clicked()),this,SLOT(grava_na_Tabela())); connect(botao_Alterar,SIGNAL(clicked()),this,SLOT(altera_na_Tabela())); connect(botao_Excluir,SIGNAL(clicked()),this,SLOT(exclui_na_Tabela())); connect(botao_limpar_Tela,SIGNAL(clicked()),this,SLOT(limpa_Tela())); connect(botao_Agata,SIGNAL(clicked()),this,SLOT(gera_Relatorio_Agata())); connect(botao_openRPT,SIGNAL(clicked()),this,SLOT(gera_Relatorio_openRPT())); query_Clientes=new QSqlQuery; //Associa uma consulta a tabela ao grid de dados model_Clientes=new QSqlQueryModel(this); model_Clientes->setQuery("select * from clientes order by codigo"); model_Clientes->setHeaderData(0, Qt::Horizontal, tr("Codigo")); model_Clientes->setHeaderData(1, Qt::Horizontal, tr("Nome")); tableView_Clientes->setModel(model_Clientes); tableView_Clientes->setColumnWidth(0,60); tableView_Clientes->setColumnWidth(1,270); tableView_Clientes->show(); edit_Codigo->setFocus(); arquivo=new QFile(this); chama_Kugar=new QProcess(this); exclui_Arquivo=new QProcess(this); cria_Arquivo=new QProcess(this); connect(botao_Relatorio,SIGNAL(clicked()),this,SLOT(gera_Relatorio())); } fCad_Clientes::~fCad_Clientes() { delete query_Clientes; delete model_Clientes; delete chama_Kugar; delete exclui_Arquivo; delete cria_Arquivo; delete arquivo; } void fCad_Clientes::grava_na_Tabela() { //Aqui é auto evidente o que o codigo faz, grava na tabela. query_Clientes->prepare(" insert into clientes (codigo,nome) values (:cod,:nom) "); query_Clientes->bindValue(":cod", edit_Codigo->text());//Parâmetros. query_Clientes->bindValue(":nom", edit_Nome->text()); query_Clientes->exec(); model_Clientes->setQuery("select * from clientes order by codigo");//Atualiza o grid tableView_Clientes->show(); limpa_Tela(); } void fCad_Clientes::altera_na_Tabela() { //Idem ao gravar query_Clientes->prepare(" update clientes set nome=:nom where codigo=:cod "); query_Clientes->bindValue(":cod", edit_Codigo->text()); query_Clientes->bindValue(":nom", edit_Nome->text()); query_Clientes->exec(); model_Clientes->setQuery("select * from clientes order by codigo"); tableView_Clientes->show(); limpa_Tela(); } void fCad_Clientes::exclui_na_Tabela() { //Idem ao gravar query_Clientes->prepare(" delete from clientes where codigo=:cod "); query_Clientes->bindValue(":cod", edit_Codigo->text()); query_Clientes->exec(); model_Clientes->setQuery("select * from clientes order by codigo"); tableView_Clientes->show(); limpa_Tela(); } void fCad_Clientes::limpa_Tela() { //Limpa os campos de edição. edit_Codigo->clear(); edit_Nome->clear(); edit_Codigo->setFocus(); } void fCad_Clientes::gera_Relatorio() { //Verifica a existencia de arquivos anteriores, se não, cria um novo arquivo de dados vazio. if (arquivo->exists("/home/rodolfo/sistemaqt/relatorios/relatorio_clientes.kdf")) { exclui_Arquivo->start("rm /home/rodolfo/sistemaqt/relatorios/relatorio_clientes.kdf"); exclui_Arquivo->waitForFinished(); cria_Arquivo->start("/usr/bin/touch /home/rodolfo/sistemaqt/relatorios/relatorio_clientes.kdf"); cria_Arquivo->waitForFinished(); } else { cria_Arquivo->start("/usr/bin/touch /home/rodolfo/sistemaqt/relatorios/relatorio_clientes.kdf"); cria_Arquivo->waitForFinished(); } QSqlQuery* query_rel=new QSqlQuery;// A query do relatório query_rel->exec(" select * from clientes order by nome"); //Seta o objeto arquivo para o arquivo no disco e escreve nele. arquivo->setFileName("/home/rodolfo/sistemaqt/relatorios/relatorio_clientes.kdf"); if (arquivo->open(QIODevice::WriteOnly | QIODevice::Text)) { //Aqui é de acordo com o DTD do Kugar. QTextStream out(arquivo); out <<""<<"\n"; out <<"\n"; out <<""<<"\n"; out <<" "<<"\n"; out <<"\n"; out <<" "<<"\n"; out <<" "<<"\n"; out <<"]>"<<"\n"; out <<"\n"; out <<""<<"\n"; while (query_rel->next()) { out <<""<<"\n"; } out <<""<<"\n"; //Aqui chama o Kugar para mostrar o relatório. chama_Kugar->start("kugar /home/rodolfo/sistemaqt/relatorios/relatorio_clientes.kdf"); } delete query_rel; } void fCad_Clientes::gera_Relatorio_Agata() { fAnt_Agata=new fAnt_rel_Agata(this); fAnt_Agata->show(); } void fCad_Clientes::gera_Relatorio_openRPT() { fAnt_openRPT=new fAntRelOpenRPT(this); fAnt_openRPT->show(); } fAnt_rel_Agata.h: #ifndef FANT_REL_AGATA_H #define FANT_REL_AGATA_H #include //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 fAnt_rel_Agata.cpp: #include "fAnt_rel_Agata.h" #include #include #include #include #include #include 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. 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); } fAnt_rel_Agata::~fAnt_rel_Agata() { delete chama_Agata; delete radio_Grupo_Ordem; delete radio_grupo_Formato; delete arquivo; } 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()<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<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. } fAntRelOpenRPT.h #ifndef FANTRELOPENRPT_H #define FANTRELOPENRPT_H #include "ui_fAntRelOpenRPT_Parent.h" class QProcess; class QFile; class QButtonGroup; class QSqlQuery; class QComboBox; class fAntRelOpenRPT:public QWidget,private Ui::fAntRelOpenRPT_Parent { Q_OBJECT public: fAntRelOpenRPT(QWidget* parent=0); ~fAntRelOpenRPT(); private: QButtonGroup* radio_Grupo_Ordem;//Para ordenar a consulta ao banco QButtonGroup* radio_grupo_Formato;//Para escolher entre o formato default e PDF QProcess* chama_openRPT;//Para chamar o rptRender QFile* arq_Anterior;//Para excluir arquivos antigos. QComboBox* combo_codigo_Clientes;//Para filtrar o relatório por cliente. QSqlQuery* query_Clientes; private slots: void gera_rel_openRPT();//Para gerar o relatório, passar os parâmetros. void trava_libera_filtro(); }; #endif fAntRelOpenRPT.cpp #include "fAntRelOpenRPT.h" #include #include #include #include #include #include #include #include fAntRelOpenRPT::fAntRelOpenRPT(QWidget* parent) { 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. 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);//Para escolher o formato, se PDF ou default. radio_grupo_Formato->setExclusive(true); radio_grupo_Formato->addButton(botao_Default); radio_grupo_Formato->setId(botao_Default,0); radio_grupo_Formato->addButton(botao_PDF); radio_grupo_Formato->setId(botao_PDF,1); connect(botao_Imprimir,SIGNAL(clicked()),this,SLOT(gera_rel_openRPT())); chama_openRPT = new QProcess(this);//para criar o objeto Qprocess arq_Anterior=new QFile(this); combo_codigo_Clientes=new QComboBox(this);//Cria e preenche o combobox com os valores do campo nome da tabela clientes no banco de dados, cria um segundo combo não visivel com os codigos. combo_codigo_Clientes->setVisible(false); query_Clientes=new QSqlQuery; query_Clientes->exec("select codigo,nome from clientes order by nome"); while (query_Clientes->next()) { combo_Clientes->addItem(query_Clientes->value(1).toString(),query_Clientes->value(1).toString()); combo_codigo_Clientes->addItem(query_Clientes->value(0).toString(),query_Clientes->value(0).toString()); } connect(check_Clientes,SIGNAL(stateChanged(int)),this,SLOT(trava_libera_filtro())); } fAntRelOpenRPT::~fAntRelOpenRPT() { delete chama_openRPT; delete radio_Grupo_Ordem; delete radio_grupo_Formato; delete arq_Anterior; } void fAntRelOpenRPT::gera_rel_openRPT() { QString arq_Modelo,arq_Saida,form_Arq,ext_Arq,nomeScript; QString hostname,databasename,user_Name,user_Password,arq_Antigo; QString openRPT,caminho_Relatorios,aplicativo_Saida; user_Name=QSqlDatabase::database().userName();//Para pegar o nome e a senha do usuario e passa-la ao openRPT para ele se conectar ao banco. user_Password=QSqlDatabase::database().password(); //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 hostname=settings.value("banco/hostname").toString(); databasename=settings.value("banco/databasename").toString(); arq_Antigo=caminho_Relatorios;//para excluir relatórios antigos if (radio_grupo_Formato->checkedId()==1)//testa o formato do relatório { aplicativo_Saida=settings.value("caminhos/pdf").toString(); form_Arq="pdf"; ext_Arq="pdf"; arq_Antigo.append("/clientes."); arq_Antigo.append(ext_Arq); if (arq_Anterior->exists(arq_Antigo)) { #ifdef Q_OS_UNIX//Para diferenciar Linux de Windows, shell script de batch do DOS. arq_Antigo.prepend("rm "); #endif #ifdef Q_OS_WIN arq_Antigo.prepend("del "); #endif chama_openRPT->start(arq_Antigo); chama_openRPT->waitForFinished(); } arq_Saida=caminho_Relatorios;//monta a string que representa o arquivo gerado arq_Saida.append("/clientes."); arq_Saida.append(ext_Arq); } arq_Modelo=caminho_Relatorios; if (check_Clientes->isChecked())//Testa se foi filtrado por cliente. { arq_Modelo.append("/clientes_filtrado.xml "); nomeScript=settings.value("scripts/openRPTfiltrado").toString(); } else { if (radio_Grupo_Ordem->checkedId()==0)//testa se é por ordem de codigo ou nome arq_Modelo.append("/clientes_codigo.xml "); else arq_Modelo.append("/clientes_nome.xml "); nomeScript=settings.value("scripts/openRPT").toString(); } //parametros openRPT QString host_banco; host_banco="-databaseURL=psql://"; host_banco.append(hostname); host_banco.append("/"); host_banco.append(databasename); host_banco.append(":5432 "); user_Name.prepend("-username="); user_Password.prepend(" -passwd="); QString pdf=""; QString tipo_Print=""; if (radio_grupo_Formato->checkedId()==1)//Se for escolhido pdf,cria o arquivo pdf, senão, chama o preview. { pdf=" -pdf -outpdf="; pdf.append(arq_Saida); } else tipo_Print=" -PrintPreview"; QString close=" -close "; QString parametro; if (check_Clientes->isChecked())//Se for filtrado, passa o codigo do cliente como parâmetro ao openRPT. { QString cod_Cliente; combo_codigo_Clientes->setCurrentIndex(combo_Clientes->currentIndex()); cod_Cliente=combo_codigo_Clientes->currentText(); parametro=" -param=cod_cli:int="; parametro.append(cod_Cliente); } else parametro=""; QStringList a; a<start(caminho_Relatorios, a); #endif #ifdef Q_OS_WIN //Se Windows,cria e chama o batch do DOS. openRPT=settings.value("caminhos/openRPT").toString(); QFile file(caminho_Relatorios); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return; QTextStream out(&file); out <start(caminho_Relatorios,argumento);//chama o batch, sem parametros, já que em um batch do DOS não se pode passar o caracter "=" como parâmetro,pois o DOS considera o "=" como delimitador. #endif chama_openRPT->waitForFinished(); retorno=chama_openRPT->readAllStandardOutput();//retorna a linha do console QMessageBox::information(0,"Relatório de clientes",retorno); if (radio_grupo_Formato->checkedId()==1) { QStringList saida; saida<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. } } void fAntRelOpenRPT::trava_libera_filtro() { if (check_Clientes->isChecked()) combo_Clientes->setEnabled(true); else combo_Clientes->setEnabled(false); }