Compilando com Qt Creator



A organização de Qt (Especial de Natal)
ANTERIOR
Página Inicial Em Desenvolvimento
PRÓXIMA


Criado em 12/01/2011 às 12:00

     



Depois de conhecer o modo com que Qt organiza seus arquivos vamos dar continuidade ao exemplo da lanchonete. Na página "O Poder do Qt Designer" fizemos o programinha através de uma visão puramente gráfica. Agora vamos implementar um pouco de funcionalidade a ele.

Antes de partir para o código propriamente dito, vamos alterar o formulário "ui" que havíamos criado para que possamos abrir uma nova janela quando o usuário clicar em um botão "Ajuda" por exemplo.



Então, abra o projeto novamente e de duplo clique no formulário dialog.ui, sob a pasta "Forms". Para adicionar um novo botão é necessário aumentar um pouco o tamanho atual da janela, porque um novo botão não cabe ali.

Perceba que se você tentar aumentar a janela você não conseguirá. Isso acontece porque nós tinhamos definido este tamanho como "Maximum Size" e "Minimum Size". Então acesse a propriedade maximumSize (de QWIdget) do "property editor" e clique no botão que tem uma pequena seta. O tamanho será redefinido para o tamanho máximo original (16777215x16777215).



Agora você pode expandir o quanto quiser. Para que nós entremos num acordo, ajuste as propriedades "Width" e "Height" da sua janela para 350 e 150 respectivamente. Depois disso insira um novo botão entre os dois botões pré existentes, mude seu texto de exibição para "Ajuda" e seu objectName para "ajuda".





Perceba que a imagem de fundo permaneceu do mesmo tamanho e começa a se repetir no eixo horizontal. Para consertar isso, Acesse seu arquivo "Resource" sob a pasta Resources, remova a imagem anterior e adicione a nova imagem deste link:



Não esqueça de adicionar a imagem à pasta de imagens.

Ao salvar o arquivo resource, o fundo atualizará automaticamente.

Agora criaremos a janela (dialog) que será exibida quando o usuário clicar em "Ajuda".

Da mesma forma que fizemos para adicionar um arquivo resource:
  • clique com o botão direito no projeto
  • escolha "Add New..."
  • Qt, Qt Designer Form class,
  • Dialog without buttons, ok
  • mude o nome para "DialogoAjuda":









Neste novo formulário adicione uma nova label, para mudar seu texto de forma que exiba mais do que uma linha de texto acesse a propriedade "text" no proprety editor. Clique no botão "..." e escreva um texto qualquer.





Clique no formulário e aplique um layout vertical (ou horizontal, já que só temos uma coisa para alinhar) e clique no botão Adjust Size.

Com isso nosso dialog adicional está pronto.



Neste momento, seus arquivos devem se apresentar da seguinte forma:



Agora que todos os forms estão desenhados, é hora de partir para o código. Você pode testar seu programa agora para ver se tudo está funcionando corretamente clicando no botão "Run" ou pressionando Ctrl+R:



Mas é claro que os botões ainda não funcionam, você ainda não os conectou.

Nada mais justo que começarmos pelo main (que já está pronto):

Código 12. main.cpp do programinha "lanchonete".
#include <QtGui/QApplication>   //QObject-QCoreApplication-QApplication
#include "dialog.h"

int main(int argc, char *argv[])
{

    QApplication a(argc, argv);
    Dialog w;
    w.show();

    return a.exec();
}


No main, nada de novo certo? A classe Dialog é a classe que foi criada automaticamente pelo QtCreator quando escolhemos o nome "Dialog" la no começinho. Vamos ao código de dialog.h (header do dialogo que criamos no designer, que tem os radio buttons e botões):

Código 13. dialog.h do programinha "lanchonete".
#include <QDialog>  //QObject-QWidget-QDialog

namespace Ui {
    class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;

    //adicionado
public slots:
    void ok_clicado();
    void cancel_clicado();
    void abrir_ajuda();
};

