Programacao Em Qt

28
Qt Qt é uma biblioteca de classes para a linguagem de programação C++, além disso ela também pode ser definida como um conjunto de ferramentas para escrever programas com interfaces gráficas e multiplataforma. Usando a filosofia "Escreva uma vez, Compile em qualquer lugar" o Qt traz uma infinidade de APIs, que podem ser usadas para diversos fins, tanto para criação de interfaces gráficas como já comentado antes quanto para tratamento de strings, manipulação de arquivos, criação de objetos OpenGL e diversas outras possibilidades, isso é possivel pois o QT herda toda a eficiência do C++ e seus recursos. Uma curiosidade interessante é que o QT é a biblioteca base do KDE, boa parte dos aplicativos escritos para o KDE tem o seu código fonte escrito em QT. A União QT/KDE fez com que os dois crescessem juntos de forma surpreendente. Origem do Qt O Qt começou a ser desenvolvido em 1991 quando Haavard Nord e Eirik Chambe-Eng decidiram escrever uma "Caixa de Ferramentas" em C++ para o desenvolvimento de interfaces gráficas de usuários. Erik teve a idéia de usar " sinais e slots (signals and slots)", simples mas um poderoso paradigma de programação de interfaces gráficas, Haarvard pegou a idéia e implementou o código fonte. Em 1993, eles tinham desenvolvido o primeiro kernel gráfico do QT e foram capazes de implementar os seus próprios widgets*, no final do ano Haarvard sugeriu que começassem um negócio juntos para criarem " A melhor caixa de ferramentas gráficas de C++ do Mundo).

Transcript of Programacao Em Qt

Page 1: Programacao Em Qt

Qt

Qt é uma biblioteca de classes para a linguagem de programação C++, além disso ela também pode ser definida como um conjunto de ferramentas para escrever programas com interfaces gráficas e multiplataforma. Usando a filosofia "Escreva uma vez, Compile em qualquer lugar" o Qt traz uma infinidade de APIs, que podem ser usadas para diversos fins, tanto para criação de interfaces gráficas como já comentado antes quanto para tratamento de strings, manipulação de arquivos, criação de objetos OpenGL e diversas outras possibilidades, isso é possivel pois o QT herda toda a eficiência do C++ e seus recursos.

Uma curiosidade interessante é que o QT é a biblioteca base do KDE, boa parte dos aplicativos escritos para o KDE tem o seu código fonte escrito em QT. A União QT/KDE fez com que os dois crescessem juntos de forma surpreendente.

Origem do Qt

O Qt começou a ser desenvolvido em 1991 quando Haavard Nord e Eirik Chambe-Eng decidiram escrever uma "Caixa de Ferramentas" em C++ para o desenvolvimento de interfaces gráficas de usuários. Erik teve a idéia de usar " sinais e slots (signals and slots)", simples mas um poderoso paradigma de programação de interfaces gráficas, Haarvard pegou a idéia e implementou o código fonte. Em 1993, eles tinham desenvolvido o primeiro kernel gráfico do QT e foram capazes de implementar os seus próprios widgets*, no final do ano Haarvard sugeriu que começassem um negócio juntos para criarem " A melhor caixa de ferramentas gráficas de C++ do Mundo).

O nome "QT" foi escolhido porque eles acharam a letra "Q" bonita na Haavard's Emacs font e o "t" foi adicionado para representar "toolkit"(caixa de ferramentas) inspirado no "Xt" o X Toolkit. A companhia que Haarvard havia sugerido foi criada primeiramente com o nome "Quasar Technologies", depois mudou para "Troll Tech" e hoje em dia "Trolltech".

Em maio de 1995 o Qt teve a sua primeira versão publicada, o Qt 0.90, que poderia ser usado para desenvolvimento tanto em Linux quanto em Windows, oferecendo a mesma API para as duas plataformas. O QT opera sob duas licenças, a licença comercial que é requerida para o

Page 2: Programacao Em Qt

desenvolvimento de softwares comercialmente e a free software edition que é avaliada para o desenvolvimento de software com o código aberto.

* widgets: símbolo gráfico de uma interface que possibilita a interação entre o usuário e o computador

Instalando o QT

Temos à nossa disposição uma variedade de métodos de instalação do QT, podendo variar dependendo da distribuição GNU/Linux que está sendo utilizada.

Como este curso é baseado na distribuição Debian, mostraremos como instalar o QT utilizando a ferramenta aptitude do debian.

Este curso é baseado no QT3 , portanto instalaremos o memos em 2 passos:

