Tutorial Qt – Capitulo 04 – Uma aplicação básica usando Qt

Nesse capitulo, iremos começar o uso do Qt, para produzir uma aplicação mais substancial. Iremos construir uma caixa de diálogo simples onde o usuário pode adicionar itens. Esse itens também poderão ser removidos da lista.

A Figura abaixo mostra como a aplicação vai ficar quando estiver pronta. Para criar esse formulário e escrever o código correspondente, iremos usar o Qt Designer.

O primeiro passo é iniciar o terminal e criar uma pasta. Escolha um nome para sua aplicação. Use o comando ‘cd’ para acessar o novo diretório e inicie o Qt Designer digitando ‘designer &’. É possível executar o Qt Designer do menu em distribuições mais modernas, mas iremos executar alguns comandos a partir do terminal, então eu recomendo acessar p Designer dessa maneira. Isso irá deixar você como a janela mostra abaixo.

Vamos começar criando um novo Projeto C++. Simplesmente escolha File – Bew. Marque “C++ project” e clique em “Continue”. Na próxima caixa de diálogo (abaixo) preencha com um nome para o seu projeto (use o botão “…” para acessar uma caixa de diálogo onde pode escolher o local do arquivo). Para nosso exemplo, chame-o de simple-dialog.pro. Não há necessidade de acessar nenhuma das outras abas no momento, mas sinta-se a vontade para explora-las antes de clicar no botão Ok.

Agora temos um projeto , então tudo que temos que fazer é anexar itens a ele. Escolha File – New novamente, mas dessa vez, adicione uma caixa de diálogo ao projeto. Você acabará com uma caixa de diálogo vazia chamada Form1. Começaremos renomeando essa caixa de diálogo para um nome melhor, como dlgMain. Isso é feito clicando pela alteração da propriedade Name no editor de propriedades mostrado no lado direito da janela principal do Qt Designer. Se não puder acha-la, certifique-se que está visível clicando em Windows – Views.

NOTA: Você precisa dar um nome a todos os seus widgets, caixas de diálogo e janelas antes de editar  o código correspondente se quiser evitar confusão com o Qt Designer.

A tabela abaixo resume as mudanças feitas as propriedades da caixa de diálogo:

Widget Property New Value
dlgMain Name dlgMain
dlgMain Caption Simple Dialog Example

Agora estamos prontos para começar a adicionar os widgets a nossa caixa de diálogo. Adicione uma groupbox contendo uma listbox, uma lineedit e dois botões. Abaixo da groupbox, adicione outro botão. Os widgets estão disponíveis na barra de ferramenta e seus nomes são mostrados quando o ponteiro do mouse é mantido por um tempo sobre o botão.

A figura abaixo mostra o nomes dos widgets e o local aproximado deles na caixa de diálogo.

O botão abaixo do groupbox é nomeado como pbOk. Os outros dois foram nomeados como pbAdd e pbRemove. A listbox recebe o nome lbItems, e a lineedit o nome liItem. A tabela abaixo resume as mudanças a serem feitas  as propriedades do widget.

Widget Property New Value
pbAdd Name pbAdd
pbAdd Text Add
pbAdd Default True
pbRemove Name pbRemove
pbRemove Text Remove
pbOk Name pbOk
pbOk Text Ok
lbItems Name lbItems
leItem Name leItem
GroupBox1 Title (empty)

Para testar a caixa de diálogo, escolha um estilo  de sua preferência no menu Preview (tente vários estilo para comparação). A figura abaixo mostra o resultado com o estilo Windows, mas você pode conseguir algo bem diferente. O importante é que você tenha os mesmos widgets na caixa de diáologo.

Eu acho que nós todos podemos concordar que essa disposição é bem feia. Antes que possamos começar a rearrumar os widgets para aperfeiçoar a aparẽncia precisamos discutir um tópico específico do Qt. O Qt é desenhado para executar em muitos sistemas diferentes, de palmtops a servidores Unix. Também suporta aplicações internacionalizadas com suporte a qualquer linguagem concebida. Para tornar possível  executar aplicações Qt com textos diferentes no mesmo local e em qualquer resolução de tela existe uma solução chamada layouts. Ao invés de especificar onde exatamente os widgets ficariam, nós especificamos como eles ficam em relação um ao outro. Você verá em breve o que isso significa.

