Académique Documents
Professionnel Documents
Culture Documents
Minicurso de
Parte 3
http://www.youtube.com/user/revistaqt
Ol carssimos leitores... Desta vez a Revista Qt se superou no atraso da publicao. Apesar das constantes conclamaes feitas tanto na RQt como no site, no tenho recebido artigos de outras fontes para publicao. A propsito, deixa eu lembr-los mais uma vez: quem quiser enviar matrias relacionadas a programao em C++, especialmente usando o Qt, s enviar o texto para o e-mail:
revistaqt@gmail.com
Nesta edio volto s origens, adotando o BrOffice Draw para composio da revista. Continuamos com o nosso Minicurso de Programao C++ com Qt e com a traduo do livro How to think like a computer scientist de Allan B. Downey. A srie Qt + PHP tambm voltou, desta vez com um exemplo de implementao de CRUD usando Qt + PHP + Zend + MySQL. Um grande abrao a todos
AndrLuizdeOliveiraVasconcelos
ndice
www.revistaqt.com
Editor Andr Luiz de O. Vasconcelos Charges Oliver Widder (Geek and Poke) Colaboradores Adriano H. Hedler Rafael Fassi Thiago Rossener Nogueira Frum QtBrasil
5 Iniciar
Minicurso de Programao C++ com Qt
30 Laboratrio
Iniciar
Nessa analogia, cada gaveta ou cada compartimento desse arquivo seria uma varivel, cada objeto seria uma determinada informao e cada tipo de objeto (lquido, slido, alimento, etc.) seria um tipo de informao. Da mesma forma como colocaramos indicadores nas gavetas do nosso armrio fictcio para facilitar a localizao de um determinado objeto, as variveis tambm precisam de identificadores, de modo que possamos localizar uma informao especfica. Estes identificadores, so os nomes das variveis. Suponhamos ento que voc queira guardar o ano do seu nascimento em uma varivel, de modo que possa depois recuperar esta informao. O ano de nascimento um nmero inteiro (sem casas decimais), portanto vamos informar ao compilador que precisamos de um espao na memria do computador para armazenar um nmero inteiro. O processo criar uma varivel em C++ chamado de declarao de varivel.
fig. 2.1
Maro/Abril-2011
www.revistaqt,com
Iniciar
Vejamos ento como seria a declarao de uma varivel para armazenar o ano de nascimento:
www.revistaqt,com
Maro/Abril-2011
Iniciar
fig. 2.3
Maro/Abril-2011
www.revistaqt,com
Iniciar
At aqui, vimos que o tipo de uma varivel corresponde ao tipo de dado que ela pode armazenar, assim como o tipo de gaveta dependia do tipo de objeto que queramos guardar em nosso armrio fictcio. A propsito, vocs podem estar se perguntando o porque do nome: varivel. simples, chamamos de variveis porque o contedo delas pode variar. Isto significa que podemos substituir o contedo de uma varivel por outro, assim como poderamos trocar o objeto guardado em uma das gavetas do armrio. Mas no vimos ainda como colocar contedo em uma varivel. Este procedimento chamado de atribuio de valor e pode ser feito no momento em que declaramos a varivel ou posteriormente. Ao declararmos a varivel anoNascimento, poderamos na mesma instruo, atribuir-lhe um valor. A declarao da varivel com a atribuio do meu ano de nascimento ficaria assim:
www.revistaqt,com
Maro/Abril-2011
Iniciar
Maro/Abril-2011
www.revistaqt,com
Iniciar
fig. 2.7 No prximo passo, vocs devem informar o nome do arquivo anonascimento nesse caso e a localizao, ou seja, a pasta onde o arquivo ser gerado. No meu caso, salvei o arquivo na pasta: /home/vasconcelos/Projetos/minicurso fig. 2.8
10
www.revistaqt,com
Maro/Abril-2011
Iniciar
A figura 2.9 mostra o cdigo completo do segundo programa desse nosso curso. Em relao ao primeiro, temos como novidade: - a declarao de uma varivel; - a solicitao de uma informao ao usurio.
figura 2.9 Bom, agora vamos com muita calma. Este pode ser um programa pequeno e praticamente intil, mas introduz um importante recurso: a interao com o usurio. Notem que ao invs de colocar um valor fixo na varivel, estamos solicitando ao usurio que o faa. A partir de um programa to simples quanto esse, poderamos evoluir para um que calculasse a idade do usurio, por exemplo. Vamos ento analisar nosso pequeno programa linha a linha. Recomendo que vocs deixem para digit-lo depois, quando souberem o que faz cada linha.
Maro/Abril-2011
www.revistaqt,com
11
Iniciar
As primeiras linhas desse programa so iguais s primeiras linhas do programa que fizemos na aula anterior, mas no custa dar mais uma repassada, ento vamos l: #include <iostream> Esta instruo inclui as definies para os objetos "cout" (vimos na primeira aula) e "cin" (j veremos para que serve). using namespace std; Esta linha indica ao compilador que estamos utilizando o espao de nomes chamado "std". No cabe a explicao do que um espao de nomes neste ponto do curso. Por ora, basta que saibamos que esta declarao informa ao compilador onde procurar por nomes como "cin", "cout" e endl. Sem a declarao, teramos de escrever "std::cout" ao invs de simplesmente cout, "std::cin" ao invs de cin e std::endl no lugar de endl. Com certeza bem mais simples declarar o uso do espao de nomes std apenas uma vez no programa do que ter que prefixar cada cout, cin e endl com std. int main(int argc, char * argv[])
12
www.revistaqt,com
Maro/Abril-2011
Iniciar
Agora a ltima novidade deste programa... o objeto cin. Ele praticamente o inverso de cout. Enquanto o primeiro d sada de informaes para o console, este permite a entrada de dados a partir do console (cin = console input). A sintaxe (forma como est escrita) desta instruo muito clara. A entrada obtida a partir do console est sendo armazenada na varivel anoNascimento. Quando for executada esta instruo far com que o programa pare e fique aguardando que o usurio digite alguma informao e tecle ENTER. Quando o usurio tecla ENTER, o valor que ele digitou armazenado na varivel anoNascimento e a execuo prossegue.
cout << "Ano do nascimento foi: " << anoNascimento << endl;
Participe deste projeto. Envie suas crticas, dvidas e sugestes para: revistaqt@gmail.com 13
Maro/Abril-2011
www.revistaqt,com
Iniciar
Finalmente, o programa imprime uma mensagem mostrando o contedo da varivel anoNascimento, seguido por uma quebra de linha. A ltima instruo do nosso programa apenas indica que a funo main retorna o valor 0. No futuro veremos como utilizar diferentes valores para este retorno. Pronto. Agora coloquem a mo na massa... podem digitar, compilar e testar o programa. Quem no se lembra como fazer para compilar, deve consultar a primeira aula na segunda edio da RQt. Experimentem alterar o programa retirando o endl no final da primeira instruo cout, deixando-a desta forma:
Compilem novamente, executem e vejam a diferena. Vejamos agora quais so as regras para criao de nomes de variveis em C++. - J vimos que o compilador distingue entre maisculas e minsculas nos nomes das variveis. Assim: "nome" e "Nome" so nomes vlidos de variveis diferentes.
14
www.revistaqt,com
Maro/Abril-2011
Iniciar
Para encerrar a aula, alguns comentrios sobre nomes de variveis. boa prtica de programao criar nomes que facilitem a identificao do dados que as mesmas guardaro. A varivel anoNascimento, por exemplo, no nos deixaria em dvida sobre o seu contedo. Em programas pequenos como o que escrevemos nesta aula, pode no fazer diferena alguma qual o nome da varivel, mas acreditem, escreveremos com o tempo programas bem maiores e utilizar uma nomenclatura adequada para as variveis pode poupar neurnios na hora de ler os cdigos. Experimente substituir o nome da varivel "anoNascimento" no programa por "a". Isso mesmo, s a letra "a". O programa vai funcionar da mesma forma que antes, mas no cdigo s identificamos que a varivel vai armazenar o ano de nascimento quando olhamos para a linha que solicita ao usurio que informe o seu ano de nascimento. Em programas pequenos certas recomendaes podem parecer meio paranicas, mas acreditem, medida em que o tamanho dos cdigos aumenta, aumenta a dificuldade de localizar erros. isso. Chegamos ao final da nossa segunda aula. Para tirar dvidas, acessem o grupo do nosso curso: https://groups.google.com/group/professorvasconcelos?hl=pt-br&pli=1 Um grande abrao a todos e at mais.
figura 2.10
Maro/Abril-2011
www.revistaqt,com
15
Oliver Widder o criador do site Geek and Poke e colaborador da Revista Qt.
16
www.revistaqt,com
Maro/Abril-2011
Maro/Abril-2011
www.revistaqt,com
17
Como mencionei no ltimo captulo, voc pode colocar tantas declaraes quantas queira na funo main. Por exemplo, para mostrar mais de uma linha de sada: #include <iostream.h> // main: gera algumas sadas simples void main () { cout << "Al, mundo." << endl; // exibe uma linha cout << "Como vai voc?" << endl; // exibe outra } Como voc pode ver, legal colocar comentrios ao final de uma linha, assim como em uma linha por s. As sentenas que aparecem entre aspas so chamadas strings (sequncia ou cadeia em ingls), porque so formadas de uma seguncia de letras. Na verdadade, strings podem conter qualquer combinao de letras, nmeros, sinais de pontuao, e outros caracteres especiais. Frequentemente til mostrar a sada de vrias declaraes de sada todos em uma linha. Voc pode fazer isso deixando fora o primeiro endl: void main () { cout << "Adeus, "; cout << "mundo cruel!" << endl; }
Neste caso, a sada aparece em uma nica linha como "Adeus, mundo cruel!".
18
www.revistaqt,com
Maro/Abril-2011
Verso Brasileira
Observe que existe um espao entre a palavra "Adeus," e o fechamento de aspas. Este espao aparece na sada, ento ele afeta o comportamento do programa. Espaos que aparecem fora de aspas geralmente no afetam o comportamento do programa. Por exemplo, eu poderia ter escrito: void main () { cout<<"Adeus, "; cout<<"mundo cruel!"<<endl; } Este programa deve compilar e executar to bem quanto o original. As quebras de linha no afetam o comportamento do programa tambm, ento eu poderia ter escrito: void main(){cout<<"Adeus, ";cout<<"mundo cruel!"<<endl;} Isto funcionaria tambm, no entanto voc provavelmente percebeu que o programa est ficando mais e mais difcil de ler. Quebras de linhas e espaos so teis para organizar seu programa visualmente, tornando-o mais fcil ler o programa e localizar erros de sintaxe.
2.2 Valores
Um valor uma das coisas fundamentais - como uma letra ou um nmero - que um programa manipula. Os nicos valores que manipulamos at aqui so os valores string que imprimimos, como "Al, mundo.". Voc (e o compilador) podem identificar valores string porque eles esto entre aspas. Existem outros tipos de valores, incluindo "integers" e "characters". Um integer um nmero inteiro como 1 ou 17. Voc pode imprimir valores integer da mesma forma que voc imprime strings:
Maro/Abril-2011
www.revistaqt,com
19
Verso Brasileira
cout << 17 << endl; Um valor character uma letra ou dgito ou sinal de pontuao entre aspas simples, como 'a' ou '5'. Voc pode imprimir valores character da mesma forma: cout << } << endl; Este exemplo imprime uma chave sozinha em uma linha. fcil confundir diferentes tipos e valores, como "5", '5' e 5, mas se voc prestar ateno pontuao (aspas duplas e simples), dever ficar claro que o primeiro uma string, o segundo um character e o terceiro um integer. O motivo porque esta distino importante dever ficar clara em breve.
2.3. Variveis
Uma das mais poderosas caractersticas de uma linguagem de programao a habilidade de manipular variveis. Uma varivel uma localizao nomeada que armazena um valor. Assim como existem diferentes tipos de valores (integer, character, etc.), existem diferentes tipos de variveis. Quando cria uma nova varivel, voc tem que declarar de que tipo ela . Por exemplo, o tipo character em C++ chamado char. A seguinte instruo cria uma nova varivel chamada fred que tem o tipo char. char fred;
20
www.revistaqt,com
Maro/Abril-2011
Verso Brasileira
O tipo de uma varivel determina que tipo de valores ela pode armazenar. Uma varivel char pode conter characters, e no deve ser nenhuma surpresa que variveis int possa armazenar integers. Existem alguns tipos em C++ que podem armazenar valores strings, mas vamos pular esta parte por enquanto (v. captulo 7). Para criar uma varivel integer, a sintaxe : int bob; onde bob um nome arbitrrio que voc inventa para a varivel. Em geral, voc ir querer inventar nomes de variveis que indiquem o que voc planeja fazer com a varivel. Por exemplo, se voc visse estas declaraes de variveis: char firstLetter; char lastLetter; int hour, minute; voc provavelmente teria um bom palpite de que valores seriam armazenados nelas. Este exemplo tambm demonstra a sintaxe para declarao de mltiplas variveis com o mesmo tipo: hour e minute so ambas inteiros (tipo int).
2.4 Atribuio
Agora que criamos algumas variveis, gostaramos de armazenar valores nelas. Fazemos isto com uma declarao de atribuio.
Maro/Abril-2011
www.revistaqt,com
21
Verso Brasileira
firstLetter = a; // d a firstLetter o valor a hour = 11; // atribui o valor 11 a hour minute = 59; // "seta" minute para 59 Este exemplo mostra trs atribuies, e os comnetrios mostram trs diferentes formas como as pessoas algumas vezes falam sobre declaraes de atribuio. O vocabulrio pode ser confuso aqui, mas a idia simples: . Quando voc declara uma varivel, cria uma localizao de armazenamento nomeada. . Quando faz uma atribuio a uma varivel, voc d a ela um valor. Uma forma comum de representar variveis no papel desenhar uma caixa com o nome da varivel do lado de fora e o valor da varivel dentro. Este tipo de figura chamada de diagrama de estado porque mostra em qual estado cada varivel est (voc pode pensar nisso como o "estado de esprito" da varivel). Este diagrama mostra o efeito das trs declaraes de atribuiao:
22
www.revistaqt,com
Maro/Abril-2011
Verso Brasileira
Algumas vezes, eu uso formas diferentes para indicar diferentes tipos de variveis. Esta formas devem ajud-lo a lembrar que uma das regras em C++ que uma varivel deve ter o mesmo tipo do valor que voc atribui a ela. Por exemplo, voc no pode armazenar uma string em uma varivel int. A seguinte declarao gera um erro de compilao: int hour; hour = "Hello."; // ERRADO! Esta regra algumas vezes uma fonte de confuo, porque existem muitas formas de voc converter valores de um tipo para outro, e C++ algumas vezes convertem coisas automaticamente. Mas por enquanto voc deve lembrar-se de que, como regra geral, variveis e valores tm que ter o mesmo tipo, e falaremos sobre casos especiais mais tarde. Outra fonte de confuso que algumas strings parecem com inteiros, mas elas no so. Por exemplo, a string "123", que composta pelos characters 1, 2 e 3, no a mesma coisa que o nmero 123. Esta atribuio ilegal: minute = "59"; // ERRADO!
Maro/Abril-2011
www.revistaqt,com
23
Verso Brasileira
Este programa cria duas variveis integers chamadas hour e minute, e uma varivel character chamada colon. Ele atribui valores para cada uma das variveis e ento usa uma serie de declaraes de sada para gerar o seguinte: A hora corrente 11:59 Quando falamos sobre "imprimir uma varivel", queremos dizer imprimir o valor da varivel. Para imprimir o nome da varivel, voc tem que coloc-lo entre aspas. Por exemplo: cout << "hour"; Como j vimos antes, voc pode incluir mais de um valor em uma nica declarao de sada, o que pode tornar o programa anterior mais conciso: int hour, minute; char colon; hour = 11; minute = 59; colon = :; cout << "A hora corrente " << hour << colon << minute << endl; Em uma linha, este programa imprime uma string, dois integers, um character e o valor especial endl. Impressionante!
2.6 Palavras-chaves
Algumas sesses atrs, eu disse que voc pode inventar qualquer nome que desejar para suas variveis, mas isto no exatamente verdade. Existem certas palavras que so reservadas em C++ porque elas so usadas pelo compilador para interpretar a estrutura do seu programa, e se voc us-las como nomes de variveis, ele ficar confuso. Estas palavras, chamadas palavras-chaves, incluem: int, char, void, endl e muitas mais. A lista completa de palavras-chaves includa no padro C++, que a definio oficial da linguagem adotada pela International Organization for Standardization (ISO) em 1 de setembro de 1998. Voc pode baixar uma cpia eletrnica em: http://www.ansi.org/
24
www.revistaqt,com
Maro/Abril-2011
Verso Brasileira
Ao invs de memorizar a lista, eu sugeriria que voc aproveitasse uma caracterstica disponvel em muitos ambientes de desenvolvimento: destaque de cdigo (code highlighting). medida em que voc digita, diferentes partes do seu programa devem aparecer em diferentes cores. Por exemplo, palavras-chaves podem ser azuis, strings vermelhas e outros cdigos pretos. Se voc digita o nome de uma varivel e ele fica azul, cuidado! Voc deve obter um comportamento estranho do compilador.
2.7 Operadores
Operadores so smbolos especiais que so usados para representar computaes simples como adio e multiplicao. A maioria dos operadores em C++ faz exatamente o que voc esperaria que eles fizessem, porque eles so smbolos matemticos comuns. Por exemplo, o operador para adio de dois integers +. Todas as expresses a seguir so legais em C++, com significados mais ou menos bvios: 1+1 hour-1 hour*60 + minute minute/60 Expresses podem conter tanto nomes de variveis quanto valores inteiros. Em cada caso o nome da varivel substituido pelo seu valor antes de que seja executada a computao. Adio, subtrao e multiplicao todos fazem o que voc espera, mas voc pode surpreender-se com a diviso. Por exemplo, o seguinte programa: int hour, minute; hour = 11; minute = 59; cout << "Nmero de minutos desde a meia-noite: "; cout << hour*60 + minute << endl; cout << "Frao da hora que passou: "; cout << minute/60 << endl;
Maro/Abril-2011
www.revistaqt,com
25
Verso Brasileira
geraria a seguinte sada: Nmero de minutos desde a meia-noite: 719 Frao da hora que passou:
A primeira linha o que voc espera, mas a segunda linha singular. O valor da varivel minuto 59, e 59 dividido por 60 0.98333, no 0. O motivo para a discrepncia que C++ executa uma diviso inteira. Quando ambos os operandos so inteiros (operandos so as coisas nas quais os operadores operam), o resultado dever ser tambm um inteiro, e por definio, inteiros sempre arredondam para baixo, mesmo em casos como este em que o prximo inteiro est to prximo. Uma alternativa possvel neste caso calcular um percentual ao invs de uma frao: cout << "Percentual da hora que passou: "; cout << minute*100/60 << endl; O resultado : Percentual da hora que passou: 98 Novamente o resultado arredondado para baixo, mas pelo menos agora a resposta est aproximadamente correta. Para obter um resultado ainda mais preciso, podemos usar um tipo diferente de varivel, chamado ponto flutuante, que capaz de armazenar valores fracionados. Chegaremos a este ponto no prximo captulo.
26
www.revistaqt,com
Maro/Abril-2011
Verso Brasileira
. Multiplicao e diviso acontecem antes da adio e subtrao. Ento 2 * 3 - 1 resulta em 5, no em 4, e 2 / 3 - 1 retorna -1, no 1 (lembrese de que a diviso inteira 2/3 igual a 0). . Se os operadores tem a mesma precedncia eles so avaliados da esquerda para a direita. Ento na expresso minute * 100 / 60, a multiplicao acontece primeiro, resultando 5900 / 60, o que por sua vez retorna 98. Se as operaes tivessem sido feitas da direita para a esquerda, o resultado seria 59 * 1 o que daria 59, o que est errado. . Sempre que voc quiser sobrepor as regras de precedncia (ou voc no estiver certo quais sejam elas) voc pode usar parnteses. Expresses em parnteses so avaliadas primeiro, ento 2 * (3 - 1) igual a 4. Voc tambm pode usar parnteses para tonar uma expresso mais fcil de ser lida, com em (minute * 100) / 60, mesmo que isto no altere o resultado.
Maro/Abril-2011
www.revistaqt,com
27
Verso Brasileira
O resultado 97, que o nmero usado internamente por C++ para representar a letra 'a'. Porm, sempre uma boa idia tratar characters como characters e integers como integers, e apenas converter de um para o outro se houver um bom motivo. Converso automtica de tipo um exemplo de problema comum no projeto de uma linguagem de programao, que a existncia de um conflito entre o formalismo, que a exigncia de que linguagens formais devem ter regras simples com poucas excees, e a convenincia, que a exigncia de que linguagens de programao sejam fceis de usar na prtica . Mais frequentemente, a convenincia ganha, o que normalmente bom para programadores experientes, que so poupados do rigoroso, porm pesado formalismo, mas ruim para programadores iniciantes, que muitas vezes surpreendem-se com a complexidade das regras e com o nmero de excees. Neste livro, tentei simplificar as coisas enfatizando as regras e omitindo muitas das excees.
2.10 Composio
At aqui olhamos para os elementos de uma linguagem de programao variveis, expresses e declaraes - isoladamente, sem falar sobre como combin-los. Uma das mais teis caractersticas de uma linguagem de programao sua habilidade para pegar pequenos blocos de construo e complos. Por exemplo, sabemos como multiplicar inteiros (int) e sabemos como exibir valores de variveis; acontece que podemos fazer as duas coisas ao mesmo tempo: cout << 17 * 3; Na verdade, eu no poderia dizer "ao mesmo tempo", uma vez que na realidade a multiplicao tem que acontecer antes da impresso, mas o fato que qualquer expresso, envolvendo nmeros, caracteres e variveis, pode ser usada dentro de uma declarao de impresso. Ns j vimos um exemplo: cout << hour*60 + minute << endl;
28
www.revistaqt,com
Maro/Abril-2011
Verso Brasileira
Esta habilidade pode no parecer muito impressionante agora, mas veremos outros exemplos onde a composio torna possvel expressar computaes complexas de forma ntida e concisa. Aviso: Existem limites para onde voc pode usar certas expresses; notadamente, o lado esquerdo de uma expresso de atribuio tem que ser um nome de uma varivel, no uma expresso. Isto porque o lado esquerdo indica o local para onde vai o resultado. Expresses no representam locais de armazenamento, apenas valores. Ento o seguinte ilegal: minute+1 = hour.
2.11 Glossrio
varivel: Um local nomeado para armazenamento de valores. Todas as variveis tm um tipo, que determina que valores podem armazenar. valor: Uma letra, nmero, ou outra coisa que possa ser armazenada em uma varivel. tipo: Um conjunto de valores. Os tipos que vimos so inteiros (int em C++) e caracteres (char em C++). palavra-chave: Uma palavra reservada que usada pelo compilador analisar programas. Exemplos que vimos incluem int, void e endl. statements: Uma linha de cdigo que representa um comando ou uma ao. At aqui, os statements que vimos so declaraes, atribuies e declaraes de impresso. declarao: Um statement que cria uma nova varivel e determina seu tipo. atribuio: Um statement que atribui um valor a uma varivel. expresso: Uma combinao de variveis, operadores e valores que representam um valor nico de resultado. Expresses tambm tm tipos, determinados pelos seus operadores e operandos. operador: Um smbolo especial que representa uma computao simples como adio ou multiplicao. operando: Um dos valores aos quais se aplica um operador. precedncia: A ordem na qual as operaes so avaliadas. composio: A habilidade de combinar expresses simples e statements em statements compostos e expresses para representar computao complexa de modo conciso.
Maro/Abril-2011
www.revistaqt,com
29
Laboratrio
Na primeira edio da Revista Qt, foi publicado um artigo demonstrando o desenvolvimento de uma aplicao hbrida Desktop + WEB. Na segunda edio, tivemos a segunda parte da srie, com um exemplo de aplicao um pouco mais complexa, acessando um banco de dados e utilizando o Zend Framework do lado servidor. Nesta edio, a terceira parte da srie Qt + PHP traz um exemplo de aplicao simples, porm completa. Esta aplicao representa o que comumente chamado de CRUD Create, Retrieve, Update and Delete, ou seja: Criar, recuperar, atualizar e eliminar (referindo-se a registros em um banco de dados).
figura 1
A figura 1 mostra como ficar a tela da nossa aplicao, que ser uma mini agenda. Para alterar os dados de um contato, devemos clicar duas vezes na linha correspondente ao contato. Neste caso, ser apresentada uma outra janela com os dados do contato. Nesta tela (de alterao) teremos um boto Salvar para gravar no banco as alteraes e um boto Apagar que permitir ao usurio excluir o contato. Para incluir novos contatos, o usurio deve clicar no boto Novo mostrado na figura 1. O boto Atualizar carrega novamente os dados do banco. O boto Sair simplesmente encerra a aplicao.
30
www.revistaqt,com
Maro/Abril-2011
Laboratrio
A estrutura da nossa aplicao a mesma que usamos na aplicao publicada na segunda edio da RQt. No caso da parte servidora da aplicao em PHP utilizei inclusive o mesmo diretrio phpapp que usei naquela ocasio. Recapitulando, na aplicao publicada na segunda edio da RQt criamos um diretrio chamado phpapp com um subdiretrio Classes nele e um link para o diretrio library/Zend do Zend Framework, O lado servidor da nossa aplicao naquela ocasio tinha apenas duas classes: Conexao Responsvel por estabelecer a conexo com o banco de dados da aplicao ListaEstado Responsvel por recuperar os dados de uma tabela de estados e retornar aplicao cliente (em Qt). Para a aplicao que vamos desenvolver agora, faremos algumas mudanas no lado servidor. Para implementar as opes disponveis agora, criaremos uma classe chamada Modelo com os mtodos necessrios para recuperar, gravar e apagar registros do banco de dados. Esta classe ser implementada de modo que suas filhas tenham o mnimo de cdigo necessrio. Cada filha da classe Modelo corresponder a uma tabela no banco de dados. Para a aplicao que estamos criando agora, teremos apenas uma tabela.
figura 2
Maro/Abril-2011
www.revistaqt,com
31
Laboratrio
Vamos comear pela criao do banco de dados que ser usado pela aplicao:
figura 3
32
www.revistaqt,com
Maro/Abril-2011
Laboratrio
Nosso prximo passo criar no banco agenda a tabela contato. O comando para criao da tabela listado a seguir:
CREATE TABLE `contato` ( `id_contato` int(11) NOT NULL AUTO_INCREMENT, `nome` varchar(40) NOT NULL, `nascimento` date NOT NULL, `telefone_residencial` varchar(10) NOT NULL, `telefone_celular` varchar(10) NOT NULL, `email` varchar(255) NOT NULL, PRIMARY KEY (`id_contato`), UNIQUE KEY `nome` (`nome`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
Com o banco pronto, podemos passar parte servidora da aplicao, considerando que voc tenha o servidor Web Apache e o PHP devidamente configurados. Se voc fez a aplicao da segunda edio, ento j tem o diretrio phpapp criado no servidor. Se no tiver, consulte o artigo Qt + PHP da segunda edio da Revista Qt a partir da pgina 7 onde tambm encontra-se o procedimento para criao do link para o diretrio com as bibliotecas do Zend Framework. Com o servidor Apache/PHP pronto, e o diretrio phpapp criado, podemos passar s listagens dos programas em PHP que compem o lado servidor na nossa aplicao. Alguns destes arquivos foram criados no artigo da segunda edio que mencionei antes, mas como tivemos alteraes vou reproduzir aqui a listagem de todos eles. O primeiro da lista o arquivo index.php, o ponto de entrada para a poro PHP da nossa aplicao. Este o arquivo chamado pela parte desktop (escrita em Qt) da nossa aplicao para execuo de mtodos de classes em PHP. Este arquivo (index.php) deve ser criado no diretrio raiz da aplicao web phpapp. A seguir a listagem do arquivo index.php:
Maro/Abril-2011
www.revistaqt,com
33
Laboratrio
figura 4
A figura 4 traz a listagem completa do arquivo index.php. A explicao do que faz cada linha deste arquivo pode ser conferida na pgina 9 da segunda edio da RQt. O prximo arquivo que veremos o Conexao.php que contm a declarao da classe responsvel pela conexo e envio de comandos para o banco de dados. Como o cdigo-fonte maior, o veremos por partes. A figura 5 mostra a incluso da definio da classe Db do Zend Framework, que usaremos para conexo com o banco de dados, assim como envio de comandos para ele. Este arquivo deve ficar no diretrio Classes dentro do diretrio da aplicao phpapp.
figura 5
34
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 6
A figura 6 traz o cdigo do mtodo conecta, utilizado para estabelecer a conexo com o banco de dados. Observe que neste mtodo feita uma verificao do atributo db. Caso este atributo seja um recurso, isto indica que a conexo j foi estabelecida. Caso contrrio, o mtodo far a conexo com o banco. Voc deve alterar o cdigo neste mtodo, substituindo a senha pela senha do usurio root de sua instalao do MySQL.
figura 7
Maro/Abril-2011
www.revistaqt,com
35
Laboratrio
Na figura 7, continuando com o cdigo fonte do arquivo Conexao.php, temos o mtodo getConexao. Este mtodo retorna uma instncia do objeto Conexao. O mtodo declarado como esttico, porque poder ser chamado sem que haja um objeto da classe Conexao instanciado. Esta uma implementao do design pattern conhecido como Singleton. Se o atributo instancia da classe Conexao estiver setado, ento o mtodo simplesmente retorna este atributo. Caso contrrio cria uma nova instncia da classe Conexao e seta o atributo instancia com este objeto, antes de retorna-lo (o atributo instancia).
figura 8
O prximo mtodo da classe Conexao o camposTabela (figura 8), que retorna um array com a coleo de campos de uma tabela passada como argumento para o mtodo. Ele chama o mtodo conecta (figura 6) e em seguida atravs de uma chamada ao mtodo describeTable da classe Zend_Db, retorna o array com os campos da tabela. A mgica para este mtodo ser to simples est na utilizao do Zend Framework.
figura 9
A figura 9 mostra o cdigo do mtodo executaQuery. Este mtodo recebe como argumento um comando SQL, conecta ao banco de dados (pela chamada ao mtodo conecta) e submete o comando ao banco atravs de uma chamada ao mtodo fetchAll da classe Zend_Db, retornando o resultado que no caso ser um XML com o retorno da consulta.
36
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 10
Da mesma forma como temos um mtodo para execuo de consultas SQL, temos um mtodo para executar um INSERT em uma dada tabela. Este mtodo, mostrado na figura 10, o executaInsert. O mtodo recebe como argumentos, o nome da tabela e um array com os dados a serem inseridos. Daqui a pouco veremos qual deve ser a estrutura deste array de dados. O mtodo conecta ao banco e solicita a insero dos dados atravs de uma chamada ao mtodo insert da classe Zend_Db.
figura 11
A figura 11 mostra o cdigo do mtodo executaUpdate da nossa classe Conexao, que como voc j deve estar desconfiando, executa comandos UPDATE em tabelas do banco de dados. Alm do nome da tabela e do array com os dados para execuo do UPDATE, este mtodo recebe ainda um array com as condies para execuo do comando. No se preocupe que mais para a frente veremos a estrutura desse array.
Maro/Abril-2011
www.revistaqt,com
37
Laboratrio
figura 12
Finalmente, pra encerrar o cdigo da classe Conexao (arquivo Conexao.php), temos o mtodo executaDelete, mostrado na figura 12, que o responsvel pela execuo de comandos DELETE em tabelas do banco. Este mtodo recebe como argumentos o nome da tabela e um array com as condies para a execuo do DELETE. A execuo do comando se d pela chamada ao mtodo delete da classe Zend_Db. A chave fechando na linha 61 corresponde que foi aberta na linha 3 (v. figura 5), delimitando o cdigo da classe Conexao. Agora que criamos a classe que cuidar da nossa conexo com o banco de dados, vamos criao da classe que ser a responsvel pela manipulao de dados correspondente s tabelas do banco. No caso da aplicao que estamos desenvolvendo neste artigo, teremos apenas uma tabela, mas esta classe servir de base para aplicaes maiores no futuro. A seguir, o cdigo da classe Modelo, no arquivo Modelo.php que deve ficar no diretrio Classes dentro do diretrio da aplicao phpapp. A figura 13 mostra as primeiras linhas de cdigo da classe Modelo. Esta classe possui dois atributos: $tabela que armazena o nome da tabela do banco e $campos que um array com os campos que compem a tabela.
figura 13
38
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 14
A figura 14 apresenta o cdigo do mtodo construtor da classe Modelo. Aqui foram usados alguns truques para facilitar ainda mais o desenvolvimento da nossa aplicao servidora. Pra comear, setamos o atributo tabela com o nome da classe convertido para minsculas. Parece no fazer muito sentido agora, mas nas classes filhas, isto evita que tenhamos que identificar a tabela. Eu explico: na aplicao que estamos desenvolvendo neste artigo, temos uma tabela contato no banco de dados. A classe correspondente a esta tabela se chamar Contato e ser filha (extends) da classe Modelo. Dessa forma, o construtor da classe pai ir setar o nome da tabela como contato. Continuando, o construtor inicializa o atributo campos como um array, pega da classe Conexao uma conexo com o banco de dados e preenche o atributo campos com os campos da tabela, excetuando o primeiro campo (o campo id da tabela). Prosseguindo com a listagem do arquivo Modelo.php, temos o mtodo grava, que ser o responsvel por gravar os dados nas tabelas dos bancos. Este mtodo utilizado tanto para incluso de novos registros como para atualizao de registros existentes. Este mtodo preenche um array com os campos e seus respectivos contedos. Claro que para que isto funcione, a aplicao precisa receber pela URL, os nomes corretos dos campos, correspondentes aos nomes dos campos da tabela no banco de dados. Para determinar quando se trata de uma incluso ou de uma atualizao, o mtodo verifica se foi passado um campo id pela URL. Se for passado um id ento trata-se de uma autlizao mtodo executaUpdate caso contrrio trata-se de uma incluso mtodo executaInsert. Veja o cdigo do mtodo grava na figura 15.
Maro/Abril-2011
www.revistaqt,com
39
Laboratrio
figura 15
Na figura 15, o cdigo do mtodo apaga que elimina registros das tabelas no banco de dados. O mtodo deve receber pela URL um campo chamado id contendo o id do registro a ser eliminado do banco. O mtodo utilizado para eliminar o registro o executaDelete da classe Conexao.
figura 16
40
www.revistaqt,com
Maro/Abril-2011
Laboratrio
A figura 17 traz o ltimo mtodo da classe Modelo, o recuperaTodos que responsvel pela recuperao de dados das tabelas do banco de dados. Observe que a montagem do comando SQL para recuperao dos dados utiliza o atributo tabela que contm o nome da tabela. Caso tenha sido passado pela URL um campo chamado order, este ser utilizado na clusula ORDER BY do comando SQL. A ltima chave fechando na linha 55 refere-se abertura de chaves feita na linha 3 (v. figura 13).
figura 17
Para concluir a parte servidora da nossa aplicao, veremos agora o cdigo da classe Contato, no arquivo Contato.php que deve ser criado no diretrio Classes do diretrio da nossa aplicao (phpapp). Esta classe ser filha da classe Modelo. Como a inteligncia para a manipulao da dados de tabelas foi implementada na classe pai Modelo o cdigo da classe Contato ser mnimo (como pode-se conferir na figura 18).
Maro/Abril-2011
www.revistaqt,com
41
Laboratrio
figura 18
Isto encerra a parte PHP da nossa aplicao. Acabou ficando muito simples apenas quatro arquivos pela utilizao do Zend Framework. Agora vem a parte mais divertida da aplicao seu lado desktop, em Qt. No Qt Creator, selecione a opo Create Project..., selecionando em seguida Qt C++ Project e Qt Gui Application (figura 19). Continuando, temos o nome e a localizao da aplicao. Usando toda a criatividade que me peculiar, coloquei o nome da aplicao Agenda e selecionei a pasta que utilizo para meus projetos que abusando da mesma criatividade, chama-se Projetos (figura 20).
figura 19
figura 20
42
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 22
figura 21
Continuando, temos as informaes da nossa classe principal do nosso projeto aquela que corresponder janela principal da aplicao. Aceitei a sugesto do Qt Creator como MainWindow, ento tudo que precisei fazer foi clicar no boto Next novamente (figura 22). Na figura 23, o resumo apresentado pelo wizard de criao de projetos do Qt Creator. Clicando no boto Finish teremos concluido o processo.
figura 23
Maro/Abril-2011
www.revistaqt,com
43
Laboratrio
figura 24
44
www.revistaqt,com
Maro/Abril-2011
Laboratrio
Na figura 24, temos a tela do Qt Creator com a janela principal da nossa aplicao. A tela principal da nossa agenda ter um QTableWidget que ser utilizado para exibir a lista dos dados cadastrados no banco de dados e trs QPushButtons para os controles da aplicao. Veja na figura 25, a janela principal com os respectivos componentes. No se preocupe com o posicionamento, pois deixaremos isto por conta do gerenciador de layouts do Qt.
figura 25
Maro/Abril-2011
www.revistaqt,com
45
Laboratrio
figura 26
Altere os rtulos dos botes conforme mostrado na figura 26. Alm dos rtulos dos botes, altere seus nomes conforme mostra a tabela 1. Rtulo &Novo &Atualizar &Sair Nome do componente btnIncluir btnAtualizar btnSair
tabela 1
46
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 27
Para ajustar o posicionamento dos componentes na tela, clique na janela com o boto direito e selecione a opo Lay out em seguida Lay Out in a Grid. Outra forma de chegar a este mesmo resultado clicando na tela para selecion-la e usando em seguida a combinao de teclas CTRL + G. A aparncia da tela dever ser a apresentada na figura 27. Com a tela principal da aplicao pronta, vamos criao da janela que ser utilizada para edio dos dados em nossa agenda. Clique no boto Edit no painel do lado esquerdo do Qt Creator para sair do modo de Design. Para criar uma nova janela, clique com o boto direito do mouse na na opo Forms e em seguida selecione no menu de contexto a opo Add New, como mostrado na figura 28.
Maro/Abril-2011
www.revistaqt,com
47
Laboratrio
figura 28
Para ajustar o posicionamento dos componentes na tela, clique na janela com o boto direito e selecione a opo Lay out em seguida Lay Out in a Grid. Outra forma de chegar a este mesmo resultado clicando na tela para selecion-la e usando em seguida a combinao de teclas CTRL + G. A aparncia da tela dever ser a apresentada na figura 27. Com a tela principal da aplicao pronta, vamos criao da janela que ser utilizada para edio dos dados em nossa agenda. Clique no boto Edit no painel do lado esquerdo do Qt Creator para sair do modo de Design. Para criar uma nova janela, clique com o boto direito do mouse na na opo Forms e em seguida selecione no menu de contexto a opo Add New, como mostrado na figura 28.
48
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 30
figura 29
Selecione a opo Dialog without Buttons e clique no boto Next para continuar. Na prxima tela (figura 31), vamos dar um nome para a classe da nossa janela de edio de dados. Criei esta classe com o nome de DialogoEditar. Para continuar clique no boto Next. Para concluir o processo, clique no boto Finish na tela mostrada na figura 32, que apresenta um resumo da operao de criao do novo dilogo para nossa aplicao. A exemplo de como fizemos para a janela principal da aplicao, vamos colocar os componentes em nossa janela de edio de dados.
Para criao da janela de edio da dados da nossa agenda, selecione as opes Qt Qt Designer Form Class (figura 29). Para continuar, clique no boto Choose. A janela de edio de dados da agenda ser um QDialog, ou seja, uma janela de dilogo. Acionada a partir da janela principal da aplicao, ela ficar em primeiro plano durante sua exibio. Ao ser fechada, a aplicao habilita novamente a janela principal.
Maro/Abril-2011
www.revistaqt,com
49
Laboratrio
figura 31
figura 32
Na janela de edio de dados temos (v. figura 33): 5 componentes QLabel usados para os rtulos dos campos (Nome, Nascimento, Fone Cel., Fone res. e e-mail. 4 componentes QLineEdit usados para os campos nome, fone celular, fone residencial e e-mail do contato. 1 componente QDateEdit usado para o campo data de nascimento do contato 3 componentes QPushButton usados para acesso s opes: apagar, salvar alteraes e fechar a janela.
50
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 33
Distribua os componentes no formulrio como mostrado na figura 33 ou da forma que achar melhor. Na tabela abaixo esto os nomes de cada um dos componentes. Campo Nome Nascimento Fone Cel. Fone Res. e-mail Boto Apagar Boto Salvar Boto Cancelar Componente QLineEdit QDateEdit QLineEdit QLineEdit QLineEdit QPushButton QPushButton QPushButton Nome do componente nome nascimento fonecel foneres email btnApagar btnSalvar btnCancelar
tabela 2
Maro/Abril-2011
www.revistaqt,com
51
Laboratrio
Com os formulrios criados, podemos passar ao cdigo fonte. Vamos comear pela classe MainWindow a janela principal da nossa aplicao.
figura 34
Na figura 34, a primeira parte do arquivo mainwindow.h a declarao da classe MainWindow. Alm dos includes para as classes Qt usadas, observe o include para o arquivo dialogoeditar.h, usada para edio de registros da nossa agenda. Na figura 35, o restante do cdigo do arquivo mainwindow.h.
52
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 35
Depois do cdigo de declarao da classe MainWindow (no arquivo mainwindow.h), vamos sua implementao no arquivo mainwindow.cpp, Como o cdigo deste arquivo relativamente extenso pouco mais de duzentas linhas vamos quebrar o cdigo em partes, apresentadas da figura 36 at a figura 43. Com combinamos que esta srie de artigos - Laboratrio seria dedicada ao pessoal com mais conhecimento tanto de programao como de Qt, no veremos a explicao de todos os mtodos do programa.
Maro/Abril-2011
www.revistaqt,com
53
Laboratrio
figura 36
54
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 37
Maro/Abril-2011
www.revistaqt,com
55
Laboratrio
figura 38
56
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 39
Maro/Abril-2011
www.revistaqt,com
57
Laboratrio
figura 40
58
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 41
Maro/Abril-2011
www.revistaqt,com
59
Laboratrio
figura 42
60
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 43
Participe deste projeto. Envie suas crticas, sugestes, dvidas, artigos para: revistaqt@gmail.com
Maro/Abril-2011
www.revistaqt,com
61
Laboratrio
figura 44
62
www.revistaqt,com
Maro/Abril-2011
Laboratrio
figura 45
Maro/Abril-2011
www.revistaqt,com
63
Laboratrio
figura 46
64
www.revistaqt,com
Maro/Abril-2011
Laboratrio
isso. Execute a aplicao e teste suas funcionalidades, incluindo, excluindo e alterando registros na agenda. A figura 47 mostra a aparncia da nossa pequena Agenda. Como esta aplicao foi concebida para servir como exemplo, tentei simplific-la ao mximo. No implementei uma opo de pesquisa, por exemplo. A propsito este pode ser um bom exerccio pra voc: criar um dilogo que solicite o dado a ser localizado na agenda, procure no banco e exiba os registros localizados. Nas prximas edies da RQt veremos outros exemplos de aplicaes hbridas como esta. At l.
figura 47
Maro/Abril-2011
www.revistaqt,com
65