- Passo 1: primeiramente vamos verificar se o QT3 está disponível no repositório do debian com o comando:

$ aptitude search qt3

Este comando listará todos os pacotes que contenham QT3 no nome, dentre esse pacotes, os pacotes abaixo listados deverão estar presentes na saída deste comando:

libavahi-qt3-1

libqt3-headers

libqt3-mt

qt3-apps-dev

libqt3-mt-dev

Page 3: Programacao Em Qt

qt3-assistantq

qt3-dev-tools

qt3-doc

qt3-examples

- Passo 2 : Agora que temos certeza que os pacotes estão disponíveis para a instalação, basta executar o seguinte comando:

$ su (para você ficar com as permições de root, pra que seja possível instalação)

# aptitude install libqt3-mt-dev qt3-apps-dev qt3-assistant qt3-dev-tools qt3-doc qt3-examples

Pronto , Agora o Qt3 está instaldo e poderemos a partir daqui começar a escrever e compilar algumas linhas de código em QT. Que comece a Diversão!!!!!!

Começando a Diversão!

Nesta lição vamos mostrar como combinar o basico de C++ com as funcionalidades do QT para criar pequenas e simples interfaces gráficas e na próxima lição começaremos a falar um pouco sobre a idéia que originou o QT, "sinais e slots".

Hello QT

Vamos começar com o Hello QT, um programa simples que irá mostra na tela uma janela com "Hello QT - Yeah" escrito dentro dela. Primeiro irei mostrar o código fonte, depois explicaremos linha por linha e finalmente veremos como compilar o código.

Page 4: Programacao Em Qt

Hello QT:

Antes de partirmos para o entendimento do código. Faremos uma observação, no decorrer do curso você verá que os fontes dos programas estão como imagens. Isso não é para dificultar o aprendizado, muito pelo contrário. Estamos acostumado com o famoso "copy and paste", dessa maneira somos forçados a escrever o código no editor de texto e assim vamos entender e aprender melhor.

Entendendo o código

Nas linhas 1 e 2 estamos incluindo as classes QApplication e QLabel, são classes do qt, mais abaixo falaremos sobre elas.

Na linha 5 é um objeto QApplication que gerencia os recursos do programa.

O QApplication requer os argumentos argc e argv porque o QT suporta alguns argumentos em linha de comando, ou seja o QT aceita que sejam passados parâmetros ao programa na sua chamada.

Page 5: Programacao Em Qt

Na linha 6 é criado o *widget QLabel que irá mostrar "Hello QT - Yeahh!"

Na linha 7 é feito com que a (label) que foi criado na linha 6 se torne o widget principal, para que quando o usuário fechar a janela (clicando no X da barra de titulo da janela,por exemplo) o programa termine, casa não seja feito essa ligação, que torna a label a widget principal (main widget) quando o usuário fechar a janela o programa ainda continuaria rodando ocultamente. Em qualquer programa em que se deseja que o programa seja encerrado ao fechar uma janela, essa janela deve ser a widget principal, caso contrario o programa continuará em execução.

Na linha 8 é feito com que a label se torne visível, pois todos os widgets que são criados, por padrão, são ocultos, ou seja não são mostrados na tela.

Na linha 9 é passado o controle do programa, ou seja , é neste ponto que o programa entra em stand-by esperando a ação do usuário, clicks do mouse ou ações do teclado.

Vamos Compilar!

Agora que já escrevemos o primeiro código em QT, vamos aprender a compilá-lo, para gerar o executável desse código, assim então poderemos visualizar o resultado.

A primeira coisa que devemos fazer é: Criar um diretório "pasta" com o nome "hello" no qual salvaremos o código fonte com o nome de "hello.cpp".

Agora que já criamos o diretório e salvamos o código vamos usar o qmake em 3 etapas para compilar.

1ª etapa: Vamos criar o arquivo "hello.pro" que no caso é a plataforma independente do projeto, para criar o "hello.pro" vamos executar o seguinte comando:

# qmake -project

Page 6: Programacao Em Qt

2ª etapa: Agora que criamos o arquivo "hello.pro" vamos criar o mekefile para a plataforma específica a partir do "hello.pro" com o comando:

#qmake hello.pro

3ª etapa: Com o makefile criado vamos executar o comando make para compilar o código.

Pronto, depois de executar todas as etapas o código foi compilado e o arquivo hello foi gerado, esse arquivo é o executável do código fonte.

Vendo o Resultado

Com o código compilado e o executável gerado vamos ver como ficou a cara do osso programa.