Antes de aplicar qualquer layout precisamos adicionar espaçadores para preencher os espaços vazios de nossa caixa de diálogo. O espaçador é usado como um widget mas que será invisível durante a execução da aplicação. Eles podem ser selecionados na barra de ferramentas e desenhados na caixa de diálogo como qualquer outro widget. Na figura abaixo, dois espaçadores são mostrados.

Parta selecionar múltiplos widgets de uma vez, selecione o primeiro e mantenha pressionada a tecla shift enquanto seleciona os outros. Agora selecione o espaçador a esquerda do botão Ok e o botão. Depois cliqueno botão “layout horizontally”. A figura abaixo mostra os diferentes botões de layout da forma como aparecem na barra de ferramentas do Qt Designer (observe que eles ficam azul quando ativos).

Agora selecione o lineedit e os dois botões da groupbox juntos com o espaçador e escolha o layout vertical. Depois marque toda a groupbox e escolha o layout horizontal (isso aplica o layout a todos os widgets dentro da groupbox). Finalmente, selecione a caixa de diálogo e o layout vertical. Se você cometer algum erro ao aplicar os layouts, ou quiser experimenta-los, simplesmente selecione um layout e clique em “brealk layout”  para começar de novo.

Ao prever novamente deve ser mostrado a você algo como a figura abaixo. Mude o tamanho da caixa de diálogo para testar a flexibilidade do layout.

neste momento. completamos o desenho visual da caixa de diálogo.  Há somente mais duas coisas relacionadas ao visual a fazer antes de começar a escrever o código.

A primeira é corrigir a ordem das abas, isto é, a ordem que os widgets são ativados quando a tecla tab é usada para navegar pela caixa de diálogo. Simplesmente clique no botão “tab order” (ele se parece com três linhas azuis com os números 1, 2 e 3 escritos a esquerda), e clique nos widgets na ordem que você quiser. Para sair do mode de edição da ordem das abas, clique na seta da barra de ferramentas (a legenda dessa botão é Pointer).

Agora, observe o explorador de objetos, usualmente acima do editor de propriedades. Selecione a aba members e adicione dois slots públicos (dê clique com o botão direito  no item public abaixo  do item slots). A figura abaixo mostra os slots que foram adicionados. Lembre-se dos parêntesis quando estiver declarando cada slot.

Agora chegou a hora de escrever alguns códigos. Feche a caixa de diálogo clicando no botão Ok, e começe clicando em um dos slots que você criou. Isso exibitá uma janela de codificação com o código mostrado abaixo:

/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you wish to add, delete or rename slots use Qt Designer which will
** update this file, preserving your code. Create an init() slot in place of
** a constructor, and a destroy() slot in place of a destructor.
*****************************************************************************/
void dlgMain::addItem()
{
}
void dlgMain::removeItem()
{
}

Antes que começar a alterar o código, nós adicionaremos um último slot. Dessa vez, adicione um slot protected chamado init(). Esse slot será adicionado automaticamente na janela source. Esse é um dos slots especiais adicionado pelo Qt Designer para evitar a antiga abordagem de versões antigas do Qt quando era necessário criar uma sub-classe para cada caixa de diálogo para adicionar um construtor ou destrutor. Os slots protected init()  e destroy() salvam você dessa abordagem. Essa abordagem é mais pragmática que a antiga, e remove uma das inconveniências de uma interface muito limpa.

No slot addItem(), nós executaremos as ações que serão tomadas quando o usuário clicar no botão add. As ações são checar se a lineedit contém algum texto e se for o caso, adicionar esse texto a lista, e depois limpar a lineedit e colocar o foco lá para que o usuário possa continuar digitando. O slot removeItem() simplesmente checa se algum item da listbox está selecionado, removendo esse item. Finalmente, o slot init() garante que a listbox esteja vazia e então colocao o foco na lineedit.

