Inicio.
O objetivo deste tutorial é demonstrar as técnicas básicas e essenciais para se desenvolver um aplicativo cliente/servidor em C++ Qt/Kdevelop, isto é, o aplicativo devera rodar em estações de uma rede intranet acessando um banco de dados no servidor desta mesma rede. Também é objetivo demonstrar o uso das ferramentas de forma integrada, ou seja, o Kdevelop como IDE que integra editor de programação, ferramentas de debug com gdb e Valgrind, compilador C++ GNU g++, GNU make e o Qmake.
Faço aqui uma observação sobre o uso do Kdevelop como IDE, pois é possível compilar diretamente um programa feito em Qt/C++ diretamente na linha de comando usando o Qmake e o g++, você teria de usar qualquer editor de texto e fazer tudo na mão, mas se busca produtividade e rapidez o Kdevelop segue o espírito "RAD" (Rapid Application Development ) como as conhecidas ferramentas de programação do sistema operacional concorrente, como o Delphi® ou VB®. Também é possível usar o Eclipse® da IBM® como IDE para Qt, mas esta opção eu nunca experimentei. Também estou direcionando este tutorial para quem é iniciante no Linux mas já tenha alguma experiência como programador, saiba C++ e SQL, ou seja, alguém que venha do mundo do sistema concorrente e já usava algumas das ferramentas citadas acima.
Mesmo este mínimo que aqui pretendo demonstrar as vezes é difícil para um iniciante encontrar na Internet ou em livros e apostilas, daí o objetivo deste pequeno tutorial. Nele serão descritos os passos básicos para se criar o aplicativo, que são: O Desenho da interface no Qt Designer, gerar uma classe "mãe" a partir desta interface usando o Qmake e o uic (User Interface Compiler) chamado a partir do Kdevelop, criar uma classe C++/Qt que será o principal do aplicativo em si, classe esta que herdara da classe mãe, criar uma tabela no banco de dados que no nosso caso sera o PostgreSql e depois fazer, a partir da estação, o nosso binário se conectar ao banco no servidor.
Estou usando o Kdevelop 3.3.5 e a versão 4.4.3 da biblioteca Qt, neste caso, temos de usar o Designer separado do Kdevelop, pois o Designer que vem integrado no Kdevelop 3.3.5 não "entende" a versão 4.4.3 da biblioteca, somente entende a versão 3.x.x, isto porque eu uso o Debian, escolha da qual eu não abro mão, se você usa alguma distribuição com KDE 4 que já venha com a Qt 4.x.x talvez sua versão do Kdevelop tenha o Designer atualizado para Qt 4.x.x e ai você poderá trabalhar com o Designer integrado ao Kdevelop mas, veja bem, este é um pequeno detalhe que não interfere em nada.
A biblioteca Qt pode ser obtida no site da Qt Software, no arquivo que você baixar terá as instruções de compilação, é importante você incluir a opção de acesso ao PostgreSql na compilação da biblioteca. Uma vez que seu computador esteja com tudo em ordem, Kdevelop instalado e Qt 4.4.3 compilada e instalada, podemos começar.
Obs: Baixe aqui os fontes do aplicativo.
Crie um diretório com o nome de "sistemaqt" no seu home e em seguida abra o QTDesigner:
Abaixo:QTDesigner.(Clique na imagem para ampliar).
>
Em seguida clique no botão Create no dialogo aberto ou se quiser pode fechar este dialogo e usar a opção file -> New... que o mesmo dialogo voltara a aparecer. Escolha a opção "Main Window" como na figura acima e clique no botão "Create". A seguinte tela ira aparecer, já com a janela principal ou "form", como queiram, criada:
Abaixo, QTdesiner + form.(Clique na imagem para ampliar).
>
Agora, re-dimensione a janela para as seguinte proporções(Width=480, Height=335), faça isto com o mouse ou use a janela “Property editor” a direita na tela, na opção geometry:
Abaixo, QTdesiner + Property Editor.(Clique na imagem para ampliar).
>
Agora, mude a opção “windowTitle” para “Cadastro de clientes” e, muito importante, a opção “windowModality” para “ApplicationModal”, isto fara com que qualquer janela aberta seqüestre a tela, não permitindo que outras janelas do aplicativo sejam abertas, mude a propriedade “objectName” para fCad_Clientes_Parent. Agora, clique com o botão direito do mouse sobre a nossa janela e escolha a opção “Remove Status Bar” para remover a barra de status, desnecessária em nossa aplicação. Depois vá até a barra superior de menus da nossa janela, novamente clique com o botão direito do mouse e escolha “Remove Menu Bar”, também desnecessária em nossa aplicação. Agora, salve a janela com o nome fClientes_Parent.ui, a extensão .ui o Designer deve colocar automaticamente, salve no diretório sistemaqt que nos criamos. Agora, na parte esquerda da janela do Designer esta o “Widget Box”, o menu de componentes da biblioteca Qt, escolha o componente “PushButton”, arraste até a parte superior esquerda da nossa janela, como na figura abaixo, e solte, no Designer você coloca componentes na janela arrastando e soltando e não clicando no componente e depois na janela. Coloque mais três PushButton ao lado do primeiro:
Abaixo, janela principal com botões.(Clique na imagem para ampliar).
>
Agora, em cada um dos botões você vai mudar as seguintes propriedades: “objectName”: Mude para botao_Incluir, botao_Alterar, botao_Excluir e botao_limpar_Tela, respectivamente, depois mude a propriedade “text” para &Incluir, &Alterar, &Excluir e &Limpar Tela, respectivamente, o caractere “&” (E comercial) é para se criar um atalho de teclado para o botão:
Abaixo, janela principal com botões e texto.(Clique na imagem para ampliar).
>
Se quiser, coloque ícones nos botões através da propriedade “icon”, só que você tera de criar um arquivo de recursos, um “Resource file” como é chamado em Qt, no Designer tem o “Resource Browser”, você copia os ícones do seu gosto para o diretório do projeto, cria o resource file através do “Resource Browser” e inclui seus ícones nele, depois pela propriedade “icon” do PushButton você acessa seus ícones, na documentação da Qt você encontrara explicações mais detalhadas:
Abaixo, janela principal com botões,texto e icones.(Clique na imagem para ampliar).
>
Agora vamos colocar os campos para edição da nossa tabela, do nosso cadastro de clientes, que sera o mais simples possível tendo apenas o código do cliente e o nome, lembrando que o objetivo deste tutorial e demonstrar o meio de se rodar um aplicativo em rede no linux. Coloque dois “lineEdit” que você encontra na aba “input Widgets” a esquerda no Designer, e para cada lineEdit coloque um “label”, conforme a figura abaixo:
Abaixo, janela principal com lineEdits e labels.(Clique na imagem para ampliar).
>
No Label, mude a propriedade "text" para Código e Nome, respectivamente , e nos lineEdit mude a propriedade "objectName" para edit_Codigo e edit_Nome, respectivamente. Em seguida você ira colocar um "tableView" logo abaixo dos lineEdits, que servira como um "grid" para exibição de dados, como mostra a figura abaixo, ele é encontrado na aba "item Views (Model-Based)", de a ele o nome("objectName") de "tableView_Clientes", ao colocar o tableView na janela, redimensione-a ao seu gosto:
Abaixo, janela principal com tableView.(Clique na imagem para ampliar).
>
Para finalizar esta etapa, salve tudo novamente. Abra o Kdevelop:
Abaixo, janela principal do Kdevelop.(Clique na imagem para ampliar).
>
Vá até o menu projeto e escolha a opção "Novo projeto...", em seguida ira aparecer uma caixa de dialogo com as opções para o seu projeto:
Abaixo, janela novo projeto.(Clique na imagem para ampliar).
>
Escolha a opção "C++" e em seguida a opção "Qmake project" e em seguida a opção "Aplicação" como na imagem abaixo:
Abaixo, janela Qmake project.(Clique na imagem para ampliar).
>
No campo Nome do aplicativo coloque "cadastro" e em localização coloque o diretório sistemaqt que nos criamo e clique em Próximo. na próxima tela você não precisa fazer nada:
Abaixo, opções do projeto.(Clique na imagem para ampliar).
>
Clique novamente em próximo e sera pedido o sistema de controle de versão, no nosso caso deixe sem nenhum:
Abaixo, controle de versão.(Clique na imagem para ampliar).
>
As duas próximas telas são somente informativas:
Abaixo, modelo do cabeçaho (*.h).(Clique na imagem para ampliar).
>
Abaixo, modelo do corpo (*.cpp).(Clique na imagem para ampliar).
>
Clique em finalizar e então poderemos começar a programar:
Abaixo, kdevelop com programa modelo.(Clique na imagem para ampliar).
>
Esta tela é um modelo padrão de um editor de texto em Qt, é muito interessante como aprendizado, posteriormente você pode realizar todos estes passos novamente e compilar este programa a título de aprendizado, análise o seu código fonte com cuidado. Mas agora nós iremos apagar tudo que o Kdevelop colocou nos arquivo cadastro.h, cadastro.cpp e main.cpp e iremos colocar o nosso código fonte do cadastro de clientes. Vá até a aba seletor de arquivos a direita e clique, a seguinte janela ira aparecer:
Abaixo, Kdevelop com seletor de arquivos aberto.(Clique na imagem para ampliar).
>
De um clique duplo no diretório src novamente um clique duplo nos seguintes arquivos:cadastro.h e main.cpp e src.pro e depois feche o seletor de arquivos:
Abaixo, todos arquivos abertos.(Clique na imagem para ampliar).
>
O arquivo src.pro deve estar assim:
Agora você vai até o diretório sistemaqt que nos criamos, dentro dele o Kdevelop criou uma serie de novos diretórios, você vai copiar os seguintes arquivos para o diretório /src dentro de /sistemasqt: fClientes_Parent.ui, icones.qrc(que nada mais é que o arquivo que nos criamos no QTDesigner para ser o nosso container de ícones, no caso eu dei o nome de icones.qrc) e os ícones que você escolheu. Abaixo a estrutura de diretórios que o Kdevelop criou dentro do diretório /sistemasqt:
Abaixo, estrutura de diretórios dentro do diretório do projeto.(Clique na imagem para ampliar).
>
Depois que copiar os arquivos para diretório /sistemaqt/cadastro/src (fizemos isto para que o Kdevelop possa localizar os arquivos), volte ao src.pro e faça as seguintes modificações:
Note que incluímos as seguintes linhas:
A primeira é a que instrui o Kdevelop a chamar o uic para, a partir do arquivo do QTDesigner, fClientes_Parent.ui, que nada mais é do que um arquivo XML com as coordenadas dos componentes na tela e mais algumas especificações, gerar uma classe C++/Qt a partir deste arquivo. A segunda Qt += sql instrui o Qmake a trabalhar com SQL e a terceira, RESOURCES += icones.qrc , informa qual é o arquivo de recursos. Vamos compilar digitando a tecla F8, preste atenção se a janela de mensagens embaixo do Kdevelop escreveu o seguinte:
"gerando ui_fClientes_Parent.h (uic)" :
>
Pronto, a partir de agora já temos a nossa classe mãe ,ui_fClientes_Parent.h, ele não gera um arquivo .cpp, só o .h. Agora vamos limpar main.cpp, cadastro.cpp e cadastro.h e colocar no lugar o nosso código. A partir de agora eu vou comentar o código relativo a acesso a banco de dados e SQL, não vou comentar o básico da biblioteca Qt porque não é esse o objetivo deste tutorial. Primeiro, vamos a main.cpp:
Agora, vá até cadastro.h:
Vá até cadastro.cpp:
Agora, você pode compilar com F8, só para ver a tela que criamos aberta:
Abaixo, Kdevelop rodando o aplicativo.(Clique na imagem para ampliar).
>
Por enquanto o programa é só uma casca vazia de botões sem função, então vamos dar vida a ele. Agora vamos criar nossa tabela no PostgreSql, se quiser testar com outro banco(Mysql, Firebird etc) fique a vontade. Existem varias ferramentas graficas para gerenciar o Postgre, entre elas o Pgadmin, o Tora que é voltado para Oracle mas tambem serve para o Postgre e tambem o psql que funciona no terminal , eu costumo usar o psql para tudo que eu tenho de criar, como tabelas, indices, restrições etc e o Pgadmin só para consultar as tabelas. No caso do Postgre preste atenção nestes dois arquivos: /etc/postgresql/8.1/main/pg_hba.conf onde você controla a autenticação de clientes, abaixo a parte do meu arquivo que autentica clientes na rede 192.168.2.0
/etc/postgresql/8.1/main/postgresql.conf, neste você deve prestar atenção a dois parametros:
listen_addresses = '*' ( Especifica o endereço, ou endereços, de TCP/IP onde o servidor atende as conexões dos aplicativos cliente.). Isto eu copiei da documentação do Postgre.
port = 5432 ( A porta TCP onde o servidor esta atendendo; 5432 por padrão. Deve ser observado que é utilizada a mesma porta em todos os endereços de IP onde o servidor atende. Somente pode ser definido na inicialização do servidor.). Copiado da documentação.
Crie um banco de dados chamado "projetoqt" no postgre, depois, dentro do banco "projetoqt" crie uma tabela chamada clientes:
Abaixo,psql no terminal.(Clique na imagem para ampliar).
>
A tabela clientes vista pelo Pgadmin:
>
A tabela clientes vista pelo Tora:
>
Agora, voltemos ao Kdevelop e ao main.cpp:
Vamos a parte dos includes e incluir algumas bibliotecas:
#include <QSettings>//Para abrirmos um arquivo texto.
#include <QMessageBox>//Para dialogos de menssagem.
#include <QSqlDatabase>//Para conexão ao banco.
#include <QDesktopWidget>//Para a função "centralizarWidget"
Vamos criar um arquivo texto no diretório /bin do nosso projeto, onde esta o binario, com a seguinte estrutura:
[banco]
database = QPSQL
hostname = localhost
databasename = projetoqt
Nomei-o de config.txt, ele servira para passar os parâmetros da conexão ao aplicativo em diferentes lugares da rede. O main.cpp ficara assim:
Olhe no apêndice B no final do tutorial um algoritmo alternativo para main.cpp
Daqui em diante entraremos na parte de manipulação dos dados, portanto eu não vou explicar os mecanismos basicos da Qt, como Signals/Slots, que podem ser estudados na documentação. Agora, vamos ao cadastro.h:
Agora, o principal do aplicativo, cadastro.cpp:
Compile com F8 e rode com <shift>F9, deve aparecer assim:
>
Se você esta em uma rede, já deve ter criado o banco no servidor, no meu caso eu tenho duas maquinas, a que é o servidor é a minha maquina de trabalho mesmo, depois tenho outra maquina para testes, onde texto o desempenho em rede, localmente o parâmetro é db.setHostName("localhost"), o host do meu servidor é "Programador", portanto na estação eu crio um diretório onde coloco o binario e o arquivo config.txt com a seguinte configuração:
database = "QPSQL"
hostname = "Programador"
databasename = "projetoqt"
Resumindo, para o sistema rodar a partir de uma estação da rede, crie um diretório para ele, copie o binário, o arquivo config.txt , dentro do diretório do binário crie outro diretório chamado "sqldrivers" este é importante , é onde vai o driver do Postgre, e o nome deve ser este mesmo "sqldrivers", não pode ser outro, copie para ele o driver do Postgre, cujo nome é "libqsqlpsql.so" e pode ser encontrado no diretório /usr/local/Trolltech/Qt-4.4.3/plugins/sqldrivers/, se tudo estiver correto, o sistema vai rodar perfeitamente, abaixo a imagem da configuração dos arquivos na estação e o aplicativo rodando na estação:
>
Abaixo, o aplicativo rodando na estação.
>
Espero ter demonstrado os princípios básicos para se construir um aplicativo cliente/servidor no Linux, tão fácil como em qualquer outra plataforma ou qualquer outra ferramenta RAD, é claro que este pequeno programa que fizemos não é comercial do ponto de vista estético e funcional, não tem botões de navegação na tabela e outros recursos que eu uso normalmente, mas se fôssemos fazer como os sistemas que eu coloquei de exemplo aqui no site iríamos nos delongar além do necessário, e fica como um desafio para quem estiver iniciando na programação para Linux melhorar este pequeno aplicativo. Fica aqui um comentário de quem programou em Delphi® por 10 anos seguidos, C++ é mais abstrato, permite coisas inimaginaveis em Pascal, como sobrecarga de operadores, declarar duas funções diferentes com o mesmo nome, namespaces etc, portanto é mais flexível, é uma linguagem de programação incomparável e também te obriga a ter um conhecimento maior de orientação a objetos e classes do que no Delphi®, que é completamente automatizado.
Finalizando, acho que já esta mais do que na hora do Linux entrar com tudo no desktop, as ferramentas hoje disponíveis para desenvolvimento de sistemas não ficam nada a dever para as da plataforma concorrente em termos de produtividade, rapidez e eficiência e no final você tera aplicativos rodando em uma plataforma mais estável e segura.
Obs: Baixe aqui os fontes do aplicativo.
Integrados ao Kdevelop temos duas excelentes ferramentas de debug e verificação de erros, o gdb e o Valgrind. gdb
O gdb é o GNU Debugger, ferramenta para se rodar o programa passo a passo, monitorar e alterar valores de variáveis internas do programa durante a execução, alterar funções de forma independente do fluxo do programa. O gdb não tem interface gráfica própria, ele pode ser utilizado no terminal para debugar qualquer programa c ou C++:
Exemplo:
Compile com a opção -g no gcc ou g++
$> gcc -g -o prog prog.c
$> gdb prog
(gdb) run
(gdb) print, break, step, list, info, set, next, delete
Felizmente, existem interfaces gráficas para o gdb e também o Kdevelop o integra em sua IDE. Para usar o gdb em um aplicativo Qt você deve colocar o seguinte parâmetro no arquivo src.pro:
Onde esta CONFIG += release \ troque pro: CONFIG += debug \ , isto é fundamental para que o compilador coloque "marcas" internamente ao código gerado para servir de guia ao gdb. após feito isso compile novamente o aplicativo.
Você pode usar o Kdbg, uma interface gráfica do KDE para o gdb. no terminal digite kdgb, abra o binário, coloque os pontos de parada ou breakpoints e faça o kdgb iniciar o aplicativo, ele vai parar a execução no primeiro ponto de parada e você pode executar passo a passo, verificando valores de variáveis e descobrindo linha do fonte onde ocorrem erros, na figura abaixo, nosso aplicativo "cadastro" rodando a partir do kdbg com as janelas "locals" e "registers", abertas, e mostrando respectivamente o valor das variáveis e o conteúdo dos registradores , também se vê o breakpoint no main.cpp. O kdbg e bastante intuitivo e fácil de usar, na sua barra de ferramentas principal estão os botões para avançar passo a passo no fonte.
>
Agora vamos ver o gdb integrado ao Kdevelop, o processo é parecido com o kdbg:
>
Pessoalmente, quando preciso de uma analise mais completa prefiro o kdbg pois acho a integração do gdb ao Kdevelop um pouco confusa, algumas variáveis não mostram o seu valor, coisa que não acontece no kdgb, porem, para analises mais simples, o gdb integrado ao kdevelop é suficiente.
Ferramentas para identificar problemas com threads, alocação e desalocação de memória incorretas, acessos em áreas invalidas, memory leaks etc.
Normalmente eu uso mais o Valgrind do que o gdb, vazamentos de memória são mais difíceis de localizar, são erros sutis e as vezes insidiosos que transformam o seu programa em uma bomba relógio, um erro que pode ser localizado pelo gdb geralmente é um erro que interrompe a execução do programa, ao passo que um memory leak pode passar despercebido por muito tempo, o programa roda normalmente. O Valgrind pode ser rodado no terminal, sua saída é simples, no caso do nosso aplicativo, você pode fazer:
rodolfo@Programador:~$ cd /home/rodolfo/sistemaqt/cadastro/bin/
rodolfo@Programador:~/sistemaqt/cadastro/bin$ valgrind ./cadastro
Você tera a seguinte saida:
>
O Valgrind é melhor integrado ao Kdevelop do que o gdb, portanto você pode usa-lo a partir do Kdevelop sem nenhum problema, use o menu depurar do Kdevelop, escolha a opção "Verificação de falta de memória doValgrind":
>
Saida do Valgrind no Kdevelop:
>
Operações de abertura, leitura e escrita em arquivos são muito comuns em programação, se você for programar em C++ "puro" para linha de comando você pode usar o Kdevelop mas não pode depender da Qt, por isso coloquei aqui uma versão alternativa do algortimo de abertura e leitura do arquivo "config.txt" feito em C++ que faz o mesmo que o primeiro sem depender de nada a não ser as libs do C++.
Tutorial anterior: Introdução a construção(building) de um aplicativo Qt
Próximo Tutorial: Criando um relatório para o aplicativo com o Kugar
Faço aqui uma observação sobre o uso do Kdevelop como IDE, pois é possível compilar diretamente um programa feito em Qt/C++ diretamente na linha de comando usando o Qmake e o g++, você teria de usar qualquer editor de texto e fazer tudo na mão, mas se busca produtividade e rapidez o Kdevelop segue o espírito "RAD" (Rapid Application Development ) como as conhecidas ferramentas de programação do sistema operacional concorrente, como o Delphi® ou VB®. Também é possível usar o Eclipse® da IBM® como IDE para Qt, mas esta opção eu nunca experimentei. Também estou direcionando este tutorial para quem é iniciante no Linux mas já tenha alguma experiência como programador, saiba C++ e SQL, ou seja, alguém que venha do mundo do sistema concorrente e já usava algumas das ferramentas citadas acima.
Mesmo este mínimo que aqui pretendo demonstrar as vezes é difícil para um iniciante encontrar na Internet ou em livros e apostilas, daí o objetivo deste pequeno tutorial. Nele serão descritos os passos básicos para se criar o aplicativo, que são: O Desenho da interface no Qt Designer, gerar uma classe "mãe" a partir desta interface usando o Qmake e o uic (User Interface Compiler) chamado a partir do Kdevelop, criar uma classe C++/Qt que será o principal do aplicativo em si, classe esta que herdara da classe mãe, criar uma tabela no banco de dados que no nosso caso sera o PostgreSql e depois fazer, a partir da estação, o nosso binário se conectar ao banco no servidor.
Estou usando o Kdevelop 3.3.5 e a versão 4.4.3 da biblioteca Qt, neste caso, temos de usar o Designer separado do Kdevelop, pois o Designer que vem integrado no Kdevelop 3.3.5 não "entende" a versão 4.4.3 da biblioteca, somente entende a versão 3.x.x, isto porque eu uso o Debian, escolha da qual eu não abro mão, se você usa alguma distribuição com KDE 4 que já venha com a Qt 4.x.x talvez sua versão do Kdevelop tenha o Designer atualizado para Qt 4.x.x e ai você poderá trabalhar com o Designer integrado ao Kdevelop mas, veja bem, este é um pequeno detalhe que não interfere em nada.
A biblioteca Qt pode ser obtida no site da Qt Software, no arquivo que você baixar terá as instruções de compilação, é importante você incluir a opção de acesso ao PostgreSql na compilação da biblioteca. Uma vez que seu computador esteja com tudo em ordem, Kdevelop instalado e Qt 4.4.3 compilada e instalada, podemos começar.
Obs: Baixe aqui os fontes do aplicativo.
Crie um diretório com o nome de "sistemaqt" no seu home e em seguida abra o QTDesigner:
Abaixo:QTDesigner.(Clique na imagem para ampliar).
>
Em seguida clique no botão Create no dialogo aberto ou se quiser pode fechar este dialogo e usar a opção file -> New... que o mesmo dialogo voltara a aparecer. Escolha a opção "Main Window" como na figura acima e clique no botão "Create". A seguinte tela ira aparecer, já com a janela principal ou "form", como queiram, criada:
Abaixo, QTdesiner + form.(Clique na imagem para ampliar).
>
Agora, re-dimensione a janela para as seguinte proporções(Width=480, Height=335), faça isto com o mouse ou use a janela “Property editor” a direita na tela, na opção geometry:
Abaixo, QTdesiner + Property Editor.(Clique na imagem para ampliar).
>
Agora, mude a opção “windowTitle” para “Cadastro de clientes” e, muito importante, a opção “windowModality” para “ApplicationModal”, isto fara com que qualquer janela aberta seqüestre a tela, não permitindo que outras janelas do aplicativo sejam abertas, mude a propriedade “objectName” para fCad_Clientes_Parent. Agora, clique com o botão direito do mouse sobre a nossa janela e escolha a opção “Remove Status Bar” para remover a barra de status, desnecessária em nossa aplicação. Depois vá até a barra superior de menus da nossa janela, novamente clique com o botão direito do mouse e escolha “Remove Menu Bar”, também desnecessária em nossa aplicação. Agora, salve a janela com o nome fClientes_Parent.ui, a extensão .ui o Designer deve colocar automaticamente, salve no diretório sistemaqt que nos criamos. Agora, na parte esquerda da janela do Designer esta o “Widget Box”, o menu de componentes da biblioteca Qt, escolha o componente “PushButton”, arraste até a parte superior esquerda da nossa janela, como na figura abaixo, e solte, no Designer você coloca componentes na janela arrastando e soltando e não clicando no componente e depois na janela. Coloque mais três PushButton ao lado do primeiro:
Abaixo, janela principal com botões.(Clique na imagem para ampliar).
>
Agora, em cada um dos botões você vai mudar as seguintes propriedades: “objectName”: Mude para botao_Incluir, botao_Alterar, botao_Excluir e botao_limpar_Tela, respectivamente, depois mude a propriedade “text” para &Incluir, &Alterar, &Excluir e &Limpar Tela, respectivamente, o caractere “&” (E comercial) é para se criar um atalho de teclado para o botão:
Abaixo, janela principal com botões e texto.(Clique na imagem para ampliar).
>
Se quiser, coloque ícones nos botões através da propriedade “icon”, só que você tera de criar um arquivo de recursos, um “Resource file” como é chamado em Qt, no Designer tem o “Resource Browser”, você copia os ícones do seu gosto para o diretório do projeto, cria o resource file através do “Resource Browser” e inclui seus ícones nele, depois pela propriedade “icon” do PushButton você acessa seus ícones, na documentação da Qt você encontrara explicações mais detalhadas:
Abaixo, janela principal com botões,texto e icones.(Clique na imagem para ampliar).
>
Agora vamos colocar os campos para edição da nossa tabela, do nosso cadastro de clientes, que sera o mais simples possível tendo apenas o código do cliente e o nome, lembrando que o objetivo deste tutorial e demonstrar o meio de se rodar um aplicativo em rede no linux. Coloque dois “lineEdit” que você encontra na aba “input Widgets” a esquerda no Designer, e para cada lineEdit coloque um “label”, conforme a figura abaixo:
Abaixo, janela principal com lineEdits e labels.(Clique na imagem para ampliar).
>
No Label, mude a propriedade "text" para Código e Nome, respectivamente , e nos lineEdit mude a propriedade "objectName" para edit_Codigo e edit_Nome, respectivamente. Em seguida você ira colocar um "tableView" logo abaixo dos lineEdits, que servira como um "grid" para exibição de dados, como mostra a figura abaixo, ele é encontrado na aba "item Views (Model-Based)", de a ele o nome("objectName") de "tableView_Clientes", ao colocar o tableView na janela, redimensione-a ao seu gosto:
Abaixo, janela principal com tableView.(Clique na imagem para ampliar).
>
Para finalizar esta etapa, salve tudo novamente. Abra o Kdevelop:
Abaixo, janela principal do Kdevelop.(Clique na imagem para ampliar).
>
Vá até o menu projeto e escolha a opção "Novo projeto...", em seguida ira aparecer uma caixa de dialogo com as opções para o seu projeto:
Abaixo, janela novo projeto.(Clique na imagem para ampliar).
>
Escolha a opção "C++" e em seguida a opção "Qmake project" e em seguida a opção "Aplicação" como na imagem abaixo:
Abaixo, janela Qmake project.(Clique na imagem para ampliar).
>
No campo Nome do aplicativo coloque "cadastro" e em localização coloque o diretório sistemaqt que nos criamo e clique em Próximo. na próxima tela você não precisa fazer nada:
Abaixo, opções do projeto.(Clique na imagem para ampliar).
>
Clique novamente em próximo e sera pedido o sistema de controle de versão, no nosso caso deixe sem nenhum:
Abaixo, controle de versão.(Clique na imagem para ampliar).
>
As duas próximas telas são somente informativas:
Abaixo, modelo do cabeçaho (*.h).(Clique na imagem para ampliar).
>
Abaixo, modelo do corpo (*.cpp).(Clique na imagem para ampliar).
>
Clique em finalizar e então poderemos começar a programar:
Abaixo, kdevelop com programa modelo.(Clique na imagem para ampliar).
>
Esta tela é um modelo padrão de um editor de texto em Qt, é muito interessante como aprendizado, posteriormente você pode realizar todos estes passos novamente e compilar este programa a título de aprendizado, análise o seu código fonte com cuidado. Mas agora nós iremos apagar tudo que o Kdevelop colocou nos arquivo cadastro.h, cadastro.cpp e main.cpp e iremos colocar o nosso código fonte do cadastro de clientes. Vá até a aba seletor de arquivos a direita e clique, a seguinte janela ira aparecer:
Abaixo, Kdevelop com seletor de arquivos aberto.(Clique na imagem para ampliar).
>
De um clique duplo no diretório src novamente um clique duplo nos seguintes arquivos:cadastro.h e main.cpp e src.pro e depois feche o seletor de arquivos:
Abaixo, todos arquivos abertos.(Clique na imagem para ampliar).
>
O arquivo src.pro deve estar assim:
SOURCES += cadastro.cpp \
main.cpp
HEADERS += cadastro.h
TEMPLATE = app
CONFIG += release \
warn_on \
thread \
qt
TARGET = ../bin/cadastroAgora você vai até o diretório sistemaqt que nos criamos, dentro dele o Kdevelop criou uma serie de novos diretórios, você vai copiar os seguintes arquivos para o diretório /src dentro de /sistemasqt: fClientes_Parent.ui, icones.qrc(que nada mais é que o arquivo que nos criamos no QTDesigner para ser o nosso container de ícones, no caso eu dei o nome de icones.qrc) e os ícones que você escolheu. Abaixo a estrutura de diretórios que o Kdevelop criou dentro do diretório /sistemasqt:
Abaixo, estrutura de diretórios dentro do diretório do projeto.(Clique na imagem para ampliar).
>
Depois que copiar os arquivos para diretório /sistemaqt/cadastro/src (fizemos isto para que o Kdevelop possa localizar os arquivos), volte ao src.pro e faça as seguintes modificações:
SOURCES += cadastro.cpp \ main.cpp HEADERS += cadastro.h TEMPLATE = app CONFIG += release \ warn_on \ thread \ qt TARGET = ../bin/cadastro QT += sql RESOURCES += icones.qrc
Note que incluímos as seguintes linhas:
FORMS += fClientes_Parent.ui QT += sql RESOURCES += icones.qrc
A primeira é a que instrui o Kdevelop a chamar o uic para, a partir do arquivo do QTDesigner, fClientes_Parent.ui, que nada mais é do que um arquivo XML com as coordenadas dos componentes na tela e mais algumas especificações, gerar uma classe C++/Qt a partir deste arquivo. A segunda Qt += sql instrui o Qmake a trabalhar com SQL e a terceira, RESOURCES += icones.qrc , informa qual é o arquivo de recursos. Vamos compilar digitando a tecla F8, preste atenção se a janela de mensagens embaixo do Kdevelop escreveu o seguinte:
"gerando ui_fClientes_Parent.h (uic)" :
>
Pronto, a partir de agora já temos a nossa classe mãe ,ui_fClientes_Parent.h, ele não gera um arquivo .cpp, só o .h. Agora vamos limpar main.cpp, cadastro.cpp e cadastro.h e colocar no lugar o nosso código. A partir de agora eu vou comentar o código relativo a acesso a banco de dados e SQL, não vou comentar o básico da biblioteca Qt porque não é esse o objetivo deste tutorial. Primeiro, vamos a main.cpp:
#include <QApplication>
#include "cadastro.h"
#include <QDesktopWidget>//Para a função "centralizarWidget"
//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 )
{
QApplication a( argc, argv );
//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();
return a.exec();
}
Agora, vá até cadastro.h:
#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 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();
};
Vá até cadastro.cpp:
#include "cadastro.h"
fCad_Clientes::fCad_Clientes(QWidget *parent, const char *name) { setupUi(this); } fCad_Clientes::~fCad_Clientes() { }
Agora, você pode compilar com F8, só para ver a tela que criamos aberta:
Abaixo, Kdevelop rodando o aplicativo.(Clique na imagem para ampliar).
>
Por enquanto o programa é só uma casca vazia de botões sem função, então vamos dar vida a ele. Agora vamos criar nossa tabela no PostgreSql, se quiser testar com outro banco(Mysql, Firebird etc) fique a vontade. Existem varias ferramentas graficas para gerenciar o Postgre, entre elas o Pgadmin, o Tora que é voltado para Oracle mas tambem serve para o Postgre e tambem o psql que funciona no terminal , eu costumo usar o psql para tudo que eu tenho de criar, como tabelas, indices, restrições etc e o Pgadmin só para consultar as tabelas. No caso do Postgre preste atenção nestes dois arquivos: /etc/postgresql/8.1/main/pg_hba.conf onde você controla a autenticação de clientes, abaixo a parte do meu arquivo que autentica clientes na rede 192.168.2.0
local all postgres ident sameuser host all all 192.168.2.0/24 ident sameuser
/etc/postgresql/8.1/main/postgresql.conf, neste você deve prestar atenção a dois parametros:
listen_addresses = '*' ( Especifica o endereço, ou endereços, de TCP/IP onde o servidor atende as conexões dos aplicativos cliente.). Isto eu copiei da documentação do Postgre.
port = 5432 ( A porta TCP onde o servidor esta atendendo; 5432 por padrão. Deve ser observado que é utilizada a mesma porta em todos os endereços de IP onde o servidor atende. Somente pode ser definido na inicialização do servidor.). Copiado da documentação.
Crie um banco de dados chamado "projetoqt" no postgre, depois, dentro do banco "projetoqt" crie uma tabela chamada clientes:
create table clientes( codigo int primary key, nome varchar(100) not null check (nome <> '') );
Abaixo,psql no terminal.(Clique na imagem para ampliar).
>
A tabela clientes vista pelo Pgadmin:
>
A tabela clientes vista pelo Tora:
>
Agora, voltemos ao Kdevelop e ao main.cpp:
Vamos a parte dos includes e incluir algumas bibliotecas:
#include <QSettings>//Para abrirmos um arquivo texto.
#include <QMessageBox>//Para dialogos de menssagem.
#include <QSqlDatabase>//Para conexão ao banco.
#include <QDesktopWidget>//Para a função "centralizarWidget"
Vamos criar um arquivo texto no diretório /bin do nosso projeto, onde esta o binario, com a seguinte estrutura:
[banco]
database = QPSQL
hostname = localhost
databasename = projetoqt
Nomei-o de config.txt, ele servira para passar os parâmetros da conexão ao aplicativo em diferentes lugares da rede. O main.cpp ficara assim:
#include <QApplication>
#include <QSettings>//Para abrirmos um arquivo texto.
#include <QMessageBox>//Para dialogos de menssagem.
#include <QSqlDatabase>//Para conexão ao banco.
#include "cadastro.h"
#include <QDesktopWidget>//Para a função "centralizarWidget"
//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 )
{
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 deconfiguraçã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("");//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
{
QMessageBox::information(0,"Iniciando o Sistema","Não foi possivel conectar-se ao banco de dados!");
return 1;
}
}
return a.exec();
}
Olhe no apêndice B no final do tutorial um algoritmo alternativo para main.cpp
Daqui em diante entraremos na parte de manipulação dos dados, portanto eu não vou explicar os mecanismos basicos da Qt, como Signals/Slots, que podem ser estudados na documentação. Agora, vamos ao cadastro.h:
#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 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
private slots://Nossas funções de trabalho.
void grava_na_Tabela();
void altera_na_Tabela();
void exclui_na_Tabela();
void limpa_Tela();
};
#endif
Agora, o principal do aplicativo, cadastro.cpp:
#include "cadastro.h"
#include <QSqlQuery>//Biblioteca dos componentes de acesso a tabelas no banco via SQL.
#include <QSqlQueryModel>//Para o "grid"
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()));
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();
}
fCad_Clientes::~fCad_Clientes()
{
delete query_Clientes;
delete model_Clientes;
}
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();
}
Compile com F8 e rode com <shift>F9, deve aparecer assim:
>
Se você esta em uma rede, já deve ter criado o banco no servidor, no meu caso eu tenho duas maquinas, a que é o servidor é a minha maquina de trabalho mesmo, depois tenho outra maquina para testes, onde texto o desempenho em rede, localmente o parâmetro é db.setHostName("localhost"), o host do meu servidor é "Programador", portanto na estação eu crio um diretório onde coloco o binario e o arquivo config.txt com a seguinte configuração:
database = "QPSQL"
hostname = "Programador"
databasename = "projetoqt"
Resumindo, para o sistema rodar a partir de uma estação da rede, crie um diretório para ele, copie o binário, o arquivo config.txt , dentro do diretório do binário crie outro diretório chamado "sqldrivers" este é importante , é onde vai o driver do Postgre, e o nome deve ser este mesmo "sqldrivers", não pode ser outro, copie para ele o driver do Postgre, cujo nome é "libqsqlpsql.so" e pode ser encontrado no diretório /usr/local/Trolltech/Qt-4.4.3/plugins/sqldrivers/, se tudo estiver correto, o sistema vai rodar perfeitamente, abaixo a imagem da configuração dos arquivos na estação e o aplicativo rodando na estação:
>
Abaixo, o aplicativo rodando na estação.
>
Espero ter demonstrado os princípios básicos para se construir um aplicativo cliente/servidor no Linux, tão fácil como em qualquer outra plataforma ou qualquer outra ferramenta RAD, é claro que este pequeno programa que fizemos não é comercial do ponto de vista estético e funcional, não tem botões de navegação na tabela e outros recursos que eu uso normalmente, mas se fôssemos fazer como os sistemas que eu coloquei de exemplo aqui no site iríamos nos delongar além do necessário, e fica como um desafio para quem estiver iniciando na programação para Linux melhorar este pequeno aplicativo. Fica aqui um comentário de quem programou em Delphi® por 10 anos seguidos, C++ é mais abstrato, permite coisas inimaginaveis em Pascal, como sobrecarga de operadores, declarar duas funções diferentes com o mesmo nome, namespaces etc, portanto é mais flexível, é uma linguagem de programação incomparável e também te obriga a ter um conhecimento maior de orientação a objetos e classes do que no Delphi®, que é completamente automatizado.
Finalizando, acho que já esta mais do que na hora do Linux entrar com tudo no desktop, as ferramentas hoje disponíveis para desenvolvimento de sistemas não ficam nada a dever para as da plataforma concorrente em termos de produtividade, rapidez e eficiência e no final você tera aplicativos rodando em uma plataforma mais estável e segura.
Obs: Baixe aqui os fontes do aplicativo.
Apêndice A: Ferramenta de Debug.
Integrados ao Kdevelop temos duas excelentes ferramentas de debug e verificação de erros, o gdb e o Valgrind. gdb
O gdb é o GNU Debugger, ferramenta para se rodar o programa passo a passo, monitorar e alterar valores de variáveis internas do programa durante a execução, alterar funções de forma independente do fluxo do programa. O gdb não tem interface gráfica própria, ele pode ser utilizado no terminal para debugar qualquer programa c ou C++:
Exemplo:
Compile com a opção -g no gcc ou g++
$> gcc -g -o prog prog.c
$> gdb prog
(gdb) run
(gdb) print, break, step, list, info, set, next, delete
Felizmente, existem interfaces gráficas para o gdb e também o Kdevelop o integra em sua IDE. Para usar o gdb em um aplicativo Qt você deve colocar o seguinte parâmetro no arquivo src.pro:
Onde esta CONFIG += release \ troque pro: CONFIG += debug \ , isto é fundamental para que o compilador coloque "marcas" internamente ao código gerado para servir de guia ao gdb. após feito isso compile novamente o aplicativo.
Você pode usar o Kdbg, uma interface gráfica do KDE para o gdb. no terminal digite kdgb, abra o binário, coloque os pontos de parada ou breakpoints e faça o kdgb iniciar o aplicativo, ele vai parar a execução no primeiro ponto de parada e você pode executar passo a passo, verificando valores de variáveis e descobrindo linha do fonte onde ocorrem erros, na figura abaixo, nosso aplicativo "cadastro" rodando a partir do kdbg com as janelas "locals" e "registers", abertas, e mostrando respectivamente o valor das variáveis e o conteúdo dos registradores , também se vê o breakpoint no main.cpp. O kdbg e bastante intuitivo e fácil de usar, na sua barra de ferramentas principal estão os botões para avançar passo a passo no fonte.
>
Agora vamos ver o gdb integrado ao Kdevelop, o processo é parecido com o kdbg:
>
Pessoalmente, quando preciso de uma analise mais completa prefiro o kdbg pois acho a integração do gdb ao Kdevelop um pouco confusa, algumas variáveis não mostram o seu valor, coisa que não acontece no kdgb, porem, para analises mais simples, o gdb integrado ao kdevelop é suficiente.
Valgrind
Normalmente eu uso mais o Valgrind do que o gdb, vazamentos de memória são mais difíceis de localizar, são erros sutis e as vezes insidiosos que transformam o seu programa em uma bomba relógio, um erro que pode ser localizado pelo gdb geralmente é um erro que interrompe a execução do programa, ao passo que um memory leak pode passar despercebido por muito tempo, o programa roda normalmente. O Valgrind pode ser rodado no terminal, sua saída é simples, no caso do nosso aplicativo, você pode fazer:
rodolfo@Programador:~$ cd /home/rodolfo/sistemaqt/cadastro/bin/
rodolfo@Programador:~/sistemaqt/cadastro/bin$ valgrind ./cadastro
Você tera a seguinte saida:
>
O Valgrind é melhor integrado ao Kdevelop do que o gdb, portanto você pode usa-lo a partir do Kdevelop sem nenhum problema, use o menu depurar do Kdevelop, escolha a opção "Verificação de falta de memória doValgrind":
>
Saida do Valgrind no Kdevelop:
>
Apêndice B: Algoritmo alternativo para main.cpp.
Operações de abertura, leitura e escrita em arquivos são muito comuns em programação, se você for programar em C++ "puro" para linha de comando você pode usar o Kdevelop mas não pode depender da Qt, por isso coloquei aqui uma versão alternativa do algortimo de abertura e leitura do arquivo "config.txt" feito em C++ que faz o mesmo que o primeiro sem depender de nada a não ser as libs do C++.
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
string formata_parametro(string leu_do_Arquivo)
{
int pos_ini,pos_fim;
pos_ini=leu_do_Arquivo.find_first_of(char(34));
pos_fim=leu_do_Arquivo.find_last_of(char(34));
return leu_do_Arquivo.substr(pos_ini+1,pos_fim-pos_ini-1);
}
int main(int argc, char *argv[])
{
char le_arq1[30];
char caminho[100];
char arq_Conf[13]="/config.txt";
getcwd(caminho,100);
string database,host,databasename;
strcat(caminho,arq_Conf);
ifstream arq(caminho);
int linha=1;
while(arq.eof()==false)
{
arq.getline(le_arq1,30);
switch (linha)
{
case 1:database=formata_parametro(le_arq1);
case 2:host=formata_parametro(le_arq1);
case 3:databasename=formata_parametro(le_arq1);
}
linha++;
}
arq.close();
return EXIT_SUCCESS;
}
Tutorial anterior: Introdução a construção(building) de um aplicativo Qt
Próximo Tutorial: Criando um relatório para o aplicativo com o Kugar