Para rodarmos o programa basta executar o arquivo executável com o seguinte comando:

$./hello

A cara do programa será algo parecido com essa abaixo, dependendo de qual for o tema Desktop que esta sendo utilizado.

QButton

Nesta lição iremos substituir o rótulo (label) por um botão que estará ligado a um determinado evento, que neste caso terá a função de encerrar o aplicativo.

Um botão é um elemento comum de interface com usuário em toda plataforma: você clica e algum evento acontece. Em Qt, os botões são representados pela classe QPushButton, que é uma subclasse de QButton, que por sua vez é uma subclasse de QWidget, a classe básica de todos os elementos GUI deQt.

Page 7: Programacao Em Qt

Entendendo o código

#include <qfont.h>

Como este programa usa o QFont, então devemos incluí-lo no header.

QPushButton quit( "Quit", 0 );

Dessa vez nosso botão vai dizer "Quit", o que é exatamente a função dele: fechar o programa quando clicado.Passamos o parâmetro 0 para dizer que o botão é a janela primária.

Page 8: Programacao Em Qt

quit.resize( 75, 30 );

Aqui vamos alterar o tamanho do nosso botão. Poderíamos fazer isso com o QFontMetrics também.

quit.setFont( QFont( "Times", 18, QFont::Bold ) );

Aqui escolhemos uma nova fonte para o botão, neste caso uma fonte da família Times com 18 pontos e em negrito.

Também podemos mudar a fonte padrão usando "QApplication::setFont()".Teste isso depois!!

QObject::connect( &quit, SIGNAL(clicked()), &a, SLOT(quit()) );

Agora vamos ver a parte mais importante desta lição.

Vamos dar uma olhada nessa tal de SINAIS e SLOTS (Signal and Slot), que é necessário para entender o que acontece nesse método.

Sinais e Slots são usados para a comunicação entre objetos Qt. Sempre que o botão é clicado ele envia um sinal, neste caso um sinal clicked(). Este sinal significa que o objeto foi clicado e o objeto fica a espera de alguma resposta referente a essa ação.

Page 9: Programacao Em Qt

A partir daí outros objetos que pertencem ao programa podem se conectar com o widget para serem avisadas toda vez que o botão for clicado. Isso é feito através de um slot que tem a função de responder a um sinal em particular.

Sinais e Slots são conectados através do método QObject::connect(), em que recebe como parâmetros de entrada o objeto que emite o sinal "&quit", o sinal que é emitido "SIGNAL(clicked())", o objeto que recebe o sinal "&a" e o slot onde este sinal é recebido "SLOT(&quit)". Um único sinal pode estar ligado a vários slots, bem como a recíproca é verdadeira de que um único slot pode estar escutando vários sinais.

Parent e Child Widgets

Nesta lição vamos falar um pouco sobre Parent Widgets e Child Widgets (Widgets Pais e Widgets Filhos). Aqui vamos usar um único parent e um único child para facilitar nosso entendimento.

Vamos dar uma olhada no código abaixo que iremos testar.

Page 10: Programacao Em Qt

Entendendo o código

#include <qvbox.h>

Aqui nós incluimos o header vbox.h, que é a classe de layout que iremos usar.

QVBox box;

Com esta linha criamos uma caixa (box) em que seu conteúdo será alinhado verticalmente, ou seja, o QVBox organiza os child widgets em colunas verticais. Separando-os de acordo com o QWidget::sizePolicy() de cada um dos child (filhos).

box.resize( 200, 120 );

Page 11: Programacao Em Qt

Aqui setamos o tamanho do box para 200 pixels de comprimento e 120 pixels de altura.

QPushButton quit( "Quit", &box );

Um filho acabou de nascer! (A Child is born)

Diferentemente de como usávamos o QPushButton, aqui neste exemplo o criamos com o texto "Quit" e com o parent (box). Um child widget (widget filho) fica sempre em cima do seu parent (pai).

Quando o child é mostrado, ele é colocado dentro dos limites do seu parent.

O parent widget, neste caso o QVBox, adiciona automaticamente o child no centro do box. Como nada mais foi adicionado, o botão ocupa todo o espaço que o parent possui.

box.show();

Quando o parent widget é mostrado, com a linha mostrada acima, ele irá mostrar também todos os seus filhos (children), exceto aqueles que foram feitos com o parâmetro QWidget::hide().

Agora que já vimos as parte do código, vamos entender o que acontece de uma maneira mais conceitual. Como já haviamos dito, o botão não preenche mais o widget inteiro. Isso acontece porque agora existe um widget em um nivel mais alto, o qual é responsável por organizar o tamanho do botão e sua posição