O código final é mostrado abaixo:

/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you wish to add, delete or rename slots use Qt Designer which will
** update this file, preserving your code. Create an init() slot in place of
** a constructor, and a destroy() slot in place of a destructor.
*****************************************************************************/
void dlgMain::addItem()
{
if( leItem->text().length() > 0 )
{
lbItems->insertItem( leItem->text() );
leItem->clear();
}
leItem->setFocus();
}
void dlgMain::removeItem()
{
if( lbItems->currentItem() > -1 )
lbItems->removeItem( lbItems->currentItem() );
}
void dlgMain::init()
{
lbItems->clear();
leItem->setFocus();
}

Antes que possamos compilar nosso exemplo, precisamos de uma função main() para nosso projeto. É melhor separar o código em módulos, e assim manter o código de dlgMain é seus próprio arquivo. Assim, adicionaremo um novo arquivo de código C++ (use File – New como antes, mnas selecione Um arquivo de código C++ dessa vez).

Adicione o código abaixo ao arquivo recém criado e salve como main.cpp. Leiaos comentários para entender como cada parte funciona.


// Header for the QApplication class
#include <qapplication.h>
// Header for our dialog
#include "dlgmain.h"
// Remember the ( int, char** ) part as the QApplication needs them
int main( int argc, char **argv )
{
// We must always have an application
QApplication a( argc, argv );
dlgMain *m = new dlgMain();   // We create our dialog
a.setMainWidget( m );         // It is our main widget
m->show();                    // Show it...
return a.exec();              // And run!
}

Agor já podemos compilar nossa projeto, mas primeiro temos que criar um Makefile. Certifique-se de ter salvo tudo no Qt Designer (use File – Save All), e volte para o terminal e entre na pasta do projeto. Execute qmake no arquivo .pro do projeto que o Qt Designer criou. Por exemplo, execute “qmake simple-dialog.pro” e depois execute make. Se o código não tiver nenhum erro, o resultado será um executável com o mesmo nome do projeto, simple-dialog em nosso caso.

Se você executar o executável produzido pelo make, observará que parece tudo Ok, mas nada funciona. Isso se deve porque nós não conectamos nenhuma signal aos nosso slots. Para fazer isso, volte novamente ao Qt Designer ou re-abra se tiver fechado ele.

Selecione a ferramenta “connect signals/slots” (entre o Pointer e TabOrder na barra de ferramenta). Como nossa caixa de diálogo (dlgMain) e seus widgets contém os signals e slots que pretendemosusar, podemos conectar os signalsde diferentes widgets aos slots apropriados visualmente.

Simplesmente clique e arraste o mouse de um widget por um tempo até o mesmo ser destacado na caixa de diálogo e solte o botão do mouse. Na caixa de diálogo que aparece, conecte o signal “-clicked” de cada botão ao slot apropriado. O signal de pbAdd deve ser conectado a addItem, o de pbRemove a removeItem, e o de pbOk ao close. Para evitar que a ferramenta de conexão seja deselecionada após cada conexão, você pode dar um clique duplo na barra de ferramentas na primeira vez que selecionar ela.

Para verificar se os signals e slots estão conectados adequadamente, dê um clique com o botão direito e selecione as conexões no menu popup que aparece. A caixa de diálogo resultante deve mostrar o conteúdo da figura abaixo:

Agora, retorne ao console, execute o make e rode o executável resultante. Se tudo estiver Ok, deve funcionar como pretendido.

Antes de completar esse capítulo, gostaria comentar um ponto sobre a arquitetura dessa aplicação. Não temos um loop de mensagens, nem um local de onde as coisas são controladas. Ao invés disso, instanciamos uma caixa de diálogo, conectamos os slots e colocamos as funcionalidades nos slots. Isso é programação orientada a eventos.

Sumário

O código fonte desse capitulo pode ser baixafo aqui -> ex05.tar
Traduzido de http://www.digitalfanatics.org/projects/qt_tutorial/chapter05.html