Professional Documents
Culture Documents
3 Edio
Pablo Dall'Oglio
Novatec
CAPTULO 1
Introduo
Quando voc tem uma meta, o que era um obstculo passa a ser uma das etapas do seu plano. (Gerhard Erich Boehme)
Neste captulo de introduo, conheceremos as razes do PHP e do GTK, sua histria e como surgiu o PHP-GTK, assunto principal deste livro.
Em novembro de 1997 foi lanada a segunda verso do PHP. Naquele momento, aproximadamente 50 mil domnios ou 1% da Internet j utilizava PHP. No mesmo ano, Andi Gutmans e Zeev Suraski, dois estudantes que usavam PHP em um projeto acadmico de comrcio eletrnico, resolveram cooperar com Rasmus para
18
Captulo 1 Introduo
19
aprimorar o PHP. Para tanto, reescreverem todo o cdigo, com base no PHP/FI 2. Assim nasceu o PHP3, disponibilizado ocialmente em junho de 1998. Dentre as principais caractersticas do PHP3 estavam a extensibilidade, a possibilidade de conexo com vrios bancos de dados, novos protocolos, uma sintaxe mais consistente, suporte orientao a objetos e uma nova API, que possibilitava a criao de novos mdulos e acabou por atrair vrios desenvolvedores ao PHP. No nal de 1998, o PHP j estava presente em cerca de 10% dos domnios da Internet. Naquela poca, o signicado da sigla PHP mudou para PHP: Hypertext Preprocessor, a m de retratar a nova realidade de uma linguagem com propsitos mais amplos. No inverno de 1998, aps o lanamento do PHP 3, Zeev e Andi comearam a trabalhar em uma reescrita do ncleo do PHP, tendo em vista melhorar sua performance e modularidade em aplicaes complexas. Para tal, resolveram chamar esse ncleo de Zend Engine, ou Mecanismo Zend (Zeev + Andi). O PHP4, com base nesse mecanismo, foi lanado ocialmente em maio de 2000, trazendo muitas melhorias e recursos novos, como sees, suporte a diversos servidores Web, alm da abstrao de sua API, permitindo inclusive que fosse utilizado como linguagem para shell script. Nesse momento, o PHP j estava presente em cerca de 20% dos domnios da Internet, alm de ser usado por milhares de desenvolvedores no mundo inteiro. Apesar de todos os esforos, o PHP ainda necessitava de maior suporte orientao a objetos, tal qual existe em linguagens como C++ e Java. Esses recursos foram trazidos pelo PHP 5, aps um longo perodo de desenvolvimento que culminou com sua disponibilizao ocial em julho de 2004. Atualmente, na verso 6, o PHP se consolida como uma das linguagens de programao que mais crescem no mundo. Fonte: PHP Group.
20
O GTK um conjunto de ferramentas composto de vrias partes: glib (G Library) Esta biblioteca contm algumas rotinas de programao em C, prov a estrutura bsica de programao, dene alguns tipos de dados que so usados pelas camadas superiores. gdk (GTK Drawing Kit) Encapsula o Sistema de Janelas (X ou Windows) sob o GTK. Contm as rotinas para desenho da interface e para responder aos eventos do mouse ou do teclado. gtk (Gimp Toolkit) Contm a biblioteca de componentes, que consiste em uma srie de controles, como caixas de edio, listas e botes, dentre outros, organizados em uma estrutura orientada a objetos. pango Biblioteca responsvel pelo layout e renderizao de texto (caracteres de mltiplos idiomas). Forma o ncleo de manipulao de textos e fontes no GTK2. Utiliza o padro Unicode e suporta a maioria dos idiomas.
Captulo 1 Introduo
21
User Interface). Foi escrita, em parte, para provar que o PHP uma linguagem completa e de propsitos amplos. O casamento do PHP com o GTK harmonioso, pois ambos so independentes de plataforma. No PHP-GTK temos uma ferramenta de desenvolvimento que permite aos desenvolvedores rodarem o mesmo cdigo em ambientes Linux,Windows e Mac. Na gura 1.3, voc confere o logotipo do PHP-GTK.
A primeira verso do PHP-GTK, que vigorou de 2001 a 2005, era baseada no PHP4 em conjunto com a biblioteca GTK1.2, justamente a verso coberta pela primeira edio deste livro. Logo que as primeiras verses beta do PHP5 comearam a ser lanadas, Andrei iniciou o trabalho de reescrever o PHP-GTK para aproveitar todos os novos recursos relacionados orientao a objetos que foram surgindo, bem como passar a adotar a biblioteca GTK2, que j estava consolidada e com grande adoo. Assim surge o PHP-GTK2, que a unio da linguagem PHP5 com a biblioteca GTK2, possibilitando o desenvolvimento de aplicaes grcas complexas e de grande apelo visual, proporcionadas pelo GTK2, e, ao mesmo tempo, o uso dos avanados recursos de orientao a objetos e conexo a bancos de dados, proporcionados pela linguagem PHP5. Utilizando PHP-GTK, voc poder criar uma aplicao que possui conectividade com o servidor (banco de dados e acesso a arquivos), como todos os demais programas escritos em PHP. Mas, pelo fato de rodar a aplicao na mquina-cliente, tambm tem total acesso aos recursos desta, por exemplo, executar aplicaes, escrever arquivos e acessar dispositivos perifricos. Para tal, o PHP-GTK precisa ser instalado em cada mquina-cliente que executar uma aplicao. Veja na gura 1.4 um grco que ilustra bem tudo o que foi descrito at aqui. A linguagem PHP parte central do desenvolvimento. Todo o cdigo escrito em PHP, que a linguagem-me. Como resultado visvel da aplicao ao usurio nal, existem duas possveis sadas: pgina HTML, utilizando o PHP da forma tradicional, ou Interface Grca, com um ambiente de botes e janelas empregando o GTK. O PHP uma linguagem de programao modularizada, composta por um ncleo e cercada por inmeras extenses da linguagem. Existem extenses para gerao de imagens (GD), documentos PDF (FPDF), acesso a servidores Web via Web-Services e FTP, compactao de arquivos (zlib), entre outras. O PHP-GTK surge nesse contexto com a extenso de maior tamanho e complexidade, provendo um
22
framework completo para a construo de aplicaes grcas para projetos escritos em PHP. Veja na gura 1.5 alguns exemplos de extenses do PHP.
HTML BD PHP GTK
Figura 1.4 Plataforma de desenvolvimento.
1.4.1 Compilao
Para compilar o PHP-GTK no Linux necessrio ter instaladas as ferramentas GNU (make, libtool, autoconf, automake, gcc etc). Tambm necessrio ter as verses completas do Gtk (libgtk-2.0, libgtk2.0-dev) e Glib (libglib2.0, libglib2.0-dev). Se voc quiser tambm o suporte ao Glade, necessrio ter instaladas as bibliotecas libglade2, libglade2-dev, libxml2 e libxml2-dev. Instale o PHP 5.2.x ou superior. Os parmetros a seguir so somente uma sugesto:
CAPTULO 2
Introduo ao PHP
Voc no pode ensinar nada a um homem; voc pode apenas ajud-lo a encontrar a resposta dentro dele mesmo. (Galileu Galilei)
Este captulo realiza uma introduo sobre as diversas funes, comandos e estruturas de controle bsicos da linguagem PHP, que so possivelmente utilizados ao longo do livro. Conheceremos as estruturas bsicas da linguagem, suas variveis e seus operadores e tambm um conjunto de funes para manipulao de arquivos, de arrays, de bancos de dados, dentre outros.
25
CAPTULO 3
Nenhuma mente que se abre para uma nova ideia voltar a ter o tamanho original. (Albert Einstein)
Este captulo abordar a orientao a objetos por meio de exemplos que incluam conceitos bsicos como a visibilidade, a herana, entre outros tpicos importantes para a continuidade da leitura do livro. Alm da orientao a objetos, este captulo examinar tambm o tratamento de excees e o acesso a bancos de dados de maneira estruturada e tambm orientada a objetos, utilizando a biblioteca PDO.
3.1.1 Introduo
Ao trabalharmos com a orientao a objetos, fundamental entender o conceito de classes e objetos. Uma classe uma estrutura esttica que dene um tipo de dados. Uma classe pode conter atributos (variveis) e tambm funes (mtodos) para manipular esses atributos. Neste exemplo, declaramos a classe Produto com quatro atributos. Os atributos so variveis que existem dentro do contexto de
65
CAPTULO 4
Introduo ao PHP-GTK
Nunca encontrei uma pessoa to ignorante que no pudesse ter aprendido algo com sua ignorncia. (Galileu Galilei)
Para escrever aplicaes grcas necessrio entender alguns termos que so bastante utilizados, como widgets, contineres, signals e callbacks, explicados ao longo deste captulo. Antes de tudo, um pouco da histria das interfaces grcas.
100
101
uma GUI. Toda a ideia baseia-se na psicologia. O crebro humano interpreta com mais facilidade cones do que palavras. Na dcada de 1970, Alan Kay e outros desenvolvedores criaram o Smaltalk, linguagem exvel que permitiu, posteriormente, a criao de uma GUI muito similar que conhecemos hoje. A primeira interface grca (GUI), realmente utilizvel, surgiu no Centro de Pesquisa da Xerox em Palo Alto (Xerox Palo Alto Research Center - PARC), em 1974, onde foi desenvolvido o Alto, que permitia criar aplicaes grcas e introduziu os primeiros cones, mas era grande demais para ser comercializado. Mais tarde, em 1981, a Xerox desenvolveria o Xerox Star, uma mquina aperfeioada, que provia janelas redimensionveis, menus e um mouse sosticado. Aps uma visita aos laboratrios da Xerox em 1979 (devido a um acordo de cooperao), Steve Jobs e seus colegas da Apple Computer comearam a desenvolver um sistema com interface grca com base nas mesmas ideias, o Apple Lisa, que foi comercializado em 1983, com vrias novidades, como a capacidade de clique e arraste e o menu pop-up. Grande parte dos pesquisadores da Xerox foi contratada pela Apple, que evoluiu muito na rea grca, culminando na plataforma Macintosh (Figura 4.1), em 1983. De 1981 a 1984 a Apple transferiu muitos de seus conhecimentos a tcnicos da Microsoft para que estes desenvolvessem aplicaes para a plataforma Mac. A Microsoft, por sua vez, passou a desenvolver sua prpria interface grca, culminando no Windows 1.0, em 1985. Outras interfaces grcas surgiram naquela poca, como o Amiga e o X-Window, a interface grca para Unix desenvolvida pelo MIT (Massachusetts Institute of Technology).
102
4.2.2 Contineres
Um continer um widget que est apto a conter outro widget em seu interior. A maioria dos widgets, como GtkWindow, GtkTable e GtkBox, so tambm contineres. Suas propriedades so exatamente as mesmas que as de qualquer outro widget. Os contineres tambm podem ser adicionados a outros contineres. Eles, na verdade, so classes criadas pelo mecanismo de herana a partir de uma classe chamada GtkContainer, que, por sua vez, derivada da classe GtkWidget. Alguns dos contineres (widgets) mais utilizados so as caixas. A GtkVBox (Vertical Box), mostrada na gura 4.3, um continer onde os widgets contidos por ela seguem uma disposio vertical (um abaixo do outro). Contineres como GtkVBox no so visveis, so elementos estruturais, onde se percebe somente seu contedo, ordenado verticalmente.
103
A seguir, na gura 4.4, um exemplo de GtkHBox (Horizontal Box), no qual os elementos adicionados a ela cam dispostos horizontalmente (um ao lado do outro).
Existe a possibilidade de fazer vrias construes colocando caixas (Box) dentro de caixas, tabelas e frames, ou seja, construir a interface de forma recursiva. Na gura 4.5, existe uma grande GtkHBox. Dentro dela h duas outras caixas, uma GtkVBox (com dois elementos, um abaixo do outro) e uma GtkHBox ( direita), que, por sua vez, contm duas outras GtkVBox, cada uma com dois elementos dentro. Assim, percebe-se como construda a interface grca GTK utilizando contineres e widgets.
Outra forma de construir o visual da aplicao utilizar o continer GtkFixed, o qual permite denir coordenadas xas (absolutas) para os widgets contidos por ele. Veja na gura 4.6 uma janela contendo um GtkFixed. O aspecto de grade indica a possibilidade de xar os objetos em qualquer coordenada da janela.
104
4.2.3 Signals
Sinais so mensagens emitidas por widgets em resposta a aes do usurio. Quando se programam interfaces grcas (GUI), necessrio responder a essas aes, como o clique do mouse em um boto, o ato de selecionar um item de uma lista ou o ato de se fechar uma janela. O GTK faz isso por meio de sinais, que so emitidos para que o programa saiba que aconteceu algo. Quando um sinal emitido, possvel vincular esse evento execuo de uma funo (callback).
4.2.4 Callback
Callbacks so funes registradas pelo programador para reagir a sinais emitidos por widgets.Voc especica qual funo ser executada conectando a funo a um sinal emitido por determinado Widget. A seguir, apresentam-se alguns exemplos.
CAPTULO 5
Componentes diversos
A vida o que acontece enquanto voc est ocupado com outros projetos. (John Lennon)
Neste captulo sero tratados os mais diversos widgets do GTK, como botes, rtulos de texto, janelas, painis, caixas para entrada de dados, dilogos, exibio de imagens, combos, menus de ferramentas, notebooks, barras de status, frames, escalas e tabelas, entre outros.
A seguir, denimos a ao para o sinal destroy, por meio do mtodo connect_simple(). O sinal destroy emitido sempre que a janela fechada pelo usurio. Quando emitido, ser executada a funo onClose(), emitindo uma mensagem no console para o usurio e interrompendo a execuo da aplicao pela chamada do mtodo esttico Gtk::main_quit(). Veja, na gura 5.1, o resultado deste exemplo.
121
122
window.php
<?php /* * funo onClose * executada quando usurio fecha a janela */ function onClose() { echo "Volte logo !\n"; Gtk::main_quit(); } // cria janela principal $window = new GtkWindow; // define o tamanho $window->set_default_size(200,200); // define o ttulo $window->set_title('Primeira Janela'); // define o cone $window->set_icon(GdkPixbuf::new_from_file('icons/ico_smile.png')); // define a posio na tela $window->set_position(GTK::WIN_POS_CENTER); // define a ao a ser executada quando // o usurio fecha a janela $window->connect_simple('destroy', 'onClose'); // exibe a janela $window->show_all(); Gtk::main(); ?>
125
Denimos o texto contido pelo rtulo de texto no momento de sua criao (new). Em exemplos posteriores estudaremos mais a fundo os mtodos oferecidos pela classe GtkLabel. Neste primeiro momento, simplesmente adicionaremos o rtulo de texto na janela e o exibiremos. Veja na gura 5.4 o resultado deste exemplo.
Observao: A janela s comporta um widget por vez, com a utilizao do metodo add(), por isso adicionamos somente um rtulo de texto. Mais adiante, veremos como colocar mais widgets na janela com a utilizao de contineres como GtkVBox e GtkHBox.
label.php
<?php // cria janela principal $window = new GtkWindow; $window->set_default_size(200,200); $window->set_position(GTK::WIN_POS_CENTER); $window->set_title('Label'); // cria rtulo de texto $label = new GtkLabel('Al Mundo'); // adiciona rtulo de texto janela $window->add($label);
135
label_markup.php
<?php // cria janela principal $window = new GtkWindow; $window->set_position(GTK::WIN_POS_CENTER); $window->set_border_width(4); $window->set_default_size(200,200); // cria caixa vertical $vbox = new GtkVBox; // cria rtulo de texto em negrito // e adiciona-o caixa vertical $label = new GtkLabel; $label->set_markup('texto: <b>negrito</b>'); $vbox->pack_start($label); // cria rtulo de texto em itlico // e adiciona-o caixa vertical $label = new GtkLabel; $label->set_markup('texto: <i>italico</i>'); $vbox->pack_start($label);
140
botao_imagem.php
<?php // cria nova janela $window = new GtkWindow; // define tamanho e espaamentos $window->set_default_size(120,120); $window->set_border_width(20); $window->set_position(GTK::WIN_POS_CENTER); // cria caixa vertical $vbox = new GtkVBox; // cria boto $button = new GtkButton; $button->set_label('Configurar'); // cria objeto imagem $imagem = GtkImage::new_from_file('icons/ico_config.png'); // atribui a imagem ao boto $button->set_image($imagem); $vbox->pack_start($button); // cria boto $button = new GtkButton; $button->set_label('Meus Documentos');
162
5.6 Imagens
5.6.1 Imagem de arquivo
Neste pequeno exemplo, vemos como se d a exibio de imagens a partir de arquivo. Para exibir imagens, utilizamos o widget GtkImage, que realiza a leitura da imagem do disco pelo mtodo construtor new_from_file(). Ento podemos adicionar esse widget janela pelo mtodo add().Veja o resultado deste exemplo na gura 5.26. Veja, a seguir, a hierarquia da classe GtkImage:
GtkObject GtkWidget GtkMisc GtkImage
imagem_arquivo.php
<?php // cria janela principal $window = new GtkWindow; $window->set_default_size(200,200); // cria objeto imagem a partir de imagem PNG $imagem = GtkImage::new_from_file('icons/gnome.png'); // adiciona imagem janela $window->add($imagem); // exibe janela $window->show_all(); gtk::main(); ?>
176
5.8.3 Notebook
Notebooks so contineres muito utilizados, pois dividem as janelas em abas e permitem que cada uma delas contenha vrios outros contineres e widgets. Trabalhamos com notebooks no dia a dia no editor de textos, no navegador Web etc. Veja, a seguir, a hierarquia da classe GtkNotebook:
GtkObject GtkWidget GtkContainer GtkNotebook
No exemplo apresentado na gura 5.34 temos um notebook com as abas localizadas esquerda, contendo duas pginas. Cada pgina, alm de um rtulo de texto, ter um pequeno cone identicando-a. Isso porque o notebook permite que utilizemos qualquer widget como ttulo da aba. O mtodo append_page(), responsvel pela adio de uma aba, recebe dois parmetros: o primeiro o contedo e o segundo, o ttulo da aba.
No exemplo a seguir, no mtodo construtor, criada a janela principal e tambm o objeto da classe GtkNotebook. Ento o objeto inserido dentro da janela. O mtodo set_tab_pos() dene a posio das abas (nesse caso, esquerda). Os mtodo addPage1() e addPage2() so utilizados aqui para acrescentar o contedo de cada aba do notebook. No necessrio dividir o programa em mtodos para denirmos o contedo de cada aba do notebook. Fizemos isso aqui para organizarmos melhor o cdigo do programa. O mtodo addPage1() acrescenta o contedo primeira aba do notebook. Para tal, cria um frame (GtkFrame) com o contedo Conteudo 1 O mtodo append_page() . responsvel por acrescentar uma aba ao notebook. Ele recebe o contedo como primeiro parmetro e o ttulo da aba como segundo. Nesse caso, no lugar de usarmos somente uma aba como rtulo do notebook, estamos usando como aba uma caixa vertical contendo uma imagem e um texto e somente por isso o exemplo se tornou mais complexo.
CAPTULO 6
Escolha um trabalho que ame e no ter que trabalhar um nico dia em sua vida. (Confcio)
Neste captulo abordaremos trs tpicos importantes que merecem ser estudados parte exibio de textos, listas e rvores. Esse assunto merece destaque, pois envolve um importante conceito da engenharia de software, o padro Model,View, Controller, que veremos a seguir.
209
214
$textbuffer->apply_tag($times, $start, $end);
// cria objeto imagem a partir de imagem PNG $pixbuf = GdkPixbuf::new_from_file('icons/gnome.png'); // inserindo o objeto pixbuf $textbuffer->insert_pixbuf($textbuffer->get_end_iter(), $pixbuf); // adiciona o TextView janela de rolagem $scroll->add($textview); // adiciona a janela de rolagem janela $window->add($scroll); // exibe janela $window->show_all(); Gtk::main(); ?>
O conceito mais importante que envolve GtkTreeView a completa separao entre os dados e a forma pela qual estes so exibidos em tela. Os dados, sejam eles nmeros, textos ou imagens, so armazenados em um modelo, que pode ser GtkListStore (para armazenar listas) e GtkTreeStore (para armazenar rvores). O modelo de dados atribudo a alguma visualizao (GtkTreeView). Sempre que o modelo de dados alterado, automaticamente sua exibio atualizada em tela, por sua
224
O modelo de dados carregado pela leitura de um vetor contendo a localizao da imagem da bandeira do pas e as demais informaes. Quando o usurio clicar com qualquer boto do mouse, o sinal button-release-event disparado e o mtodo onClick(), executado, exibindo um menu pop-up com as opes Informao e Excluir . Caso o usurio escolha a opo Informao o mtodo onShowInfo() executado, , exibindo a quarta coluna do modelo relativa ao iterador (linha clicada), essa coluna (que a princpio no estava sendo exibida) contm justamente o pas campeo. Caso o usurio escolha a opo Excluir o mtodo onDeleteIter() executado, apagando , o iterador (linha clicada).Veja o resultado desse exemplo na gura 6.8.
O exemplo inicia assim como o exemplo anterior, com a criao da janela principal e com a criao de uma lista (GtkTreeView). Nesse caso, conectamos o sinal button-release-event da lista ao mtodo onClick().Assim, sempre que o usurio clicar em um boto do mouse sobre um elemento da lista, esse mtodo ser executado. Logo em seguida, so criadas trs colunas (GtkTreeViewColumn) e elas so adicionadas lista por meio do mtodo append_column(). No mtodo construtor da GtkTreeViewColumn podemos j indicar o ttulo da coluna, o renderizador que ir exibi-la, o atributo e o ndice do modelo que ser exibido naquela coluna. Ento, declarada uma matriz contendo os dados que sero inseridos na lista. Esses dados sero percorridos por um foreach e adicionados ao modelo, que possui quatro colunas, a ltima coluna no exibida na lista. Quando o usurio clicar com qualquer boto do mouse sobre a lista, o mtodo onClick() executado. Esse mtodo testa qual boto do mouse foi clicado. Se for o boto 3 (boto direito), criado um menu de opes (GtkMenu) e este apresentado ao usurio por meio do mtodo popup(). Duas opes sero disponibilizadas nesse
237
Esse exemplo possui mais algumas peculiaridades. Note que existem dois renderizadores empacotados na mesma coluna. H somente uma GtkTreeViewColumn contendo um renderizador para imagens (GtkCellRendererPixbuf) e outro para textos (GtkCellRendererText). Nesse caso, vamos fazer uma analogia com o sistema de arquivos do computador, suas pastas e seus arquivos. Para tanto, o modelo de dados possui trs colunas: um objeto (imagem pixbuf) com o cone do arquivo, um texto com o nome do arquivo e outro com a sua localizao. Entretanto, essa terceira coluna do modelo de dados no ser exibida por um renderizador. Sempre que o usurio disparar um duplo clique sobre uma linha da rvore, o mtodo onDoubleClick() ser executado e a localizao do arquivo (terceira coluna do modelo de dados), exibida na tela em forma de dilogo. Veja o resultado desse exemplo na gura 6.10.
No mtodo construtor do exemplo criamos a janela da aplicao e posteriormente o objeto GtkTreeView e o objeto GtkTreeStore, que armazenar os dados da rvore. Conectamos o duplo-clique do mouse (representado pelo sinal row-activated) ao mtodo onDoubleClick(). Como explicado anteriormente, nesse exemplo teremos dois renderizadores: um de imagem (GtkCellRendererPixbuf) e um de texto (GtkCellRendererText). Os dois renderizadores sero colocados dentro da mesma coluna ($column1). Posteriormente essa coluna adicionada rvore por meio do mtodo append_column(). Em seguida, algumas imagens so lidas e armazenadas em objetos GdkPixbuf.
238
Os nodos so acrescentados na rvore aps vrias chamadas do mtodo append(). O primeiro parmetro do mtodo append() representa o elemento ao qual desejamos inserir um outro como lho. Se esse parmetro for vazio, estamos adicionando um elemento no topo da rvore. O mtodo onDoubleClick(), executado quando o usurio clica duplamente sobre um elemento, simplesmente exibe a terceira coluna do modelo de dados, que contm a localizao do arquivo.
tree_simples.php
<?php /* * classe ExemploTreeSimples * Todo exemplo est aqui contido */ class ExemploTreeSimples { private $window; private $tree; private $model; /* * Mtodo Construtor * Cria Janela principal */ public function __construct() { // cria janela principal $this->window = new GtkWindow; $this->window->set_title('rvores'); $this->window->connect_simple('destroy', array('gtk', 'main_quit')); $this->window->set_default_size(320,280); $this->window->set_position(GTK::WIN_POS_CENTER); // cria janela de rolagem $scroll = new GtkScrolledWindow; $scroll->set_policy(GTK::POLICY_AUTOMATIC, GTK::POLICY_ALWAYS); // cria rvore e adiciona no scroll $this->tree = new GtkTreeView; $scroll->add($this->tree); // define a ao para o duplo clique $this->tree->connect('row-activated', array($this, 'onDoubleClick')); // cria modelo de dados e atribui rvore $this->model = new GtkTreeStore(GObject::TYPE_OBJECT, GObject::TYPE_STRING, GObject::TYPE_STRING); $this->tree->set_model($this->model);
CAPTULO 7
Estendendo o GTK
impossvel para um homem aprender aquilo que ele acha que j sabe. (Epteto)
O desenvolvimento de sistemas com base em objetos consiste em criar o sistema sob a ptica do mundo real, criando as entidades (objetos) com comportamentos especcos (atributos/mtodos), de modo que interajam uns com os outros. So diversas as vantagens de se utilizar a orientao a objetos no desenvolvimento de aplicaes. Desde a similaridade dos objetos com a nossa percepo do mundo real, facilitando o entendimento do sistema e sua provvel manuteno; a reusabilidade proporcionada pela forma de organizao do sistema por meio de uma hierarquia; o encapsulamento, que trata da proteo de acesso s caractersticas internas de cada objeto, at a elegncia do cdigo, que tende a car mais enxuto, organizado e de fcil compreenso.
7.1 Herana
Herana em orientao a objetos um mecanismo que nos proporciona o compartilhamento de atributos e mtodos entre as classes de uma mesma hierarquia (rvore). As classes inferiores da hierarquia automaticamente herdam todas as propriedades e mtodos das classes superiores, chamadas de superclasses. Utilizando a herana, em vez de criarmos uma estrutura totalmente nova (uma classe), podemos reaproveitar uma estrutura j existente, que nos fornea uma base abstrata para o desenvolvimento, provendo recursos comuns. As classes GTK representam bem o conceito de herana, na qual as classes-lha da estrutura de rvore vo renando o comportamento das suas classes ancestrais (superclasses), adicionando novos mtodos. As classes GtkColorButton, GtkFontButton e GtkToggleButton, por exemplo, so todas lhas da classe GtkButton, pois possuem comportamento semelhante. Assim, todos os mtodos e atributos existentes na classe
241
243
Utilizando a classe
Agora demonstraremos a utilizao dessa classe criada, exibindo uma mensagem na tela. Veja o resultado do exemplo na gura 7.1.
TMessage.teste.php
<?php // inclui a classe criada include_once 'TMessage.class.php'; // emite mensagem informativa new TMessage('info', 'Warning: Saldo insuficiente !!'); // emite mensagem de erro new TMessage('error', 'Kernel Panic !!'); ?>
247
Utilizando a classe
Agora demonstraremos a utilizao dessa classe criada. No exemplo, solicitaremos ao usurio que digite seu nome. Caso ele clique em OK, o nome ser impresso no console. Veja o resultado do exemplo na gura 7.3.
TInputBox.teste.php
<?php // inclui a classe TInputBox include_once 'TInputBox.class.php'; // instancia TInputBox $dialogo = new TInputBox('ttulo da janela', 'Digite o Nome', '<digite aqui>'); // verifica resposta $resposta = $dialogo->run(); // se resposta for sim... if ($resposta == Gtk::RESPONSE_OK) { // imprime o contedo digitado echo $dialogo->get_text(); } ?>
249
Utilizando a classe
Agora demonstraremos a utilizao dessa classe criada. Para tanto, criaremos uma classe contendo uma janela e trs botes, cada qual com uma imagem diferente e uma respectiva ao. Veja o resultado desse exemplo na gura 7.4.
TImageButton.teste.php
<?php // inclui a classe criada include_once 'TImageButton.class.php'; /* * Classe ExemploBotao * Demonstra o uso da classe criada */ class ExemploBotao { /* * mtodo construtor * cria a janela com os botes */ function __construct() { $janela = new GtkWindow; $hbox = new GtkHbox; // cria os botes com imagem $botao1 = new TImageButton('Home', 'images/home.png', array($this, 'onHome')); $botao2 = new TImageButton('Config', 'images/config.png', array($this, 'onConfig')); $botao3 = new TImageButton('Imprime','images/print.png', array($this, 'onImprime')); $hbox->pack_start($botao1); $hbox->pack_start($botao2); $hbox->pack_start($botao3); $janela->add($hbox); $janela->show_all(); } // ao do boto Home function onHome() { echo "Clicou no Home\n"; } // ao do boto Config function onConfig() { echo "Clicou no Config\n"; } // ao do boto Imprime
257
Utilizando a classe
Agora ser mostrado a utilizao dessa classe criada. Para tanto, faremos um formulrio de cadastro de pessoas. Quando o usurio clicar no boto Salvar os , dados digitados no formulrio sero exibidos no console. Veja o resultado desse exemplo na gura 7.6.
Neste exemplo, em seu mtodo construtor criamos uma janela e vrios objetos ($codigo, $nome, $endereco), alm de um boto $salvar. Logo em seguida utilizamos a classe recm-criada TForm. Para cada objeto, utilizamos o mtodo addField() para adicionar o campo ao formulrio, identicando seu nome, seu rtulo de texto, o objeto e o tamanho.Ao nal, o formulrio exibido por meio do mtodo show(). Alguns dados iniciais so denidos para o formulrio por meio do mtodo setData(). Sempre que o usurio clicar no boto de ao, o mtodo onSave() ser executado. Esse mtodo coleta os dados do formulrio por meio do mtodo getData() e exibe esses dados no console.
TForm.teste.php
<?php include_once 'TForm.class.php'; /* * classe ExemploForm * criada para demonstrar a utilizao de formulrios */ class ExemploForm { private $form; // contm o objeto formulrio /* * mtodo construtor, cria a janela */ function __construct() { $janela = new GtkWindow; $janela->set_size_request(470,200);
258
// cria alguns campos para o formulrio $codigo = new GtkEntry; $nome = new GtkEntry; $endereco = new GtkEntry; $telefone = new GtkEntry;
// cria o boto de ao do formulrio $salvar = GtkButton::new_from_stock(Gtk::STOCK_SAVE); $salvar->connect_simple('clicked', array($this, 'onSave')); // cria o formulario com seus campos $this->form = new TForm; $this->form->addField('codigo', 'Cdigo', $this->form->addField('nome', 'Nome', $this->form->addField('endereco', 'Endereo', $this->form->addField('telefone', 'Telefone', $this->form->addSeparator('Ao'); $this->form->addField('salvar', 'Salvar', $this->form->show(); // define alguns dados iniciais $dados_iniciais->codigo = '1'; $dados_iniciais->telefone = '(51) XXXX-XXXX'; $this->form->setData($dados_iniciais); // adiciona o form na janela $janela->add($this->form); $janela->show_all(); } /* * mtodo onSave * simula a ao de salvar os dados do form */ function onSave() { // obtm os dados do formulrio $objeto = $this->form->getData(); // exibe os dados echo "Cdigo: " echo "Nome: " echo "Endereo: " echo "Telefone: " no console . $objeto->codigo . "\n"; . $objeto->nome . "\n"; . $objeto->endereco . "\n"; . $objeto->telefone. "\n";
CAPTULO 8
melhor estar preparado para uma oportunidade e no ter nenhuma, do que ter uma oportunidade e no estar preparado. (Whitney Young Jr.)
Neste captulo sero tratados os aspectos relativos manipulao de banco de dados, como realizar conexes, consultas, inserir dados e extrair relatrios, dentre outros. O PHP possui suporte nativo maioria dos bancos de dados utilizados hoje. Voc pode utilizar o PHP com o Postgres, Oracle, SqlServer, Firebird, DB2, MySql e outros. Como o interesse de muitos que desenvolvem uma aplicao-cliente em PHP-GTK a fcil distribuio da aplicao, os exemplos deste captulo tero como base a utilizao do Sqlite, que um banco de dados simples em formato de arquivos. O Sqlite no precisa de instalao, basta ser compactado junto com a aplicao, o que torna sua distribuio extremamente simples.
CREATE TABLE
Permite criar uma nova tabela no banco de dados, identicando-se seu nome e sua estrutura.
CREATE TABLE <tabela> (<nome_coluna><tipo_coluna>, ...)
Parmetros tabela
276
279
No mtodo construtor da classe, criamos a janela principal e uma caixa vertical onde teremos os campos do formulrio. Para criar os campos do formulrio denimos dois vetores: $this->labels para armazenar os rtulos de texto do formulrio e $this->campos para armazenar os campos. Depois de denir os campos, percorremos estes por meio de um foreach() que criar, para cada campo, uma caixa horizontal e ir acrescentar essa caixa em uma caixa vertical. Por m, ainda dentro do mtodo construtor criamos dois botes: o primeiro de salvar, que executar o mtodo onSaveClick(), e o segundo de fechar, que
280
executar o mtodo hide() da janela. Ainda no mtodo construtor executamos o mtodo criaBanco(), que responsvel por criar o banco SQLite caso este no exista. . O mtodo criaBanco() verica a existncia do banco de dados dados.db Caso esse arquivo no exista, ele criado pela funo sqlite_open(). Logo em seguida, uma instruo SQL para criao da tabela de pessoas executada. O mtodo onSaveClick() executado sempre que o usurio clicar no boto de salvar. Esse mtodo coleta os dados digitados pelo usurio no formulrio e alimenta um objeto chamado $pessoa. Esse objeto utilizado na formao da string SQL armazenada na varivel $sql e que executada por meio do mtodo sqlite_query(), inserindo o registro no banco de dados. Ao nal, o mtodo Clear() executado. O mtodo Clear() responsvel por limpar os campos do formulrio e posicionar o cursor da janela no primeiro campo do formulrio.
NovaPessoa.class.php
<?php /** * Classe NovaPessoa * Contm todo formulrio de cadastro */ class NovaPessoa { private $window; private $campos; private $labels; /** * Mtodo construtor * Encapsula a aplicao, cria janela e formulrio */ public function __construct() { // cria janela $this->window = new GtkWindow; $this->window->set_title('Incluir'); $this->window->connect_simple('destroy', array($this->window, 'hide')); $this->window->set_default_size(540,280); $this->window->set_border_width(10); $this->window->set_position(GTK::WIN_POS_CENTER); $vbox = new GtkVBox; // cria um array com os rtulos de texto // e os campos do formulrio $this->labels['codigo'] = new GtkLabel('<span foreground="red"><b> Cdigo: </b></span>'); $this->campos['codigo'] = new GtkEntry; $this->campos['codigo']->set_size_request(80,-1); $this->labels['nome'] = new GtkLabel('Nome: '); $this->campos['nome'] = new GtkEntry;
284
O exemplo inicia no mtodo construtor, onde criamos a janela principal, uma janela de rolagem e adicionamos em seu interior uma lista (GtkTreeView). Essa lista estar vinculada a um modelo (GtkListStore) com quatro colunas do tipo string. Essas quatro colunas so objetos GtkTreeViewColumn, como j vimos no captulo 6. Cada coluna representada por um renderizador GtkCellRendererText. Quando o usurio editar os dados de alguma coluna, ser executado o mtodo onEdit(), o que denido quando conectamos o sinal edited do renderizador. Para que as colunas possam ser editadas, necessrio habilitar a propriedade editable de cada renderizador. Ainda no mtodo construtor, denimos a largura das colunas, relacionamos quais dados do modelo sero exibidos e adicionamos as colunas lista pelo mtodo append_column(). Abaixo da lista existiro dois botes: excluir, que estar ligado ao mtodo onDelete(), e fechar, que estar ligado ao mtodo hide() da janela. Essa classe ter um mtodo Show() que se encarregar de carregar os dados da listagem e exibir a janela. Os dados so carregados pelo mtodo exibeDados(), que abre uma conexo com o banco de dados sqlite por meio do mtodo sqlite_open(), realiza
CAPTULO 9
Utilizando o Glade
Desenvolver aplicaes que envolvam muitas interfaces com o usurio pode dar muito trabalho caso tenha de lidar com todos os aspectos no cdigo-fonte, declarando objetos, empacotando widgets dentro de contineres e ajustando os tamanhos manualmente. Podemos criar classes para automatizar a criao de formulrios e listagens, mas, mesmo assim, em algum momento, precisaremos criar uma janela com alguns botes de forma rpida e simples. Para tais casos, existe o Glade.
9.1 Introduo
O Glade uma ferramenta cujo objetivo desenhar interfaces para programas que utilizam a biblioteca GTK. O Glade pode ser utilizado com Python, PHP, C, Ruby, dentre outras linguagens que suportam o GTK. O Glade em si no um ambiente RAD como o Delphi ou o Visual Basic, por exemplo. Seu objetivo no integrar o desenho da aplicao com a escrita de cdigo e execuo. Por meio dele, podemos facilmente criar janelas, listas, botes, caixas e organiz-los de uma forma simples. Ao nal, este esquema da interface salvo em um arquivo com a extenso .glade que nada mais do que um arquivo XML contendo a estrutura , visual da interface. Esses arquivos salvos pelo Glade podem ser interpretados a partir de nosso cdigo-fonte em PHP, disponibilizando para o sistema todos os widgets e contineres desenhados por ele. Dessa forma, podemos abstrair os detalhes de construo visual da aplicao e nos concentrar apenas na lgica. A seguir, na gura 9.1, temos a janela principal do Glade e suas opes bsicas (Abrir e Salvar), alm das opes do projeto e a lista de cada janela projetada. No menu Editar dispomos das opes como Recortar, Copiar e Colar, enquanto no menu Exibir, h opes para exibir/esconder janelas, dentre outros.
305
306
324
Por ltimo, inserimos um boto chamado Publica na parte inferior da janela, como mostrado na gura 9.29. O nome dado ao boto na janela de propriedades tambm ser publica e o nome, utilizado para posteriormente resgatar o boto no cdigo da aplicao, tal como ser feito com todos os componentes j criados.
Tendo ainda o boto selecionado, na janela de propriedades temos a guia sinais , onde h uma listagem de todos os sinais que podero ser habilitados para o boto recm-criado. Selecionamos o sinal clicked para, no passo seguinte, registrar uma funo que responder ao sinal, cujo nome ser onPublica, como pode ser visto na gura 9.30.
325
publica.php
<?php /* classe Publica * Contm todo cdigo que manipulada * o arquivo Glade e interage com o usurio */ class Publica extends GladeXML { /* mtodo construtor * L o Glade e disponibiliza * os widgets como propriedades */ function __construct($arquivo_glade) { // carrega o glade parent::__construct($arquivo_glade); // conecta os seus sinais mtodos desta classe parent::signal_autoconnect_instance($this); // carrega os widgets $this->titulo = parent::get_widget('titulo'); $this->autor = parent::get_widget('autor'); $this->email = parent::get_widget('e-mail'); $this->data = parent::get_widget('data'); $this->fonte = parent::get_widget('fonte'); $this->url = parent::get_widget('url'); $this->noticia= parent::get_widget('noticia'); } /* mtodo onPublica * L o contedo digitado nos widgets * e adiciona em um arquivo HTML */ function onPublica() { // l os contedos digitados $titulo = $this->titulo->get_text();
328
CAPTULO 10
Extras
A sabedoria da vida no est em fazer aquilo que se gosta, mas gostar daquilo que se faz. Leonardo da Vinci
Aqui sero tratados vrios assuntos que no foram cobertos pelos captulos anteriores. Assim, esperamos atender a uma srie de outras necessidades do programador ao desenvolver uma aplicao em PHP-GTK, oferecendo-lhe este captulo extra .
340
Captulo 10 Extras
345
10.3 Relgio
Neste exemplo, h um relgio digital formado por um objeto GtkLabel. Essa funcionalidade possvel graas ao uso da funo date(), que retorna a hora atual j no formato correto, em conjunto com a funo Gtk::timeout_add(), a qual agenda a execuo de uma funo qualquer para daqui a XX milissegundos. Veja o resultado desse exemplo na gura 10.3.
Logo aps a denio da funo AtualizaClock(), o programa inicia com a criao da janela principal. Logo em seguida criamos um rtulo de texto e o adicionamos janela. Ento programamos para daqui a 1 milissegundo a execuo do mtodo
AtualizaClock().
O mtodo AtualizaClock() atribui a hora atual ao objeto $label, mediante seu mtodo set_markup() e, logo em seguida, agenda uma nova execuo para daqui a 1 segundo. Como o mtodo AtualizaClock() agenda sua prpria execuo, ele ca executando permanentemente enquanto a aplicao est ativa.
timer.php
<?php /* * funo AtualizaClock * Atualiza a hora do relgio */ function AtualizaClock() { global $label; // exibe a hora atual no Label $label->set_markup('<b>'. date("h:i:s") . '</b>'); // Programa nova execuo para daqui h 1 segundo Gtk::timeout_add(1000, 'AtualizaClock'); // a cada decimo de segundo } // cria janela principal $janela = new GtkWindow; $janela->set_position(GTK::WIN_POS_CENTER); $janela->set_default_size(200,100);
346
// cria rtulo de texto $label = new GtkLabel; // adiciona rtulo janela $janela->add($label); // exibe janela $janela->show_all(); // executa Atualiza Clock em 1 mili-segundo Gtk::timeout_add(1, 'AtualizaClock'); Gtk::Main(); ?>
O exemplo inicia com a criao da janela principal. Conectamos o sinal key-press-event que emitido sempre que o usurio pressionar qualquer tecla , execuo do mtodo onKeyPress().
Captulo 10 Extras
// instancia Exemplo new ExemploListaStock; Gtk::Main(); ?>
359
Nesse exemplo, criamos uma janela e conectamos o seu sinal delete-event ao mtodo onClose(). O sinal delete-event emitido quando o usurio clica no boto para fechar a janela. Quando o usurio clicar no boto para fechar a janela, o mtodo onClose() ser executado. Esse mtodo abre uma caixa de dilogo e pergunta ao usurio se ele deseja fechar a janela. Caso sim, o mtodo retorna false e, neste caso, o programa segue a execuo para o sinal destroy que por sua vez est conectado com o mtodo , Gtk::main_quit() abortando a aplicao. Caso o usurio escolher no fechar a janela, esse mtodo retorna true e o programa segue sua execuo normal.
376
Em seguida denimos qual ser a coluna do modelo que representar a imagem do cone por meio do mtodo set_pixbuf_column() e qual representar o texto exibido junto ao cone por meio do mtodo set_text_column(). Tambm denimos a largura das colunas do GtkIconView por meio do mtodo set_item_width() e exibimos a janela da aplicao. Quando o mtodo onSelect() for executado, simplesmente obteremos do modelo de dados o elemento atual selecionado e exibimos este no console por meio da funo var_dump(). Para tal, o mtodo onSelect(), que uma resposta ao evento item, activated recebe como segundo parmetro o caminho do elemento selecionado ($path), que nos pemite obter o iterador que aponta para o elemento selecionado por meio do mtodo get_iter().
iconview.php
<?php // cria a janela $janela = new GtkWindow(); $janela->set_title('GtkIconView'); $janela->set_default_size(500, 300); $janela->connect_simple('destroy', array('Gtk', 'main_quit')); // cria a iconview e o modelo $iconview = new GtkIconView(); $model = new GtkListStore(GdkPixbuf::gtype, GObject::TYPE_STRING); $iconview->set_model($model); // cria janela de rolagem $scroll = new GtkScrolledWindow(); $scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
Captulo 10 Extras
379
Ao nal, inserimos um trecho de cdigo bsico PHP (abertura e fechamento de cdigo) por meio do mtodo insert_at_cursor() e exibimos a janela principal. Na gura 10.19, podemos ver o programa em execuo (j com algum contedo digitado pelo usurio).
teste-sourceview.php
<?php $janela = new GtkWindow; $scroll = new GtkScrolledWindow; $sourceview = new GtkSourceView; $janela->set_size_request(700, 400); $janela->set_position(Gtk::WIN_POS_CENTER); $janela->add($scroll); $scroll->add($sourceview); $buffer = new GtkSourceBuffer; $sourceview->set_buffer($buffer); $manager = new GtkSourceLanguagesManager; $lang = $manager->get_language_from_mime_type('application/x-php'); $buffer->set_language($lang); $buffer->set_highlight(true); $buffer->set_check_brackets(TRUE); $sourceview->set_auto_indent(TRUE); $sourceview->set_insert_spaces_instead_of_tabs(TRUE); $sourceview->set_tabs_width(4); $sourceview->set_show_line_numbers(true); $sourceview->set_highlight_current_line(TRUE);