MyWidget

Page 12: Programacao Em Qt

Nesta lição iremos ver como criar nosso próprio Widget, como controlar o tamanho e dar nome a ele.

Vamos agora ver o código com o qual iremos trabalho nessa lição:

Page 13: Programacao Em Qt

Entendendo o código

class MyWidget : public QWidget

{

public:

MyWidget( QWidget *parent=0, const char *name=0 );

};

Aqui nós criamos a nova classe. Como esta classe descende da classe QWidget, a nova classe é um widget e dessa maneira, será nossa mainwindow, ou seja, será nossa janela principal e as outras que iremos adicinar serão seus filhos (child).

Esta classe contém apenas um membro, o construtor. Aqui ele, construtor, é o padrão do Qt widget. Caso queria adicionar mais widgets, é necessário sempre incluir um construtor similar.

O primeiro argumento é o parent widget (widget pai). Como aqui estamos querendo que esse nosso widget seja o mainwindow (top-level window), o parâmetro parent do construtor é especificado como null (0).

O segundo argumento é o nome do nosso widget. Vale lembrar que esse nome não é aquele que aparece na barra de título do nosso widget ou o nome do botão. Na verdade é o nome associado ao widget com o qual poderemos referenciá-lo.

MyWidget::MyWidget( QWidget *parent, const char *name )

: QWidget( parent, name )

Page 14: Programacao Em Qt

É aqui que começa a implementação do construtor. Aqui nós estamos passando o parent e o nome para o construtor QWidget.

{

setMinimumSize( 200, 120 );

setMaximumSize( 200, 120 );

Como esse widget que criamos ainda não sabe lidar com alteração de tamanho, aqui nós definimos o tamanho máximo e mínimo. Esse "problema" nós iremos aprender a resolver na próxima lição, onde o usuário poderá alterar o tamanho do widget.

QPushButton *quit = new QPushButton( "Quit", this, "quit" );

quit->setGeometry( 62, 40, 75, 30 );

quit->setFont( QFont( "Times", 18, QFont::Bold ) );

Page 15: Programacao Em Qt

Aqui vamos criar e chamar o nosso widget filho (child widget) e como o estamos criando dentro do MyWidget, ele será referenciado como this. Antes definimos o que irá aparecer escrito no botão (Quit) e depois o nome do botão (quit).

Note que quit é uma variável local do construtor. MyWidget não mantém nenhum contrle sobre essa variável, mas o Qt sim e dessa forma ela será deletada assim que o MyWidget encerrar. É dessa forma que o MyWidget não precisa de um destrutor.

O setGeometry() faz o mesmo que o resize() da lição anterior.

connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );

}

Como a classe MyWidget não conhece o objeto da aplicação, ele precisa ser conectado o ponteiro para a aplicação, qApp.

O Widget é um componente de um software e deve saber o mínimo possível a respeito do ambiente em que está sendo usado. Para que assim possa ser geral e reusado o máximo possível.

E caso o Widget saiba o nome do objeto da aplicação, irá quebrar esse princípio. Dessa forma o Qt fornece um alias para ele, qApp, para o casos em que algum componente precise se comunicar com o objeto da aplicação.

Page 16: Programacao Em Qt

int main( int argc, char **argv )

{

QApplication a( argc, argv );

MyWidget w;

w.setGeometry( 100, 100, 200, 120 );

a.setMainWidget( &w );

w.show();

return a.exec();

}

Aqui nós instaciamos nosso novo filho (child), o coloca para ser o main Widget e executa a aplicação.

A diferença dessa lição para a anterior é o mode em que implementamos o child, que nos permite ter maio flexibilidade e reusabilidade.

Tente mudar o tamanho do nosso widget e incluir mais botões para ver o resultado.

Conectando widgets

Page 17: Programacao Em Qt

Nesta lição vamos aprender a criar e conectar widgets usando o signal e slots. Teremos algo como na figura abaixo:

Agora vamos ver o código que gerou esse widget:

Page 18: Programacao Em Qt

Entendendo o código

#include <qapplication.h>

#include <qpushbutton.h>

#include <qslider.h>

#include <qlcdnumber.h>

#include <qfont.h>

Page 19: Programacao Em Qt

#include <qvbox.h>

Aqui temos três novos includes que não tinhamos visto antes:

qslider.h : Precisamos dele pois utilizamos os Wigets que ele implementa, QSlider;