#endif // DIALOG_H


Começamos com um include de QDialog, por que derivamos dela afinal.

O namespace Ui é obra do QtCreator, lembra? ele define esse namespace quando trabalhamos com formulários.

O macro Q_OBJECT é necessário porque neste caso implementaremos nossos próprios slots. Nós poderiamos escolher os slots padrões de fechamento de diálogos para os botões OK e cancelar (accept() ou reject()) mas nós queremos que seja exibida uma mensagem antes que o dialog feche, então vamos criar nosso proprio slot. Lembre-se de que slots podem ser chamados como funções, não necessariamente numa conexão. Vale a pena destacar que accept() e reject() são funções virtuais e nesse caso provavelmente seriam reimplementadas, mas do jeito que está é mais simples para quem está começando.

As declarações públicas compreendem as funções construtora e destrutora.

A declaração private compreende apenas o ponteiro Ui, que é elo de ligação entre nosso formulário e o código.

As declarações slot publicos são nossos 3 slots, um para cada botão clicado.

Vamos à implementação desta classe (dialog.cpp):

Código 14. dialog.cpp do programinha "lanchonete".
#include "dialog.h"
#include "ui_dialog.h"
#include "dialogoajuda.h"

#include <QMessageBox>  //QObject-QWidget-QDialog-QMessageBox

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    connect(ui->ok, SIGNAL(clicked()), this, SLOT(ok_clicado()));
    connect(ui->cancel, SIGNAL(clicked()), this, SLOT(cancel_clicado()));
    connect(ui->ajuda, SIGNAL(clicked()), this, SLOT(abrir_ajuda()));
}

void Dialog::ok_clicado()
{
    QString saindo;
    saindo = "Saindo um ";

    if(ui->xSalada->isChecked())
    {
        saindo += "X-Salada, ";
    }
    else
    {
        if(ui->xFrango->isChecked())
        {
            saindo += "X-Frango, ";
        }
        else
        {
            if(ui->xTudo->isChecked())
            {
                saindo += "X-Tudo, ";
            }
            else
            {
                saindo += "X-Nada, ";
            }
        }
    }
    saindo += "com refrigereco ";

    if(ui->noCal->isChecked())
    {
        saindo += "light ";
    }

    if(ui->noGelo->isChecked())
    {
        saindo += "sem gelo ";
    }

    saindo += "!!";
    QMessageBox::information(this,"Pedido Finalizado!", saindo);

    this->accept();
}

void Dialog::cancel_clicado()
{
    QString saindo("Saindo um cliente descontente !!");

    QMessageBox::information(this,"Pedido Finalizado", saindo);
    this->reject();
}

void Dialog::abrir_ajuda()
{
    DialogoAjuda dialog(this);
    dialog.exec();
}

Dialog::~Dialog()
{
    delete ui;
}


O código pode parecer grande, mas optei por fazer um código bem simples e claro, mas não é tão grande. Começamos pelos includes das nossas classes (tanto a classe criada inicialmente quanto a adicionada posteriormente). Incluímos também a classe QMessageBox porque iremos mostrar uma mensagem quando o usuário clicar em Ok ou cancelar. Para mensagens simples, podemos usar este dialog pré-pronto QMessageBox. Veremos mais adiante.

A construtora começa já chamando a construtora de QDialog e inicializando o ponteiro ui (no cabeçalho). "setupUi" é chamada para vestir a roupa que projetamos no designer no dialog criado no main. Depois disso, os slots mostrados são conectados a cada botão através do signal "clicked()", um signal padrão de botões.

O nosso slot "ok_clicked()" nada mais faz do que criar uma string e povoá-la com um texto dependendo do que estiver selecionado na janela. Veja como acessamos os objetos do nosso formulário através do ponteiro Ui. "isChecked()" é a função que nos permite saber se aquele radio button está checado retornando true ou false.

