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*:


Nome: Danilo Domingos
2011-02-23 14:10:48, disse:

Caros leitores, estou ocupadíssimo no momento, mas em breve continuarei postando mais.

Quero inclusíve mudar o layout do site e deixá-lo mais atraente.

Desculpem pela demora. Obrigado pelos e-mails enviados.

23/02/2011
Nome: Herbert Hudson
2011-03-15 20:02:23, disse:

Boa noite,

Cara, muito bom o tutorial, fino demais! está sendo uma mão na roda, exatamente o que eu precisava, muito bom mesmo, se puder continuar com o tutorial, ficarei agradecido! não só eu mas a comunidade também.
Nome: Danilo Domingos
2011-03-16 08:28:44, disse:

Obrigado Hebert!

Pretendo continuar em breve!
Nome: Alexandre Arrieche de Conti
2011-06-13 14:50:13, disse:

Dan muito bom tutorial !!

No Brasil é difícil achar literatura sobre o assunto, então temos que contar com pessoas como vc, que por sinal fez um excelente tutorial muito bem explicado.

Valew !! estou ansioso pelos próximos tópicos.
Nome: Danilo Domingos
2011-06-14 08:53:41, disse:

Valew Alexandre!
Nome: Eduardo Alves da Silva
2011-07-01 18:43:42, disse:

Cara agradeço pelo seu empenho em realizar este tutorial, que já dá um grande pulo para quem está começando com Qt.
Eu comecei a mexer com Qt só através da documentação que é ótima, mas alguns detalhes que você passou ajudou muito na minha percepção em que eu devo ter passado batido quando olhei na documentação. Valeu ai e parabéns pelo trabalho bem feito.

[]s.
Nome: Danilo Domingos
2011-07-05 10:06:45, disse:

Muito obrigado Eduardo! Jájá tem mais!
Nome: Lincoln
2011-07-25 13:24:05, disse:

Parabéns pelo excelente tutorial! Foi muito útil. Aguardamos ansiosos os próximos :)
Nome: Toni
2011-09-11 11:00:25, disse:

Por favor continue com seu tutorial, ele salva pessoas tapadas(como eu) que querem se meter com programação '-'
Nome: jose joan
2011-09-20 19:20:09, disse:

Como vai amigo, preciso tirar duas dúvidas:
1 - No Qt tenho um DoubleSpinBox,mas preciso tranformar ele em uma variável para que eu possa fazer calculos com ela, como devo fazer isso, já tentei usar Valuechange(double d) por exemplo, mas não funcionou.

2 - Depois que conseguir essa variável quero usá-la em uma outra classe.

Por exemplo: a variável foi obtida no Mainwindow.cpp e quero realizar os calculos em calculo.cpp
Nome: Danilo Domingos
2011-09-21 09:53:52, disse:

Olá José Joan,

Não existe uma única forma de fazer o que você deseja. No entanto vou apresentar uma aqui, lembrando que não tem certo e errado.

1) Para utilizar a spinbox para se fazer contas podemos utilizar seu SIGNAL valueChanged(double) ou então acessar seu valor atraves do ponteiro ui->doubleSpinBox->value.

Para exemplificar eu fiz um projetinho que consiste em duas DoubleSpinBoxes (chamadas doubleSpinBox e doubleSpinBox_2) e um LineEdit (chamado lineEdit). Na medida que você varia o valor das SpinBoxes o LineEdit imprime a multiplicação entre os valores contidos no SpinBox.

Na construtora da MainWindow eu fiz as seguintes conexões para as spinBoxes:
connect(ui->doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(conta(double)));
connect(ui->doubleSpinBox_2, SIGNAL(valueChanged(double)), this, SLOT(conta(double)));

O slot conta(double) eu criei (lá na MainWindow.h) e dentro dele acontece o seguinte:
ui->lineEdit->setText(QString("%1").arg(ui->doubleSpinBox->value()*ui->doubleSpinBox_2->value()));

Ou seja, o lineEdit vai passar a exibir a multiplicação entre as spinboxes. Esse SLOT vai ser chamado sempre que o valor de um dos SpinBoxes mudar.

Vou disponibilizar estes arquivos para download: Clique aqui para baixar

Qualquer dúvida em relação à sintaxe é só falar. (jájá comento sua pergunta 2)
Nome: Danilo Domingos
2011-09-21 15:22:05, disse:

Pra utilizar o valor da spinbox em outra classe (talvez uma nova janela que abrirá), existem vários jeitos.

- pode passar por parâmetro na construtora da sua classe, mas isso é ruim caso tenha q passar mais variáveis
- pode passar o ponteiro UI na construtora da sua classe, assim pode acessar todos os atributos que o UI aponta.

Existem vaŕias formas.
Abraço
Nome: Danilo Domingos
2012-04-23 18:08:06, disse:

Galera, no momento estou extremamente ocupado e não estou conseguindo dar continuidade nos tutoriais. Mas não pensem que esqueci de vocês!

O próximo é uma simples calculadora de bases numéricas que já está pronta, só preciso editar.
E para planos futuros já estava pensando abordar bancos de dados.
Nome: David
2012-05-01 20:03:04, disse:

Olá, gostaria de saber como uso o QT apenas como uma IDE C++ normal, sem fazer uso das lbs QT. Quero usar o QT apenas como um Eclipse C/C++ ou um CodeBlocks. Procurando na net vi que tem que configurar o build settings, mas não entendi bem.
Nome: Danilo Domingos
2012-05-02 13:02:40, disse:

Oi David,

Eu já usei o Qt Creator como uma IDE C++ e não precisei modificar nada. O bom dele é a auto-completação, o esquema de cores e de identação. Dá até pra você colocar um Help estilo Qt Assitant para C++.

Se você quiser rodar seu código como se fosse um CodeBlocks ou DevC++ com saída no prompt de comando ai você escolhe "Qt Console Application" quando for criar um novo projeto:

Nome: cristiano leite cristino
2013-09-23 01:07:46, disse:

Muitíssimo obrigado pelo tutorial, o melhor sobre QTCreator.
estou cursando BSI e nem meu professor explica tão bem quanto você. continue com seus tutoriais...
Nome: Ricardo
2012-12-11 17:07:07, disse:

Olá

Danilo muito bom esse seu tutorial está me ajudando muito.

Espero que vc de continuidade a esse grande trabalho.

Vlw
Nome: Solander Lopes Agostinho
2013-04-12 11:20:06, disse:

Olá... tentei chamar uma tela através de um botão do jeito que v fez com a tela de ajuda (usando o .exec) mas não funcionou. So que a tela que eu to tentando chamar é do tipo QMainWindow e sua de ajuda é QDialog. o que faço pra chamar outra tela quando ela é QMainWindow? OBS: tentei .show mas quando clico no botão pra chamar ela aparece e desaparece rápido.

att.