qlcdnumber.h : Da mesma forma que o qslider, iremos utilizar o widget QLCDNumber;

qvbox.h : Para utilizarmos o layout automatico do Qt.

class MyWidget : public QVBox

{

public:

MyWidget( QWidget *parent=0, const char *name=0 );

};

MyWidget::MyWidget( QWidget *parent, const char *name )

: QVBox( parent, name )

{

MyWidget é derivado do QVBox, diferentemente dos outros exemplos que era do QWdiget. Dessa forma, usamos o layout do QVBox que irá alinhar os widgets filhos verticalmente. Como a alteração de tamanho é suportada pelo QVBox, logo nosso MyWidget também terá essa característica.

QLCDNumber *lcd = new QLCDNumber( 2, this, "lcd" );

Page 20: Programacao Em Qt

Aqui chamamos o construtor do objeto lcd, que descende da classe QLCDNumber. Está é uma classe que mostra um display LCD com números. Passamos como parâmetro o 2, que irá definir que iremos mostrar um número de doi dígitos e que será filho de this, que nada mais é que nosso MyWidget. E esse nosso objeto se chamará "lcd".

QSlider * slider = new QSlider( Horizontal, this, "slider" );

slider->setRange( 0, 99 );

slider->setValue( 0 );

A classe QSlider é simplesmente um slider que serve para ajustar algum valor dentro de uma faixa determinada. Com essas linhas mostradas acima, nós criamos um slider horizontal, setamos sua faixa para número entre 0-99 e colocamos como valor inicial o 0.

connect( slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)) );

Agora vamos usar o signal/slot para conectar nosso slider com o displey de LCD. Faremos isso colocando como signal o método que altera o valor do slider (valueChanged(int)), porque este sinal é conectado ao LCD. Como slot colocamos o display do nosso LCD (display(int)), o qual é chamado quando o signal é produzido.

Blocos de Widgets

Page 21: Programacao Em Qt

Nesta lição iremos ver como encapsular dois widgets dentro de um novo componente e pela primeira vez vamos usar um widget criados por nós como um widget filho (child widget). Veja abaixo como vai ficar nosso widget.

Agora vejamos o código que gerou nosso widget acima:

Page 22: Programacao Em Qt

Entendendo o código

Page 23: Programacao Em Qt

class LCDRange : public QVBox

{

public:

LCDRange( QWidget *parent=0, const char *name=0 );

};

O widget LCDRange é um widget sem aplicação (API), ele contém somente um construtor. Um widget dessa maneira não é muito útil, mas iremos adicionar algumas aplicações depois.

LCDRange::LCDRange( QWidget *parent, const char *name )

: QVBox( parent, name )

{

QLCDNumber *lcd = new QLCDNumber( 2, this, "lcd" );

QSlider * slider = new QSlider( Horizontal, this, "slider" );

slider->setRange( 0, 99 );

slider->setValue( 0 );

connect( slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)) );

}

Essa parte veio do nosso MyWidget da lição anterior. A única diferença é que tiramos o botão e a classe foi renomeada.

Page 24: Programacao Em Qt

class MyWidget : public QVBox

{

public:

MyWidget( QWidget *parent=0, const char *name=0 );

};

O nosso MyWidget também não contém, aplicações, a não ser seu construtor. Podemos fazer uma analogia como se nosso MyWidget funcionasse como uma classe abastrata, para quem já

programou em java. Ou seja, as aplicações da nossa classe serão implementadas em outras classes.

MyWidget::MyWidget( QWidget *parent, const char *name )

: QVBox( parent, name )

{

QPushButton *quit = new QPushButton( "Quit", this, "quit" );

quit->setFont( QFont( "Times", 18, QFont::Bold ) );

connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );

O nosso botão, que costumava estar onde aqui temos LCDRange, está separado para que possamos ter um botão "Quit" e muitos objetos LCDRange.

QGrid *grid = new QGrid( 4, this );

Page 25: Programacao Em Qt

Aqui criamos o objeto QGrid com 4 colunas. O widget QGrid organiza automaticamente os widgets filhos em linhas e colunas. Podemos também especificar esses parâmetros e o QGrid

vai descobrir se um novo widget filho foi criado e irá inserí-lo na grade.

for( int r = 0 ; r < 4 ; r++ )

for( int c = 0 ; c < 4 ; c++ )

(void)new LCDRange( grid );

Aqui temos um loop para gerar as 4 linhas e 4 colunas.

Criamos um LCDRange 4X4 e todos são widget filhos do objeto QGrid.