Tutorial Qt – Capitulo 01 – Qt Acoplamento fraco e Programação dirigida a evento

Qt é conhecida por muitas pessoas como um kit de ferramentas para programação multiplataforma, mas ela é muito mais. Qt suporta, além de interfaces com o usuário, banco de dados, arquivos, sistemas de arquivos, sockets (para conexão com computadores em uma rede) de uma maneira independente de plataforma. Isso tem prós e contraas, não é necessário zilhões de bibliotecas para cada aplicação, mas tem o preço de tornar a biblioteca bem extensa.

Qt é escrita em C++, mas existem formas de usa-la com programas escritos em linguagens como C, Python, C#, etc. É totalmente orientada a objeto e pode ser considerada direcionada a eventos.

Qt estende C++ com “signals” e “slots” usando o ‘moc’, o compilador de meta-objetos (meta object compiler). Isso permite a criação de componentes de baixo acoplamento que permitem ser reutilizados.

Neste capitulo introdutório nós criaremos a uma aplicação muitos simples que mostra o jeito do código da interface do Qt. Este capitulo constroi o código do zero, mas (naturalmente) existe um ambiente de desenvolvimento integrado (IDE) que permite “desenhar” as interfaces com o usuário. Iso será explicado no capitulo cinco e posteriores.

Começe criando um novo diretório para guardar os arquivos da aplicação. Eu chamarei de ex01, mas isso é só minha convenção de nomenclatura para os exemplos deste livro.

Uma interface grafica com o usuário (GUI na sigla em inglês), consiste de “widgets” (ou controles como eles são chamados no win32). Esses widgets também consistem de outros widgets e são chamados de widgets compostos, ou são um widget único como um button, line edit ou qualquer outro elemento que você encontra em sua aplicação. Nós iniciaremos nosso próprio widget composto.

Crie o arquivo mywidget.h no diretório que você criou, então cole o código baixo:

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include [qvbox.h]

class MyWidget : public QVBox
{
Q_OBJECT

public:
MyWidget( QWidget *parent = 0, char *name = 0 );
};
#endif

Este código parece bem normal para quem usa C++. O que nós fizemos é que nós herdamos a classe QVBox que é só um widget que contém outros widgets que são colocados no topo dos outros, isto é, são ordenados verticalmente. Isto significa que qualquer widget que nós coloquemos neste será ordenado verticalmente, do topo para o fundo. Os parametros do construtor, “parent” e “name”, são passados pela classe base até eles atingirem o QObject. Isso é usado para gerenciar a memória e simplificar a depuração da aplicação resulante. O Q_OBJECT macrp faz algumas mágicas maravilhosas como ativar “signals” e “slots”. Mais sobre isso pode ser encontrado na documentação da Trolltech e mais tarde nesse tutorial.

Agora para a implementação. Crie um novo arquivo: mywidget.cpp e salve-o no mesmo diretório que o mywidget.h. Cole o código abaixo no arquivo:

#include [qlcdnumber.h]
#include [qslider.h]

#include “mywidget.h”

MyWidget::MyWidget( QWidget *parent, char *name ) : QVBox( parent, name )
{
QLCDNumber *lcd = new QLCDNumber( this );
QSlider *s = new QSlider( QSlider::Horizontal, this );

connect( s, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)) );
}

As linhas “include” no topo são as duas classes Qt que nós usamos: QLCDNumber e QSlider. A parte interessante esta no construtor. Primeiro, nós chamamos o construtor do QVBox para passar para ele os “parent” e “name” por todas as classes bases até que elas alcançem o QObject que é a classe base de (quase) todas as classes da Qt. No corpo do construtor nós instanciamos um numero LCD e um deslocador (slider). Nós chamamos eles no “this”, isto é, nós colocamos eles em nosso widget onde serão exibidos do topo para o fundo, isto é, o número em cima do deslocador. Agora fazemos as ações dos “signals” e “slots”. Nós conectamos o “signal” valueChanged(int) do deslocador no “slot” display(int) do número LCD.

Muitos programadores C++ reagirão a este código dizendo que criamos um novo objeto mais não deletamos ele. Isso é feito pela classe base de que cada widget nosso foi derivado. Através da QVBox (e algumas classes mais) nós herdamos a classe QObject que deleta seus filhos quando deletada. Então, quando nosso widget for deletado, o número LCD e o deslocador será deletado junto.

Finalmente, nós criamos um arquivo main.cpp em nosso diretório e colocamos o main normal mostrado abaixo:

#include [qapplication.h]

#include “mywidget.h”

int main( int argc, char **argv )
{
QApplication a( argc, argv );

MyWidget *w = new MyWidget();
a.setMainWidget( w );
w->show();

return a.exec();
}

Primeiro nós criamos uma QApplication. Isso pode ser feito uma única vez por processo e fornece-nos um contexto para trabalho. Então nós instanciamos nosso widget, configuramos como o widget pricipal da aplicação e exibimos ele. A última coisa que nós fazemos é chamar a função exec() da aplicação. Esse método carrega nossos loops de gatilho de eventos do deslocador, que emite o sinal que nós conectamos ao número LCD, então nós temos uma aplicação funcional.

Para compilar essa aplicação, nós precisamos rodar o comando “moc” no widget e então compilar a saida do “moc”e linkar tudo junto. Isso é muito fácil graças ao qmake. Simplesmente digite qmake -project && qmake && make no console e rode a aplicação. Isso fará todas as coisas que são necessárias. Se você rodou sem qualquer problemas de compilação do código, olhe o capitulo quatro e tente configurar o ambiente de desenvolvimento. Se isso não foi bem sucedido, tente o capitulo três e vasculhe diferentes fontes de informação disponiveis na Internet.

Agora, finalmente, eu me permitirei filosofar um pouco. Eu mencionei anteriormente neste capitulo sobre acoplamento fraco. Repare que o deslocador não sabe que ele está mudando um número LCD. na verdade, ele não sabe que muda alguma coisa, ele só emite o sinal. Da mesma maneira, o número LCD não sabe quem está chamando o método de exibição. Poderia ser código comum, ou um sinal. Eles são fracamente acoplados. isso ajuda fortemente na modularização dos widgets e então torna fácil o reuso deles no futuro.

Sumário

Aqui você encontra o código dos exemplos desse capitulo -> ex01.tar

Traduzido de http://www.digitalfanatics.org/projects/qt_tutorial/chapter01.html