KDevelop"> ]> O Manual de Programação do &tdevelop; 2002-12-05 2.0 Ralf Nolden
Ralf.Nolden@post.rwth-aachen.de
Caleb Tennis
caleb@aei-tech.com
1999 Ralf Nolden 2002 Caleb Tennis &FDLNotice; O Guia de Utilizador para o Desenho de Aplicações em C++ para o Ambiente de Trabalho K (KDE) com o IDE &tdevelop; KDE KDevelop IDE desenvolvimento programação
Introdução À medida que os Sistemas Unix se tornam cada vez mais populares, até para principiantes no uso de computadores, devido às suas vantagens no que toca à estabilidade e funcionalidade, muitas pessoas ficam desiludidas, porque muita aplicações não tem uma aparência consistente e cada uma se comporta de uma forma diferente. Com o KDE, as equipas de desenvolvimento tem um modo quase perfeito de criar aplicações para estações de trabalho Unix, obtendo um maior comunidade de utilizadores meramente devido à qualidade das suas aplicações. Desta forma, o KDE tem-se tornado cada vez mais popular como base de programação, e os programadores querem tomar partido das possibilidades que o sistema tem para oferecer. O que já deve saber Para utilizar este manual de programação da melhor forma possível, assumimos que já está familiarizado com a linguagem de programação C++; se não, deve aprendê-la primeiro. Informações acerca do C++ está disponível através de várias fontes, quem em formato impresso na sua livraria local, quer em tutoriais que pode encontrar na Internet. Não são necessário conhecimentos de desenho de Interfaces Gráficas de Utilizador, uma ver que este manual tenta cobrir o desenho de aplicações KDE, o que também incluí uma introdução ao Qt bem como às bibliotecas KDE e ao desenho de Interfaces de Utilizador. Também, deve aprender a utilizar o &tdevelop;, lendo o Manual de Utilizador do &tdevelop;, que contém uma descrição das funcionalidades do ambiente de programação. Acerca deste Manual Esta manual foi escrito para dar ao programadores um introdução ao desenvolvimento de aplicações KDE utilizando o Ambiente Integrado de Desenvolvimento KDevelop. Os capítulos seguintes começam por uma introdução como criar projectos, explicam o código fonte já gerado e mostram como extender o código dado com barras de ferramentas, barras de menu e áreas de visualização. Em seguida o editor de diálogo é discutido em detalhe, explicando como os 'widgets' são criados e cobre a configuração das propriedades de 'widgets' em detalhe. Finalmente, você irá aprender sobre vários tópicos que irão completar o seu conhecimento no que respeita ao desenho de projectos e o ajudará a lidar com os tópicos adicionais para além da codificação, como a adição de documentação da API ou extender os manuais 'online'. No próximo capítulo Iremos dar uma vista de olhos nas bibliotecas do Qt e do KDE, mostrando os conceitos básicos e porque é que as coisas são assim. Também iremos discutir como criar as aplicações tutoriais que vêm com a plataforma do Qt, usando o &tdevelop;, para que os principiantes possam ver logo primeiros resultados com alguns passos, e deste modo aprender como tirar partido de algumas das melhores funcionalidades do &tdevelop;. Nos capítulos seguintes Irá aprender a: criar uma aplicação com o KAppWizard O que o esqueleto do projecto já fornece O que o código já criado significa Como criar as suas próprias vistas Como expandir a funcionalidade da sua aplicação utilizador diálogos, barras de menu e barras de ferramentas Como tornar a sua aplicação fácil de utilizar criando funções de ajuda Como escrever documentação electrónica Dados Adicionais Mais informações acerca de programação em Qt/KDE está disponível em várias fontes: Programar com o Qt por Matthias Kalle Dalheimer O Manual de Utilizador do KDevelop, fornecido com o IDE KDevelop A Referência Electrónica da biblioteca Qt A página web para Programadores do KDE Adicionalmente, você deverá procurar alguma ajuda, subscrevendo-se nas várias listas de correio, cujos endereços estão disponíveis nos 'sites' Web acima mencionados, ou nos fóruns de discussão dedicados aos utilizadores do KDE e dos Sistemas UNIX, assim como sobre as linguagens de programação C e C++. Para obter ajuda sobre o IDE KDevelop, você deverá enviar pedidos para a nossa lista de correio em kdevelop@kdevelop.org. Lembre-se que a equipa do KDevelop está dedicada a fornecer os meios que lhe permitam programar aplicações e, por isso, não pretende ser uma equipa de suporte técnico para os casos em que as aplicações que você desenvolve não funcionam devido a erros de implementação ou más configurações do seu sistema operativo. Com isto, pedimos a todos os utilizadores para tirarem partido da lista de correio em qualquer caso em que tenham problemas com a utilização do próprio IDE, assim como para enviarem erros e sugestões para melhorarem a funcionalidade do ambiente de desenvolvimento. As bibliotecas KDE e Qt A equipa norueguesa TrollTech (http://www.trolltech.com) oferece uma plataforma GUI chamada Qt. GUI significa "Graphical User Interface" ou "Interface Gráfica de Utilizador" e, como tal, as aplicações baseadas em Qt representam-se a si próprias com botões, janelas, etc, permitindo a interacção com o utilizador através da visualização das funções que uma aplicação fornece. Uma plataforma deste género é necessária para desenvolver aplicações gráficas que funcionem na interface X-Windows dos sistemas Unix, dado que o X não contém uma interface de utilizador por si só. Ainda que existam outras plataformas disponíveis para criar Interfaces de Utilizador, o Qt oferece algumas vantagens técnicas que tornam o desenho de aplicações muito simples. Para além disso, a plataforma do Qt está também disponível para os sistemas Microsoft Windows, o que permite aos programadores fornecerem as suas aplicações para ambas as plataformas. A Equipa do KDE (http://www.kde.org) juntou-se em conjunto com o objectivo de tornar os Sistemas Unix mais amigáveis e decidiu usar a plataforma do Qt para o desenvolvimento de um gestor de janelas no X-Windows, em conjunto com uma variedade de ferramentas incluídas nos pacotes do KDE. O Ambiente de Trabalho K contém, deste modo, o gestor de janelas 'twin', o gestor de ficheiros e navegador 'konqueror' e o painel 'kicker' como componentes principais, para além de um conjunto de utilitários e aplicações de primeira classe. Depois de o KDE ter saído, vários programadores começaram a olha para o novo ambiente e para o que ele tem para lhes oferecer. As bibliotecas do KDE estão a fornecer métodos e classes essenciais que tornam todas as aplicações desenhadas com eles similares e consistentes, de modo a que o utilizador tenha a grande vantagem de só ter de se acostumar com a utilização específica de uma aplicação e não com a utilização de janelas e botões. Da mesma forma, os programas do KDE integram-se no ambiente de trabalho e conseguem interagir com o gestor de ficheiros com 'Drag and Drop' (Arrastar e Largar', tendo também a gestão de sessões entre muitas outras coisas, se forem usadas as funcionalidades oferecidas pelas bibliotecas do KDE. Tanto a plataforma do Qt com as bibliotecas do KDE são implementadas na linguagem de programação C++; como tal, as aplicações que tiram partido destas bibliotecas são também feitos em grande medida em C++. No capítulo seguinte, iremos fazer uma breve viagem pelas bibliotecas para ver o que já é oferecido e como é que as aplicações do Qt e do KDE são criadas de um modo geral. Tanto a plataforma do Qt como as bibliotecas do KDE estão implementadas na linguagem de programação C++; como tal, as aplicações que tiram partido dessas bibliotecas também são em grande parte feitas em C++. No capítulo seguinte, iremos fazer uma viagem rápida pelas bibliotecas para ver o que já é fornecido e como é que as aplicações do Qt e do KDE são criadas, de um modo geral. A Plataforma Gráfica Qt Como foi dito, a biblioteca Qt é uma ferramenta que oferece elementos gráficos usados para criar aplicações gráficas e que são necessários para programar no X-Windows. Para além disso, a plataforma oferece: Um conjunto completo de classes e métodos prontos a utilizar mesmo para programação não gráfica Um boa solução para a interacção com o utilizador através de métodos virtuais e o mecanismo signal/slot Um conjunto de elementos gráficos predefinidos, chamados "widgets", que podem ser utilizador para criar facilmente os elementos visíveis Para além disto diálogo completamente predefinidos são muito utilizados nas aplicações, tais como janelas de evolução e de ficheiros Por isso, conhecer as classes do Qt é bastante essencial, mesmo que só queira programar aplicações para o KDE. Para ter uma noção básica sobre como as aplicações gráficas são criadas e compiladas, iremos ver primeiro um exemplo de um programa só em Qt; depois, extendê-lo-emos para um programa do KDE. A primeira aplicação Qt Como é normal, os programas em C++ têm de conter uma função main(), que é o ponto inicial da execução das aplicações. Como pretendemos que estas sejam visíveis graficamente como janelas e que ofereçam alguma interacção com o utilizador, teremos de saber como é que elas se apresentam ao utilizador. Por exemplo, iremos ver o primeiro tutorial incluído com a Documentação de Referência 'Online' do Qt e explicar os passos de execução básicos; também iremos explicar porque e como é que a janela da aplicação aparece: #include <qapplication.h> #include <qpushbutton.h> int main( int argc, char **argv ) { QApplication a( argc, argv ); QPushButton ola( "Olá mundo!", 0 ); ola.resize( 100, 30 ); a.setMainWidget( &ola ); ola.show(); return a.exec(); } Esta aplicação apenas desenha uma janela com um botão com o texto "Olá mundo". Como para todas as aplicações baseadas em Qt, tem que primeiro criar uma instância da classe QApplication, representada pela variável a. Em seguida, o programa cria uma instância da classe QPushButton chamada hello, isto vai ser o botão. O construtor de hello recebe uma cadeia de caracteres como parâmetro, que é o conteúdo do widget, o texto do botão. Depois, o método resize() é chamado sobre o botão 'ola'. Isto irá mudar o tamanho por omissão que um item gráfico (neste caso, o QPushButton) tem quando é criado para uma largura de 100 pixels e uma altura de 30. Finalmente, o método setMainWidget() é chamado para o 'a' e o método show() para o 'ola'. A QApplication é finalmente posta em execução com o método a.exec(), que entra no ciclo de eventos principal e fica à espera, até que devolva um valor inteiro para o Sistema Operativo subjacente, assinalando que a aplicação terminou. A Documentação de Referência do Qt Agora, vamos dar uma vista de olhos à documentação de referência da biblioteca Qt. Para o fazer, inicie o &tdevelop; e seleccione o "Qt" da árvore de documentação. O navegador de documentação abrir-se-é para mostrar a página inicial da referência do Qt. Este será o seu primeiro local para obter informações sobre o Qt, as suas classes e as funções disponíveis que ele oferece. Também, o programa acima é o primeiro que vem incluído na secção de tutoriais. Para ver as classes que pretendemos ver, a QApplication e a QPushButton, seleccione a "Lista Alfabética de Classes" e procure pelos nomes correspondentes. Siga qualquer um deles para dar uma vista de olhos na documentação da classe. Em alternativa, você poderá usar a documentação 'online' na Trolltech para o Qt Para o QApplication, você irá ver o construtor e todos os outros métodos que esta classe oferece. Se você seguir uma hiper-ligação, você irá obter mais informações sobre a utilização e o significado dos métodos, o que é bastante útil quando você não consegue às vezes detectar a utilização correcta ou quando quer arranjar um exemplo. Isto também conta para a documentação da biblioteca do KDE, a qual usa um tipo de documentação semelhante; como tal, isto é quase tudo o que você tem de saber para usar as referências das classes com o navegador da documentação. Interpretação do Exemplo Começando com a QApplication, irá encontrar todos os métodos utilizados no nosso primeiro exemplo: o construtor QApplication() o método setMainWidget() o método exec() É simples interpretar porque utilizámos este métodos: Cria uma instância da classe QApplication com o construtor, para que possamos utilizar os elementos gráficos fornecidos pelo Qt Cria um 'widget' que será o conteúdo da nossa janela de programa Configurar o 'widget' como o 'widget' principal para Executa a instância do QApplication O segundo objecto do nosso programa é o botão, uma instância da classe QPushButton. A partir dos dois construtores fornecidos para criar uma instância, nós optámos pelo segundo: este aceita um texto, o qual é o conteúdo do texto do botão; neste caso, é o texto "Olá mundo!". Aí, chamou-se o método resize() para alterar as dimensões do botão de acordo com o seu conteúdo - o botão tem de ser maior para tornar o texto completamente visível. Mas e o método show()? Agora, você verá que, como a maioria dos outros itens, a classe QPushButton baseia-se numa herança simples ou, como diz a documentação, herda de QButton. Siga a referência à classe QButton. Isto mostra-lhe que bastantes outros itens herdados pela QPushButton, os quais iremos usar posteriormente para explicar o mecanismo de 'signals'/'slots' De qualquer forma, o método show() não aparece, como tal, deverá ser um método que é fornecido por herança, da mesma forma. A classe que a QButton herda é a TQWidget. Siga de novo a ligação e você irá ver um conjunto enorme de classes que a TQWidget oferece, incluindo o método show(). Agora dá para perceber o que foi feito no exemplo com o botão: Cria uma instância de QPushButton, utiliza o segundo construtor para configurar o texto do botão Muda o tamanho do 'widget' de acordo com o seu conteúdo Escolhe o 'widget' como o 'widget' principal da instância do QApplication como Diz ao 'widget' para se mostrar no ecrã chamando show(), um método herdado de TQWidget Depois de invocar o método exec(), a aplicação fica visível para o utilizador, mostrando uma janela com o botão a dizer "Olá mundo!". Nota: os programas gráficos comportam-se de forma ligeiramente diferente da das aplicações procedimentais. A questão principal aqui é que a aplicação entra num estado chamado de "ciclo de eventos principal". Isto significa que o programa tem de esperar pelas acções do utilizador e então reagir a elas e que, numa aplicação do Qt, o programa terá de entrar no ciclo de eventos principal para conseguir começar a tratá-los. A próxima secção diz-lhe em resumo o que isto significa para o programador e o que é que o Qt oferece para processar os eventos do utilizador. Para os utilizadores já avançados: O botão não tem nenhuma janela-mãe declarada no construtor, o que significa que é um item gráfico de topo por si só e corre num ciclo de eventos local que não precisa de esperar pelo ciclo de eventos principal. Veja a documentação da classe TQWidget e o Guia de Referência da Biblioteca do KDE Interacção com o Utilizador Depois de ler as secções anteriores, já deverá saber: O que a biblioteca Qt fornece em termos de aplicações gráficas Como é criado um programa utilizando o Qt e Onde e como encontrar informações acerca das classes que deseja utilizar com o navegador de documentação Agora vamos dar "vida" à aplicação, processando os eventos do utilizador. De um modo geral, o utilizador tem duas formas de interagir com um programa: o rato e o teclado. Para ambas as formas, uma interface gráfica tem de fornecer métodos que detectem as acções e métodos que façam algo em reacção a estas acções. O sistema de janelas envia deste modo todos os eventos de interacção para a aplicação respectiva. A QApplication envia-os então para a janela activa como um QEvent e os próprios itens terão de decidir o que fazer com eles. Um item recebe o evento e processa o TQWidget::event(QEvent*), que decide então qual o evento que foi executado e como reagir; o event() é deste modo o tratador de eventos principal. Aí, o método event() passa o evento para os denominados de filtros de eventos que determinam o que se passou e o que fazer com o evento. Se nenhum filtro responder como responsável pelo evento, os tratadores de eventos especializados são invocados. Deste modo, pode-se optar entre: Eventos de teclados -- teclas TAB e Shift-TAB: virtual void focusInEvent(QFocusEvent *) virtual void focusOutEvent(QFocusEvent *) Todos a outra actividade de teclado: virtual void keyPressEvent(QKeyEvent *) virtual void keyReleaseEvent(QKeyEvent *) Movimentos do rato: virtual void mouseMoveEvent(QMouseEvent *) virtual void enterEvent(QEvent *) virtual void leaveEvent(QEvent *) Acções dos botões do rato virtual void mousePressEvent(QMouseEvent *) virtual void mouseReleaseEvent(QMouseEvent *) virtual void mouseDoubleClickEvent(QMouseEvent *) Eventos da janela que contém o 'widget' virtual void moveEvent(QMoveEvent *) virtual void resizeEvent(QResizeEvent *) virtual void closeEvent(QCloseEvent *) Lembre-se que todas as funções de eventos são virtuais e protegidas; como tal, você poderá reimplementar os eventos que necessitar nos seus próprios itens gráficos e indicar como é que o seu item terá de reagir. O TQWidget contém também outros métodos virtuais que poderão ser úteis nos seus programas; de qualquer forma, é suficiente conhecer o TQWidget bastante bem. Interacção de Objectos através de 'Signals' e 'Slots' Agora chegámos às vantagens mais óbvias da plataforma do Qt: o mecanismo de 'signals'/'slots'. Isto oferece uma solução bastante útil e fácil de os objectos interagirem entre si, o que normalmente é resolvido por funções de resposta ('callback') pelas bibliotecas do X-Window. Dado que esta documentação necessita de uma programação restrita e normalmente torna a criação de interface do utilizador muito complicada (como é referido pela documentação do Qt e é explicado no texto 'Programming with Qt' de K.Dalheimer), a Troll Tech inventou um novo sistema onde os objectos podem emitir sinais ('signals') que podem estar associados a métodos denominados por 'slots'. Para a parte de C++ do programador, ele só terá de conhecer algumas coisas sobre este mecanismo: a declaração de uma classe que utilize 'signals'/'slots' tem que ter a macro TQ_OBJECT no início (sem ponto e vírgula); e tem que ser derivada da classe TQObject um 'signal' pode ser emitido através da palavra chave 'emit', por exemplo, emit signal(parâmetros);, de qualquer método membro de uma classe que permite 'signals'/'slots' todos os 'signals' utilizados pelas classes que não são herdados tem que ser adicionados à declaração da classe numa secção 'signals' todos os métodos que podem ser ligados com um 'signal' são declarados em secções com a palavra chama adicional 'slot', ou seja, public slot: na declaração da classe o compilador de meta-objectos 'moc' tem de correr sobre o ficheiro de inclusão para expandir as macros e para produzir a implementação (que é necessário conhecer). Os ficheiros de resultado do 'moc' são compilados também pelo compilador de C++. Outra forma de usar os 'signals' sem derivar da classe TQObject é usar a classe QSignal - veja a documentação de referência para mais informações e para um exemplo de utilização. No seguinte, assume-se que você vai derivar de TQObject. Desta forma, a sua classe é capaz de enviar 'signals' para todo o lado e consegue fornecer 'slots' aos quais os 'signals' se possam ligar. Usando os 'signals', você não terá de se preocupar com que os recebe - só tem de emitir os 'signals' e qual o 'slot' que lhe deseja ligar para reagir à emissão. Os 'slots' também podem ser usados como métodos normais durante a implementação. Agora, para ligar um 'signal' a um 'slot', você terá de usar os métodos connect() que são fornecidos pelo TQObject ou, quando for possível, os métodos especiais que os objectos fornecem para definir a ligação a um dado 'signal'. Exemplo de Utilização Para explicar a forma como configurar a interacção dos objectos, iremos usar o nosso primeiro exemplo e extendê-lo com uma simples ligação: #include <qapplication.h> #include <qpushbutton.h> int main( int argc, char **argv ) { QApplication a( argc, argv ); QPushButton ola( "Olá mundo!", 0 ); ola.resize( 100, 30 ); a.setMainWidget( &ola ); connect(&ola, SIGNAL( clicked() ), &a, SLOT( quit() )); ola.show(); return a.exec(); } Como vê, a única adição para dar ao botão mais interacção é usar um método connect() : o connect(&ola, SIGNAL( clicked() ), &a, SLOT( quit() )); é tudo o que você tem para adicionar. Qual é o significado? A declaração da classe do TQObject fala sobre o método connect(): bool connect ( const TQObject * emissor, const char * signal, const TQObject * receptor, const char * membro ) Isto significa que você terá de indicar um ponteiro para uma instância de um TQObject que é o emissor do 'signal', o que significa que ele poderá emitir este 'signal' como primeiro parâmetro; depois, terá de indicar o 'signal' a que se deseja ligar. Os últimos dois parâmetros são o objecto receptor que contém um 'slot' seguido da função-membro que é, de facto, o 'slot' que será executado devido à emissão do 'signal'. Usando os 'signals' e 'slots', os objectos do seu programa podem interagir uns com os outros facilmente sem terem de explicitamente depender do tipo do objecto receptor. Você irá aprender mais sobre a utilização deste mecanismo para uma utilização produtiva posteriormente neste manual. Se quiser saber mais informações sobre o mecanismo de 'signals'/'slots' poderá ir ao Guia de Referência da Biblioteca do KDE e à referência 'online' do Qt. O que o KDE fornece As bibliotecas KDE 3.x As principais bibliotecas do KDE que irá utilizar para criar as suas aplicações KDE são: a biblioteca tdecore, contendo todas as classes com elementos não visíveis que fornecem funcionalidade às aplicações a biblioteca tdeui, que contém elementos de interface como barras de menu, barras de ferramentas, etc. a biblioteca tdefile, que contém as janelas de selecção de ficheiros Adicionalmente, para soluções específicas o KDE oferece as seguintes bibliotecas: a biblioteca tdefx, contendo 'pixmaps', efeitos visuais e a extensão TDEStyle para o QStyle a biblioteca tdehtml, que contém o componente html do KDE a biblioteca kjs, que contém o suporte Javascript do KDE a biblioteca tdeio, que contém acesso de baixo nível a ficheiros de rede a biblioteca tdeparts, que contém suporte a aplicações extensíveis, embebidas e reutilizáveis De seguida vamos ver o que é necessário para transformar a nossa primeira aplicação Qt numa do KDE. Aplicação KDE Exemplo A seguir, você irá ver que a criação de uma aplicação do KDE não é muito mais difícil que uma aplicação do Qt. Para a utilização da funcionalidades do KDE, você apenas terá de usar algumas outras classes, e fica praticamente tudo feito. Como exemplo, iremos discutir a versão alterada do exemplo do Qt acima descrito: #include <tdeapplication.h> #include <qpushbutton.h> int main( int argc, char **argv ) { TDEApplication a( argc, argv ); QPushButton ola( "Olá mundo!", 0 ); ola.resize( 100, 30 ); a.setTopWidget( &ola ); connect(&ola, SIGNAL( clicked() ), &a, SLOT( quit() )); ola.show(); return a.exec(); } Você irá constatar que, primeiro, mudámos da QApplication para a TDEApplication . Para além disso, tivemos de mudar o método setMainWidget() para setTopWidget, o qual a classe TDEApplication usa para indicar qual o item principal. É tudo! A sua primeira aplicação do KDE está pronta - você só terá de indicar ao compilador a localização dos ficheiros de inclusão e ao editor de ligações para compilar com a biblioteca 'tdecore', através da opção'-ltdecore'. Dado que já sabe o que, pelo menos, a função main() necessita geralmente e como é que uma aplicação fica visível e permite a interacção com o utilizador e com os objectos, iremos agora para o próximo capítulo, onde a nossa primeira aplicação será criada com o &tdevelop;. Aí, você também poderá testar tudo o que foi mencionado antes e ver os efeitos. O que você deverá ter olhado adicionalmente até agora é a documentação de referência do Qt, especialmente a as classes QApplication, TQWidget e TQObject , assim como a documentação da biblioteca 'tdecore' para a classe TDEApplication. O Manual de Referência da Biblioteca do KDE também cobre uma descrição completa da invocação dos construtores da QApplication e da TDEApplication, incluindo o processamento dos argumentos da linha de comandos. Criar Novas Aplicações O Assistente de Aplicações O Assistente de Aplicações do &tdevelop; pretende pô-lo a trabalhar em projectos novos no &tdevelop;. Como tal, todos os seus projectos são primeiro criados com o assistente, para que depois os possa construir e extender o que já é oferecido pelo esqueleto de código. Você poderá optar entre vários tipos de projectos, de acordo com os objectivos do seu projecto: Plataforma de Aplicações do KDE: inclui o código-fonte para uma estrutura básica para uma aplicação normal do KDE Projecto QMake: Cria uma estrutura de aplicação baseado no sistema de configuração qmake da Trolltech Programa simples de olá mundo: Cria um programa em C++ para terminais, sem suporte a interface gráficas Muitos outros esqueletos de programas Neste capítulo iremos ver como é que o Assistente de Aplicações poderá ser invocado e o que é que tem de ser feito para gerar um projecto de uma aplicação do KDE. Isto terá de ser o passo inicial da nossa cobertura, onde iremos criar a versão inicial de um projecto de exemplo. Para todos os outros tipos de projectos, os passos serão normalmente os mesmos, mas poderão não ter tantas opções disponíveis. Invocar o Assistente de Aplicações e a Geração de Projectos Iniciar o Assistente de Aplicações e a Primeira Página Para iniciar a sua aplicação do KDE, abra o &tdevelop;. No menu Projecto, seleccione o Novo Projecto. O Assistente de Aplicações é iniciado e você verá a árvore de selecções na primeira página, contendo os vários tipos de projectos disponíveis que poderão ser criados. Escolha a sub-árvore de C++, depois o KDE e depois a Plataforma de Aplicações. Para o nosso projecto de exemplo, iremos criar a aplicação KScribble. Indique isso como nome da aplicação e altere as outras informações na parte inferior deste ecrã que possam necessitar de alterações. Depois, carregue em Seguinte. Assistente de Aplicações Informações de controlo de versão Neste ecrã, você terá a possibilidade de decidir se o seu projecto irá usar um sistema de controlo de versões como o CVS. Para o nosso projecto de exemplo não iremos usar nenhum controlo de versões, por isso certifique-se que a opção de selecção diz Nenhum e escolha o Seguinte. Modelos de Cabeçalhos e Código Fonte As próximas duas páginas mostram os exemplos de cabeçalhos que irão para o topo de cada ficheiro de inclusão e de código que crie com o &tdevelop;. Por agora, deixe estes como os por omissão e seleccione Seguinte e depois Terminar. Se o botão Terminar não estiver activado, você não definiu todas as opções correctamente. Use o botão Anterior para voltar aos menus anteriores e corrigir os erros. Terminar Depois de completo, o Assistente de Aplicações deverá fechar-se e a janela de mensagens irá começar a mostrar informações sobre as tarefas que o &tdevelop; está a fazer de momento. No fim de todas as tarefas, você deverá ver **** Sucesso *****. Isto significa que a plataforma de aplicações foi carregada com sucesso. A Primeira Compilação Depois de ter o projecto gerado, iremos dar uma vista de olhos pelo código-fonte para ter uma ideia geral de como é que a plataforma de aplicações fica. Isto não só ajudará o utilizador a aprender, mas também a saber onde alterar o quê nos próximos passos. Este capítulo assume que você compreende a navegação básica do &tdevelop;. Consulte o Manual de Utilizador do KDevelop se precisar de ajuda. O gestor de Automake mostra os ficheiros de projecto como se segue: Ficheiro nos nosso projecto Antes de se aprofundar no código, deixe que o &tdevelop; compile e execute a nova aplicação. Para o fazer, seleccione a opção Construir o Projecto no menu Construir ou carregue em F8. A janela do resultado irá abrir e mostrar as mensagens que vão aparecendo durante a fase de compilação. 1 cd /home/ze/kscribble && WANT_AUTOCONF_2_5=1 WANT_AUTOMAKE_1_6=1 gmake k 2 gmake all-recursive 3 gmake[1]: Entering directory `/home/ze/kscribble' 4 Making all in doc 5 gmake[2]: Entering directory `/home/ze/kscribble/doc' 6 Making all in . 7 gmake[3]: Entering directory `/home/ze/kscribble/doc' 8 gmake[3]: Nothing to be done for `all-am'. 9 gmake[3]: Leaving directory `/home/ze/kscribble/doc' 10 Making all in en 11 gmake[3]: Entering directory `/home/ze/kscribble/doc/en' 12 /usr/local/kde3/bin/meinproc --check --cache index.cache.bz2 /home/ze/kscribble/doc/en/index.docbook 13 gmake[3]: Leaving directory `/home/ze/kscribble/doc/en' 14 gmake[2]: Leaving directory `/home/ze/kscribble/doc' 15 Making all in po 16 gmake[2]: Entering directory `/home/ze/kscribble/po' 17 gmake[2]: Nothing to be done for `all'. 18 gmake[2]: Leaving directory `/home/ze/kscribble/po' 19 Making all in src 20 gmake[2]: Entering directory `/home/ze/kscribble/src' 21 source='main.cpp' object='main.o' libtool=no \ 22 depfile='.deps/main.Po' tmpdepfile='.deps/main.TPo' \ 23 depmode=gcc3 /bin/sh /home/ze/kscribble/admin/depcomp \ 24 g++ -DHAVE_CONFIG_H -I. -I/home/ze/kscribble/src -I.. -I/usr/local/kde3/include -I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -c -o main.o `test -f 'main.cpp' || echo '/home/ze/kscribble/src/'`main.cpp 25 /usr/lib/qt/bin/moc /home/ze/kscribble/src/kscribble.h -o kscribble.moc 26 source='kscribble.cpp' object='kscribble.o' libtool=no \ 27 depfile='.deps/kscribble.Po' tmpdepfile='.deps/kscribble.TPo' \ 28 depmode=gcc3 /bin/sh /home/ze/kscribble/admin/depcomp \ 29 g++ -DHAVE_CONFIG_H -I. -I/home/ze/kscribble/src -I.. -I/usr/local/kde3/include -I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -c -o kscribble.o `test -f 'kscribble.cpp' || echo '/home/ze/kscribble/src/'`kscribble.cpp 30 kscribble.cpp: In member function `void KScribble::setupActions()' 31 kscribble.cpp:107: warning: unused variable `TDEAction*custom' 32 /usr/lib/qt/bin/moc /home/ze/kscribble/src/kscribbleview.h -o kscribbleview.moc 33 source='kscribbleview.cpp' object='kscribbleview.o' libtool=no \ 34 depfile='.deps/kscribbleview.Po' tmpdepfile='.deps/kscribbleview.TPo' \ 35 depmode=gcc3 /bin/sh /home/ze/kscribble/admin/depcomp \ 36 g++ -DHAVE_CONFIG_H -I. -I/home/ze/kscribble/src -I.. -I/usr/local/kde3/include -I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -c -o kscribbleview.o `test -f 'kscribbleview.cpp' || echo '/home/ze/kscribble/src/'`kscribbleview.cpp 37 kscribbleview.cpp: In member function `void KScribbleView::print(QPainter*, 38 int, int)': 39 kscribbleview.cpp:79: warning: unused parameter `QPainter*p' 40 kscribbleview.cpp:79: warning: unused parameter `int height' 41 kscribbleview.cpp:79: warning: unused parameter `int width' 42 /usr/lib/qt/bin/moc /home/ze/kscribble/src/pref.h -o pref.moc 43 source='pref.cpp' object='pref.o' libtool=no \ 44 depfile='.deps/pref.Po' tmpdepfile='.deps/pref.TPo' \ 45 depmode=gcc3 /bin/sh /home/ze/kscribble/admin/depcomp \ 46 g++ -DHAVE_CONFIG_H -I. -I/home/ze/kscribble/src -I.. -I/usr/local/kde3/include -I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -c -o pref.o `test -f 'pref.cpp' || echo '/home/ze/kscribble/src/'`pref.cpp 47 /usr/local/kde3/bin/dcopidl /home/ze/kscribble/src/kscribbleiface.h > kscribbleiface.kidl || ( rm -f kscribbleiface.kidl ; /bin/false ) 48 /usr/local/kde3/bin/dcopidl2cpp --c++-suffix cpp --no-signals --no-stub kscribbleiface.kidl 49 source='kscribbleiface_skel.cpp' object='kscribbleiface_skel.o' libtool=no \ 50 depfile='.deps/kscribbleiface_skel.Po' tmpdepfile='.deps/kscribbleiface_skel.TPo' \ 51 depmode=gcc3 /bin/sh /home/ze/kscribble/admin/depcomp \ 52 g++ -DHAVE_CONFIG_H -I. -I/home/ze/kscribble/src -I.. -I/usr/local/kde3/include -I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -c -o kscribbleiface_skel.o `test -f 'kscribbleiface_skel.cpp' || echo '/home/ze/kscribble/src/'`kscribbleiface_skel.cpp 53 /bin/sh ../libtool --silent --mode=link --tag=CXX g++ -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -o kscribble -R /usr/local/kde3/lib -R /usr/lib/qt/lib -R /usr/X11R6/lib -L/usr/X11R6/lib -L/usr/lib/qt/lib -L/usr/local/kde3/lib main.o kscribble.o kscribbleview.o pref.o kscribbleiface_skel.o -ltdeio 54 source='kscribble_client.cpp' object='kscribble_client.o' libtool=no \ 55 depfile='.deps/kscribble_client.Po' tmpdepfile='.deps/kscribble_client.TPo' \ 56 depmode=gcc3 /bin/sh /home/ze/kscribble/admin/depcomp \ 57 g++ -DHAVE_CONFIG_H -I. -I/home/ze/kscribble/src -I.. -I/usr/local/kde3/include -I/usr/lib/qt/include -I/usr/X11R6/include -DTQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -c -o kscribble_client.o `test -f 'kscribble_client.cpp' || echo '/home/ze/kscribble/src/'`kscribble_client.cpp 58 /bin/sh ../libtool --silent --mode=link --tag=CXX g++ -Wnon-virtual-dtor -Wno-long-long -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_DEFAULT_SOURCE -Wcast-align -Wconversion -O2 -fno-exceptions -fno-check-new -o kscribble_client -R /usr/local/kde3/lib -R /usr/lib/qt/lib -R /usr/X11R6/lib -L/usr/X11R6/lib -L/usr/lib/qt/lib -L/usr/local/kde3/lib kscribble_client.o -ltdecore 59 gmake[2]: Leaving directory `/home/ze/kscribble/src' 60 gmake[2]: Entering directory `/home/ze/kscribble' 61 gmake[2]: Nothing to be done for `all-am'. 62 gmake[2]: Leaving directory `/home/ze/kscribble' 63 gmake[1]: Leaving directory `/home/ze/kscribble' 64 *** Success *** Como pode ver, foram colocados números de linhas antes de cada linha, os quais não aparecem no resultado que irá obter mas tornará mais simples de descrever o que se está a passar durante a compilação. Primeiro que tudo, o 'gmake' funciona recursivamente. Isto significa que ele começa a partir da directoria em que é invocado e vai percorrendo as sub-pastas primeiro, uma de cada vez, e depois regressa à directoria em que foi invocado, processa-a e depois termina. A primeira linha de interesse é a 24. Repare nesta linha que o 'g++', que é o nosso compilador de C++, é chamado pelo 'make' para compilar o primeiro ficheiro de código do projecto - neste caso, o 'main.cpp'. São usadas também várias opções da linha de comandos com o compilador 'g++'; algumas das quais são predefinidas e outras podem ser configuradas através do &tdevelop;. Antes do próximo ficheiro ('kscribble.cpp', linha 29) ser compilado, o 'moc' (compilador de meta-objectos) é primeiro invocado sobre o 'kscribble.h' (linha 25). Isto é porque as classes do KScribble usam 'signals'/'slots', por isso a macro TQ_OBJECT precisa de ser expandida, e o 'moc' faz isso por nós. O ficheiro resultante, o 'kscribble.moc', é usado pelo 'kscribble.cpp' através de um comando #include dentro do ficheiro. O esqueleto do código-fonte Para conceber como é que uma aplicação do KDE funciona, iremos dar uma vista de olhos detalhada ao esqueleto de código que já é fornecido pelo Assistente de Aplicações. Como foi visto, já existe algum conjunto de ficheiros de código e de inclusão que compõem o código inicial da aplicação e a tornam pronta-a-usar. Como tal, a forma mais simples de explicar o código é seguir a implementação linha-a-linha á medida que é processada durante a execução do programa, até que entra no ciclo de eventos principal e fica pronta a ser controlada pelo utilizador. Aí, iremos ver a funcionalidade que permite a interacção com o utilizador e como é que certas coisas funcionam. Esta é provavelmente a melhor forma de explicar a plataforma e, dado que é semelhante a quase todas as aplicações do KDE, permitir-lhe-á ler o código-fonte de outros projectos de forma igualmente simples; para além disso, irá saber onde alterar uma dada parte do código para que as suas aplicações se comportem da forma como foram desenhadas. A função main() À medida que a aplicação começa a sua execução ao entrar na função main(), esta será o início do exame de código. A função main() do KScribble está implementada no ficheiro 'main.cpp' e pode também ser acedida com o Navegador de Classes, seleccionando para tal a pasta de "Funções Globais". 1 int main(int argc, char **argv) 2 { 3 TDEAboutData about("kscribble", I18N_NOOP("KScribble"), version, description, 4 TDEAboutData::License_GPL, "(C) 2002 O Seu Nome", 0, 0, "voce@o-proprio.com"); 5 about.addAuthor( "O Seu Nome", 0, "voce@o-proprio.com" ); 6 TDECmdLineArgs::init(argc, argv, &about); 7 TDECmdLineArgs::addCmdLineOptions(options); 8 TDEApplication app; 9 10 // registar-nos como um cliente dcop 11 app.dcopClient()->registerAs(app.name(), false); 12 13 // ver se estamos a começar com gestão de sessão 14 if (app.isRestored()) 15 RESTORE(KScribble) 16 else 17 { 18 // sem sessão... começar normalmente 19 TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); 20 if (args->count() == 0) 21 { 22 KScribble *widget = new KScribble; 23 widget->show(); 24 } 25 else 26 { 27 int i = 0; 28 for (; i < args->count(); i++) 29 { 30 KScribble *widget = new KScribble; 31 widget->show(); 32 widget->load(args->url(i)); 33 } 34 } 35 args->clear(); 36 } 37 38 return app.exec(); 39 } Agora, o que acontece primeiro é a criação normal de um objecto TDEApplication, mas foram adicionados alguns métodos do KDE que definem a informação do programa e da autoria desta aplicação. Início da Aplicação do Utilizador ... (ainda não escrito) O Construtor Vamos agora olhar para o construtor e ver com esta instância é chamada 1 KScribble::KScribble() 2 : TDEMainWindow( 0, "KScribble" ), 3 m_view(new KScribbleView(this)), 4 m_printer(0) 5 { 6 // aceitar arrastar e largar 7 setAcceptDrops(true); 8 9 // diz ao TDEMainWindow que este é o widget principal 10 setCentralWidget(m_view); 11 12 // então, configuramos as nossas acções 13 setupActions(); 14 15 // e uma barra de estado 16 statusBar()->show(); 17 18 // permitir à vista mudar a barra de estado e o título 19 connect(m_view, SIGNAL(signalChangeStatusbar(const TQString&)), 20 this, SLOT(changeStatusbar(const TQString&))); 21 connect(m_view, SIGNAL(signalChangeCaption(const TQString&)), 22 this, SLOT(changeCaption(const TQString&))); 23 24 } Repare que o KScribble herda da classe TDEMainWindow - uma classe de base usada normalmente pelas aplicações do KDE. É inicializada uma classe chamada KScribbleView como item gráfico central, é criada uma KStatusBar através do método statusBar() (na linha 16), e são ligados com o connect() alguns 'signals' e 'slots'. Desenho da Vista da Aplicação Introdução Ao desenvolver uma aplicação com uma interface de utilizador gráfica, o trabalho principal toma lugar ao desenvolver uma "vista" da aplicação. Uma vista é normalmente uma janela que mostra os dados de um documento e que oferece métodos para manipular o conteúdo do documento. Isto pode ser feito pelo utilizador, através dos eventos que ele emite com o teclado ou com o rato; as operações mais complexas são normalmente processadas pelas barras de ferramentas ou pelos menus que interagem com a vista e com o documento. A barra de estado irá então mostrar informações sobre o estado do documento, da vista ou da aplicação. Por exemplo, iremos ver como é que um editor é construído e onde poderemos encontrar uma determinada componente. Um editor normalmente é suposto oferecer uma interface para ver e/ou alterar o conteúdo de um documento de texto para o utilizador. Se você iniciar o Kate, voce irá ver a interface visual da seguinte forma: A barra de menu: fornece operações complexas e também abre, grava e fecha ficheiros e termina a aplicação. A barra de ferramentas: oferece ícones que permitem um acesso mais rápido às funções mais necessárias, A barra de estado: mostra o estado da posição do cursor pela linha e coluna actual, A vista no centro da janela, a mostrar um documento e a apresentar um cursor associado ao teclado e ao rato para lidar com os dados. Agora é fácil de perceber que uma vista é a componente mais única da aplicação e que o desenho da vista decide a usabilidade e a capacidade de aceitação de uma aplicação. Isto significa que um dos primeiros passos da programação é determinar o objectivo da aplicação e perceber o desenho da vista que irá responder melhor às necessidades de um utilizador para lidar com a aplicação com o mínimo de trabalho de aprendizagem da interface que lhe é apresentada. Para alguns fins, como a edição de texto ou a apresentação de ficheiros HTML, as vistas são oferecidas pelas bibliotecas do Qt e do KDE; iremos discutir certos aspectos destes itens de alto-nível na próxima secção. Porém, para a maioria das aplicações, têm de ser desenhados e implementados novos itens gráficos. É o que torna um programador também um desenhador e onde são requisitadas as suas capacidades de criatividade. Todavia, você deverá ter em atenção primeiro a intuitividade. Lembre-se, bastantes utilizadores não irão aceitar uma aplicação que não seja: graficamente bonita. ofereça muitas funcionalidades seja fácil de manejar seja rápida de aprender a utilizar Escusado será dizer que a estabilidade é um grande objectivo de desenho. Ninguém poderá evitar os erros, mas poderemos obter um mínimo se tivermos objectivos de desenho inteligentes e um uso abrangente de desenho orientado por objectos. O C++ torna a programação uma alegria se você souber como explorar as suas capacidades - a herança, o isolamento de informação e a reutilização de código já existente. Ao criar um projecto do KDE ou do Qt, você terá de ter sempre uma vista que herde de TQWidget, quer por herança directa, ou então porque o item da biblioteca que deseja usar herda do TQWidget. Como tal, o Assistente de Aplicações já construiu uma vista que é uma instância de uma classe suaAplicacaoView, a qual já herda de TQWidget. Este capítulo descreve, deste modo, como usar os itens das bibliotecas para criar vistas das aplicações do KDE e do QT que sejam geradas com o &tdevelop;, e iremos depois olhar para os tipos de vistas que já são oferecidas. Utilizar Vistas das Bibliotecas Quando o desenho da sua aplicação tiver sido definido, você deverá primeiro ver se existe código que possa tornar a sua vida muito mais simples. Uma parte desta pesquisa implica procurar por um elemento gráfico que posas ser usado como uma vista, ou pelo menos como parte dela; quer directamente quer por herança. As bibliotecas do KDE e do Qt já contêm um conjunto de elementos gráficos que podem ser usados para este fim. Para os usar, você tem duas opções: Remova a classe da nova vista e cria uma instância de um 'widget' de biblioteca; escolha depois isto com a vista, Muda a herança da classe de vista fornecida para a classe do 'widget' da biblioteca a utilizar. De qualquer forma, é importante saber que, se a plataforma aplicacional não estiver compilada com a biblioteca que contém o elemento gráfico, o editor de ligações irá falhar. Depois de optar por usar um determinado elemento gráfico, veja qual é a biblioteca que é necessária; depois abra a opção "Projecto"->"Opções" do menu do &tdevelop;. Mude para a página das "Opções do Editor de Ligações" e veja as opções referentes às bibliotecas que estão a ser usadas de momento. Se a biblioteca do seu elemento gráfico já está assinalada, você poderá deixar as opções do projecto tal-e-qual e começar a fazer as alterações necessárias à sua escolha. Caso contrário, e se as opções do editor de ligações dão a possibilidade de adicionar a biblioteca com uma opção de marcação, assinale essa opção e carregue em "OK" para sair da janela de opções do projecto de novo. Se não tiver nenhuma opção, adicione a biblioteca no campo de edição em baixo com a opção '-l'. Para as bibliotecas que a sua aplicação tem de procurar antes de preparar as Makefiles com o programa 'configure' na máquina do utilizador, adicione a seguinte macro de procura ao ficheiro 'configure.in' localizado na directoria de base do seu projecto e adicione a macro na linha de edição. Lembre-se que tem de correr o "Construir"->"Autoconf e automake" e "Build"->"Configure" antes de as Makefiles passarem a conter a expansão correcta da macro da biblioteca. Também, se os ficheiros de inclusão da biblioteca não estiver nas localizações normais (que poderão ser consultadas, vendo as opções '-I' na janela de resultado do "Make"), você terá de adicionar a sua localização na janela de Opções do Projecto - "Opções do Compilador", com a opção '-I' ou com a macro respectiva do 'automake' no campo de edição das "Opções Adicionais". Vista do Qt Olhando para a primeira página da documentação 'online' do Qt, você irá ver uma referência a "Widget Screenshots" (Imagens dos Elementos Gráficos), onde você poderá ver como é que o itens que o Qt contém irão ficar. Eles estão prontos a usar e podem ser combinados em conjunto para forma itens mais complexos, de modo a criar vistas de aplicações ou janelas. A seguir, iremos discutir alguns destes itens que são muito úteis para criar vistas de aplicações; tenha contudo em mente que as bibliotecas do KDE algumas vezes contêm outros itens para o mesmo fim; estes serão revistos na próxima secção. Aqui está um conjunto de sugestões sobre o fim para que você irá usar um determinado componente do Qt: Se a área da sua janela não for grande o suficiente para mostrar todos os seus dados, o utilizador irá precisar de se deslocar pelo documento através de barras à esquerda e em baixo na janela. Para isso, o Qt oferece a classe QScrollView, que oferece uma área-filha que poderá ser posicionável. Como foi dito, você poderá herdar o seu próprio item de QScrollView ou usar uma instância para gerir o item da vista do seu documento. Para criar você próprio uma ScrollView, herde o item da vista da classe TQWidget e adicione QScrollBars verticais e horizontais. (Isto é feito pelo item TDEHTMLView do KDE). Para processar texto, use a QTextEdit. Esta classe fornece um elemento gráfico de edição de texto completo que já é capaz de cortar, copiar e colar texto e é gerido por uma vista posicionável. Use a QTable para mostrar dados organizados numa tabela. Dado que a QTable usa também barras de posicionamento, é uma boa solução para aplicações de cálculos de tabelas. Para mostrar dois itens diferentes ou duas janelas ao mesmo tempo, use o QSplitter . Isto permite pôr lado-a-lado as vistas com divisões horizontais ou verticais. O KMail é um bom exemplo do que isto iria parecer - a área principal é separada na vertical por uma divisória e a área do lado direito é, por sua vez, dividida de novo na horizontal. A QListView mostra informações numa lista e numa árvore. Isto é útil para criar árvores de ficheiros ou outra informação hierárquica qualquer com a qual deseja interagir. Você poderá ver que o Qt sozinho já oferece um conjunto completo de elementos gráficos prontos a usar, de modo que você não tem de inventar novas soluções se estas corresponderem às suas necessidades. O efeito colateral ao usar os elementos gráficos normais é que os utilizadores já sabem como lidar com eles e só terão de se concentrar nos dados apresentados. Vistas do KDE As bibliotecas do KDE foram inventadas para tornar o desenho de aplicações para o Ambiente de Trabalho K mais fácil e capaz de novas funcionalidades do que o Qt por si só oferece. A biblioteca 'tdeui' oferece: TDEListView: uma versão mais poderosa do QListView TDEIconView: uma vista gráfica de ficheiros de ícones A biblioteca 'tdehtml', por outro lado, oferece um elemento gráfico de interpretação de HTML completo e pronto a usar. Já é posicionável, por isso você não terá sequer de se preocupar com isso. Uma utilização possível seria integrá-lo como um item de antevisão para um editor HTML; é usado por aplicações como o Konqueror para mostrar ficheiros HTML. Criar as suas próprias Vistas Ainda não escrito Configurar as Barras de Menu e de Ferramentas Introdução As barras de menu e de ferramentas são uma das partes mais importantes de uma aplicação para fornecer métodos para lidar com uma estrutura de documentos. Como regra geral, você irá tornar todas as funções disponíveis pela barra de menu. Os itens que não devam estar disponíveis numa determinada etapa do processo da aplicação deverão estar desactivados. Para além disso, uma aplicação só poderá conter uma barra de menu, mas poderá conter várias barras de ferramentas. As barras de ferramentas, por outro lado, só deverão conter os comandos usados mais frequentemente pelos ícones das imagens ou deverão fornecer métodos de acesso rápido, como por exemplo listas, para seleccionar valores. Como é que funciona? A nossa aplicação herda da classe TDEMainWindow, que trata automaticamente da criação de um menu e de barras de ferramentas por nós. No método KScribble::setupActions() existe uma chamada ao método TDEMainWindow::createGUI(). Este método carrega um ficheiro de recursos, neste caso, o 'kscribbleui.rc', para inicializar os menus no arranque. Repare que o ficheiro 'kscribbleui.rc' está listado como um dos ficheiros do projecto no Gestor do Automake. Se abrir esse ficheiro, irá revelar o seguinte: 1 <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> 2 <kpartgui name="kscribble" version="1"> 3 <MenuBar> 4 <Menu name="custom"><text>Pers&onalizado/text> 5 <Action name="custom_action" /> 6 </Menu> 7 </MenuBar> 8 </kpartgui> Explicação... Outra forma de modificar o conteúdo do menu e das barras de ferramentas é manipulá-las directamente através dos métodos oferecidos pelas suas classes. Por exemplo, o método menuBar() devolve o elemento KMenuBar para a barra do menu do nosso programa. Se olhar para a documentação da KMenuBar e da classe herdada por ela, a QMenuBar, irá encontrar um grande conjunto de métodos insertItem() que lhe permitirão adicionar itens à barra do menu. Os métodos da classe TDEMainWindow que são o statusBar() e o toolBar() irão devolver-lhe também referências aos elementos também fornecidos ao utilizador da janela. Configuração de Aceleradores de Teclado Uma coisa muito profissional que você deverá sempre adicionar à sua aplicação são os aceleradores de teclado. Estes são principalmente usados pelos utilizadores experientes que gostam de trabalhar depressa com as suas aplicações e que estão dispostos a aprender atalhos. Para isso, as bibliotecas do KDE fornecem a classe TDEAction, que fornece as teclas de atalho do teclado e o acesso aos aceleradores-padrão de teclado, configurados a nível global. Por omissão, as aplicações gráficas geradas pelo &tdevelop; só usam os aceleradores de teclado normais, como o F1 para aceder à ajuda 'online', o Ctrl+N para Novo Ficheiro, etc. Se a sua aplicação contiver um conjunto de aceleradores, você deverá torná-los configuráveis num menu de opções; tanto poderão estar em conjunto com outras configurações da aplicação numa TQWidget como usados isoladamente. A biblioteca do KDE já fornece uma classe KKeyChooser para ser usada em páginas de uma janela, enquanto que a KKeyDialog fornece uma janela de configuração de teclas pronta a usar. Funções de Ajuda Introdução Uma parte muito importante do processo de desenvolvimento é fornecer as funcionalidades de ajuda ao utilizador, sempre que possível. A maioria dos programadores tendem a atrasar isto, mas você dever-se-á lembrar que um utilizador normal nem sempre é um perito em Unix. Ele poderá vir de outra escola de 'software', onde lhe é oferecido todo um conjunto de funções de auxílio para o pôr a utilizar uma aplicação sem sequer ter de tocar nos manuais. Como tal, as bibliotecas do Qt e do KDE oferecem todos os meios normalmente pensados para tornar uma aplicação profissional aos olhos de um utilizador, com funções de ajuda prontas a usar. Dentro da aplicação, estas são: Dicas Ajuda na barra de estado Botões 'O que é isto...?' Para além disso, a aplicação deverá oferecer meios de aceder a um manual 'online' baseado em HTML directamente, através da tecla de ajuda normal que é a F1. Este sistema de ajuda baseado no contexto é fornecido automaticamente através da classe TDEMainWindow, ainda que, como autor, você tenha de fornecer o conteúdo. Como o &tdevelop; também oferece todos os tipos de ajuda, assim como a plataforma do KDE gerada pelo assistente de aplicações também contém algum suporte, este capítulo ajudá-lo-á a encontrar onde deverá adicionar a sua funcionalidade de ajuda. Durante o desenvolvimento da sua aplicação, você deverá ser consistente com o que está a fazer; como tal, você deverá efectuar os passos necessários directamente, enquanto extende o código. Isto irá evitar que você se embrenhe no seu código e perca tempo a perceber o que a sua aplicação faz e o que você pretendia em determinadas partes do código. Dicas Uma forma muito simples de fornecer ajuda são as dicas de ferramentas. Estas são pequenas mensagens de ajuda que aparecem quando o utilizador passa o rato por cima de um item, o qual mostra uma pequena explicação, e que desaparecem quando o cursor sai de cima do item. A utilização mais conhecida das dicas acontece nas barras de ferramentas, onde estas deverão ser mantidas o mais pequenas possível, dado que as barras de ferramentas podem ser configuradas para mostrar o seu conteúdo de várias formas: quer para mostrar o botão, o botão com o texto por baixo, ou apenas o texto. Esta possibilidade deverá ser configurável pelo utilizador, mas não é obrigatório. O texto é mostrado de qualquer forma como uma dica e uma barra de ferramentas normalmente consiste em botões e outros itens, como campos de edição e listas. Para uma referência completa, veja a referência da classe TDEToolBar localizada na biblioteca 'tdeui'. Neste exemplo, examinamos o botão "Novo Ficheiro" numa aplicação genérica: Aqui, a parte i18n("New File") irá mostrar uma mensagem. É rodeada pela macro i18n(), que é fornecida com o kapp.h para traduzir o texto da dica para a língua seleccionada no momento. As dicas poderão também ser adicionadas a qualquer item gráfico, se usar a classe QToolTip fornecida pelo Qt. Um exemplo seria: Extender a Barra de Estado Dado que as aplicações que herdam de TDEMainWindow também contêm uma barra de estado, esta classe também oferece já um conjunto de mensagens da barra de estado para todos os itens do menu e da barra de ferramentas. Uma mensagem da barra de estado é uma mensagem curta que extende o significado de uma dica de ferramentas, ou poderá ser vista como um substituto das dicas para os itens do menu e é (como o nome indica) mostrada na barra de estado, sempre que o utilizador abre um menu e selecciona um item deste. O Botão <guibutton>O que é Isto...?</guibutton> O botão O Que É Isto...? fornece janelas de ajuda com a intenção de que o utilizador quer obter ajuda sobre um determinado elemento na área de trabalho ou sobre um item da barra de ferramentas. É colocado na barra de ferramentas e é activado logo que o utilizador carregue no botão. O cursor muda para uma seta com um ponto de interrogação semelhante ao que o botão tem. O utilizador então poderá carregar num item visível para obter uma janela de ajuda. Como exercício, você poderá tentar este comportamento com o botão O que é isto...? no &tdevelop;. Para adicionar a ajuda 'O Que É Isto...?' a um dos seus itens gráficos, use o método estático QWhatsThis::add(TQWidget *item, const TQString &texto) Documentação Introdução Devido ao facto de que os projectos normalmente não têm um conjunto completo de documentação do utilizador, todos os projectos do &tdevelop; contêm já um manual pré-elaborado que poderá ser facilmente adaptado; como tal, preenche outro objectivo do KDE: fornecer ajuda 'online' suficiente para suportar os utilizadores que não estejam familiarizados com uma aplicação. Assim, este capítulo irá introduzi-lo à extensão do modelo de documentação fornecido e ao que precisa de fazer para torná-lo disponível para o utilizador. Documentação para Utilizadores A documentação para o seu projecto fica normalmente em 'dir_projecto/doc/en', ou noutra directoria qualquer se o Inglês não for a sua língua nativa. Aí dentro existe um ficheiro, o 'index.docbook', no qual fica a documentação. O formato para editar este ficheiro é explicado no 'site' Web de documentação do KDE. Documentação para Programadores Outra parte importante da documentação é incluir uma ajuda descritiva para as interfaces da sua classe. Isto permitir-lhe-á a si e aos outros programadores usarem as suas classes se lerem a documentação em HTML da classe, a qual poderá ser criada com o KDoc. O &tdevelop; suporta a utilização completa do KDoc para criar a documentação da biblioteca do KDE, estando também as suas plataformas aplicacionais já documentadas. Para você trabalhar também no código fornecido, seria uma boa ideia começar a ler a documentação 'online' incluída. O seguinte descreve como fazer para obter a documentação da API, onde o &tdevelop; ajudá-lo-á a adicioná-la e quais os tipos de marcas ('tags') que o KDoc oferece. Internacionalização Introdução O 'i18n' é um sistema de internacionalização que é usado para oferecer versões internacionalizadas de uma dada aplicação ou projecto. A dificuldade ao criar aplicações é que elas só suportam a língua para a qual foram criadas; visualmente isto poderá ser visto nas legendas, itens de menu, entre outros itens. O objectivo da internacionalização é oferecer às aplicações e às funções da biblioteca a língua do utilizador; como tal, permitindo aos utilizadores que não falem nativamente a língua original, que usem a funcionalidade oferecida e se sintam mais confortáveis. Créditos (... ainda não escrito ...) Bibliografia <ulink url="info://make/Top">GNU Make Manual</ulink> Richard M.Stallman RolandMcGrath <ulink url="info://automake/Top">GNU Automake</ulink> DavidMacKenzie TomTromey <ulink url="info://autoconf/Top">GNU Autoconf</ulink> DavidMacKenzie BenElliston <ulink url="info://gcc/Top">Using the GNU Compiler Collection</ulink> Richard M.Stallman <ulink url="info://libtool/Top">GNU Libtool</ulink> GordonMatzigkeit AlexandreOliva ThomasTanner Gary V.Vaughan GNU Autoconf, Automake, and Libtool 1st edition October 2000 Gary V.Vaughan BenElliston TomTromey Ian LanceTaylor New Riders Publishing ISBN 1578701902 Advanced Programming in the UNIX(R) Environment 1st edition June 1992 W. RichardStevens Addison-Wesley Pub Co ISBN 0201563177 Thinking in C++, Volume 1: Introduction to Standard C++ 2nd Edition April 15, 2000 BruceEckel Prentice Hall ISBN 0139798099 Open Source Development with CVS 2nd Edition October 12, 2001 KarlFogel MosheBar The Coriolis Group ISBN 158880173X Programming PHP 1st edition March 2002 RasmusLerdorf KevinTatroe O'Reilly & Associates ISBN 1565926102 Programming Python 2nd Edition March 2001 MarkLutz O'Reilly & Associates ISBN 0596000855 Gui Programming With Python : Using the Qt Toolkit Bk&Cd-r edition January 2002 BoudewijnRempt Opendocs Llc ISBN 0970033044 Programming Perl The Camel book 3rd Edition July 2000 LarryWall TomChristiansen JonOrwant O'Reilly & Associates ISBN 0596000278 Learning Perl The Lama book 3rd Edition July 15, 2001 Randal L.Schwartz TomPhoenix O'Reilly & Associates ISBN 0596001320 &underFDL;