Depois de analisar todas as possíveis escolhas, o programa exibe uma mensagem informando qual é o pedido através da função estática "information" de QMessageBox. QMessageBox é um dialogo pré-pronto de Qt que permite que nós exibamos mensagens na tela através de uma janela. Ele tem algumas funções estáticas que permitem que nós chamemos alguns tipos pré-definidos de dialogs sem termos necessariamente que instanciar uma nova classe QMessageBox. Além da função information, existem outras (que já tem o ícone bonitinho do lado esquerdo):
  • QMessageBox::question(parent, título, texto)
  • QMessageBox::information(parent, título, texto)
  • QMessageBox::warning(parent, título, texto)
  • QMessageBox::critical(parent, título, texto)

Estas são algumas funções estáticas e alguns parâmetros. A utilidade do parâmetro "parent" será discutida mais adiante. Outra forma de se fazer isso é instanciando uma classe QMessageBox e personalizando-a inteira.

O mesmo raciocínio se aplica para o botão cancelar. O botão de ajuda exibe um dialog criado por nós. O slot conectado a esse botão cria uma nova instancia para a classe "DialogoAjuda" e já manda ele entrar no loop de eventos (exec()). É isso mesmo, só de chamar a função exec() do dialog recém-criado ele já é exibido. O parâmetro this e a função exec() serão discutidos mais a frente.

Os códigos para "dialogoajuda.h" e "dialogoajuda.cpp" são criados automaticamente pelo QtCreator e nós não mudamos nadinha de nada, já que fizemos alterações apenas no formulário. Essas mudanças no formulário estarão na caixinha de supresas e como não implementamos absolutamente nada no ".cpp" então a construtora apenas chama setupUi. Mas aqui estão os códigos:

Código 15. dialogoajuda.h do programinha "lanchonete".
#ifndef DIALOGOAJUDA_H
#define DIALOGOAJUDA_H

#include <QDialog>

namespace Ui {
    class DialogoAjuda;
}

class DialogoAjuda : public QDialog
{
    Q_OBJECT

public:
    explicit DialogoAjuda(QWidget *parent = 0);
    ~DialogoAjuda();

private:
    Ui::DialogoAjuda *ui;
};

#endif // DIALOGOAJUDA_H
Código 16. dialogoajuda.cpp do programinha "lanchonete".
#include "dialogoajuda.h"
#include "ui_dialogoajuda.h"

DialogoAjuda::DialogoAjuda(QWidget *parent) :
    QDialog(parent),

    ui(new Ui::DialogoAjuda)
{
    ui->setupUi(this);
}

DialogoAjuda::~DialogoAjuda()
{
    delete ui;
}


Agora que todos os formulários estão criados, os botões conectados, os slots implementados, é hora de compilar. Quando se usa o QtCreator, ao clicar no botão "Run" ele executa o "make.exe" sozinho então não é necessário mais o uso do prompt de comando. TRY IT!

Responda as questões abaixo para um melhor entendimento do comportamento de dialogs abertos a partir da janela principal.


Exercício 3

i) O que acontece se passarmos "0" ao invés de "this" como parent das nossas QMessageBox::information?
ii) O que acontece se instanciarmos nossa classe Dialogoajuda sem utilizar a construtora ("DialogoAjuda dialog;" ao invés de "DialogoAjuda dialog(this)")
iii) Qual a diferença de comportamento entre "janela que mandou abrir" e a "janela aberta" quando executamos a função exec() ou show() ("dialog.exec()" e "dialog.show()").


Exemplo desta página, clique aqui

     



A organização de Qt (Especial de Natal)
ANTERIOR
Página Inicial Em Desenvolvimento
PRÓXIMA


Comentários: Compilando com Qt Creator

Se você tiver alguma sugestão ou dúvida, por favor, preencha o formulário abaixo. O seu comentário só será adicionado após uma verifição do conteúdo.



Nome*:

Email*:

Mensagem*: