Primeira Aplicação



Estrutura de uma Aplicação
ANTERIOR
Página Inicial Pais e Filhos, quer dizer, e Signals/Slots
PRÓXIMA


Criado em 24/09/2010 às 21:29

     



Bom, se o primeiro exemplo não fazia nada, esse não está muito longe. Antes de irmos para o código, dê uma olhada no resultado:



Eu sei que você está ansioso mas, para criar esse exemplo, você vai resistir à tentação de abrir o Qt Creator ou o Qt Designer e vai abrir qualquer editor de texto, eu aconselho o NotePad++. ...Tudo bem, eu sei que você já abriu... já arrastou uns trequeté pra lá e pra cá... virou pra sua mãe e disse "olha mãe!", mas agora fecha e abre o editor! Coloque o nome de "main.cpp" e digite o código abaixo, onde substituimos a linha //algum código, por algum código (4 novas linhas)!

Código 2. Código que gera o Zé Pequeno(main.cpp).
#include <QApplication>
#include <QLabel>

int main(int argc, char * argv[])
{
	QApplication app(argc, argv);
	
	QLabel textinho("Que mané Hello World oq!? Meu nome é Zé Pequeno!");
	textinho.resize(400,80);
	textinho.setAlignment(Qt::AlignCenter);
	textinho.show();

	app.exec();
}

Primeiramente, para cada objeto criado numa aplicação Qt dá-se o nome de Widget (não exatamente todos). Exemplos de Widgets são Botões, Labels, ComboBoxes, DropBoxes, LineEdits, Botões de novo, RadioButtons e etc. Os processos envolvidos na criação de widgets (como a nossa Label , que não passa de um texto pequeno) são os seguintes:

Criação da Widget: QLabel textinho("Que mané Hello World oq!? Meu nome é Zé Pequeno!");
Configuração da Widget:    

textinho.resize(400,80);
textinho.setAlignment(Qt::AlignCenter);
Exibição da Widget: textinho.show();

Note que a Widget "textinho" pode ser inicializada com uma de suas construtoras "QLabel ( const QString & text, QWidget * parent = 0, Qt::WindowFlags f = 0 )" , vide Qt Assistant. O primeiro parâmetro é uma String do Qt (QString). O segundo parâmetro de sua construtora é uma variável do tipo QWidget que, se fosse informada, seria a mãe (ou pai) da nossa Label. Como não passamos nenhum valor para estes parâmetros (parent e f), eles são inicializados como 0 (como podemos ver pela construtora). Você ainda vai ver muito essa classe QWidget e o esquema de parentesco.
A nossa label também poderia ser inicializada sem parâmetro nenhum ( QLabel textinho ), utilizando a construtora "QLabel ( QWidget * parent = 0, Qt::WindowFlags f = 0 )" e, posteriormente, em sua configuração digitar "textinho.setText("Que mané Hello World oq!? Meu nome é Zé Pequeno!")". Vide Qt Assistant.

Já que a nossa label é o único Widget da aplicação, dizemos que ela é uma janela (Window), e não somente uma window mas sim uma Top-Window, filha de ninguém, e nesse caso nem usa crianças na sua quadrilha. Então, se alterarmos o seu tamanho, ela vai influenciar diretamente a janela principal da aplicação. Em relação ao alinhamento central, utiliza-se a função "void setAlignment ( Qt::Alignment )", onde seu parâmetro é uma flag. Outros exemplos de flag são: Qt::AlignLeft, Qt::AlignRight, Qt::AlignHCenter, Qt::AlignVCenter. Vale lembrar que existem diversos outros modos de lidar com a geometria da sua janela.

Agora Basta exibir a Widget com a função show(). Não esqueca de incluir a diretiva "#include <QLabel>" no começo do código.

Futuramente utilizaremos bastante alocação dinâmica de memória, ou seja, usaremos ponteiros para criar nossas widgets. Então lembre-se: para acessar membros de ponteiros usamos "->" e para acessar membros de variáveis na pilha (como no Código 2) usamos ".".


Procedimento de Compilação dos Códigos

Beleza, compile o seu programa! (Atenção: este não é o único meio de compilar seus programas em Qt, na verdade, não será o meio pelo qual você compilará seus programas. Mas para uma primeira aproximação é o suficiente.)

  • Abra o Prompt de comando do Qt
  • Vá até o diretório do seu arquivo "main.cpp"
  • Digite o comando: qmake -project
  • Digite o comando: qmake
  • Digite o comando: make
Se suas variáveis de ambiente estiverem corretas, no diretório do arquivo "main.cpp" serão criados alguns arquivos e algumas pastas. O seu executavel estará dentro da pasta "Debug".

Exemplo de compilação bem sucedida.



Relação entre Parentesco e Memória Heap

Antes de tudo, vamos relembrar como funciona a alocação de memória heap no C++:

Fragmento de Código. Criação de variável na memória heap.
tipoDaVariavel *var = new tipoDaVariavel;
//código
delete var;

No C++, a criação (new) de uma variável na heap culmina inevitavelmente num delete da mesma variável por parte do programador. Veremos que no Qt é aconselhável criar variáveis na heap e nós podemos inclusive, em alguns casos, omitir o delete. No C++ isso é um crime, ou melhor, Memory Leak! Mas o Qt lida com isso para nós deletando as variáveis (que tem um parent) automaticamente, facilitando nossa vida. Toda widget mãe terá seus filhos deletados quando a própria mãe for deletada, estejam os filhos na heap ou no stack. No exemplo do Código 2 nós não temos filhos, mas vale apena introduzir este conceito nesse momento.

Mas então você pergunta:
Por que usar variáveis na heap então?



De acordo com o livro "The Book of Qt 4: The Art of Building Qt Applications" (pág. 32, nota de rodapé 6), as variáveis do stack serão deletadas uma vez que exec() retorne "quit" e o programa acabe. Nesse momento, as variáveis mãe vão tentar "matar todas as filhas". Se as filhas estiverem na stack, podem ocorrer problemas como "a filha já estiver sido deletada dentro de algum bloco de código" ou então "dependendo da ordem que o compilador empilha as variáveis na stack". Para evitar complicações desse tipo, recomenda-se que as filhas sejam criadas na heap, o mesmo para as filhas das filhas e assim por diante.

O melhor uso desse esquema de deletes automáticos é para interfaces gráficas compostas de dezenas de widgets. De forma que simplesmente ao fechar a janela/widget, todas as filhas são deletadas também, economizando preocupação pro lado do programador em relação a rastreio de variáveis da heap. Variáveis adicionais da heap (sem parent) devem ser "cuidadas" e deletadas pelo programador.

Outros exemplos de designação de parentesco serão mostrados adiante, mas você já sabe de antemão: quando variáveis mãe são deletadas, as filhas também serão e a forma mais prática de assegurar a ausência de problemas é criando as filhas na heap.

**Sugestão de alteração da sessão "Relação entre Parentesco e Memória Heap" por Matheus Saraiva e Luiz Augusto (Qt Brasil). Obrigado! (01/10/2010)
Exercício 1

Crie um programa semelhante ao mostrado, mas mande ele exibir (show()) duas QLabel diferentes, cada uma com uma variável no STACK, cada uma com um comando show() e responda:

i) Como o programa mostra as frases? na mesma janela ou em janelas diferentes?
       Pense a respeito: Se forem abertas duas janelas, a nossa variável QApplication está "olhando"
       pra qual delas? em qual delas o loop de eventos está ativo?

ii) Se for em janelas diferentes, qual aparece sobreposta a qual? A ordem importa?
iii) Se for em janelas diferentes procure, no Qt Assistant, um meio de alterar o título das janelas de cada label.
       Dica: a classe QWidget tem uma função que altera o título da janela do widget (caso não tenha pais), será que QLabel têm QWidget como antepassado?

OBS: Não fique preso aos exemplos aqui passados, vá tentando fazer a coisa acontecer!





     


Estrutura de uma Aplicação
ANTERIOR
Página Inicial Pais e Filhos, quer dizer, e Signals/Slots
PRÓXIMA


Comentários: Primeira Aplicação

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: Matheus Saraiva
2010-09-30 20:32:24, disse:

Fala grande Dan!

Bem vc escreveu que a memória é desalocada no momento em que a aplicação é fechada, mas a aplicação não vai consumir muita memória a medida que o usuário for manipulando a aplicação? Tipo o usuário abre uma determinada parte da aplicação para realizar alguma tarefa e nessa parte são criadas várias variaveis na Heap, depois que ele terminar e voltar para o controle principal da aplicação as variaveis continuarão na memória consumindo espaço desnecessariamente.
Ai depois ele entra em outra parte que cria um outro monte de variáveis na heap agora são as variaveis da parte1+parte2 consumindo espaço desnecessariamente.
Não sei se esse meu raciocínio está correto, pois não sou expert em c++, mas se estiver acretido que não seja uma boa prática deixar pra limpar a memória só depois que fechar a aplicação.
Nome: Danilo Domingos
2010-09-30 22:33:12, disse:

Ok, vamos lá..

Vamos supor que a aplicação começou, então temos as variáveis do GRUPO1 (geradas na janela principal da aplicação).

Se o usuário abrir uma nova tarefa, como uma janela ou um Dialog (é visto nas páginas subsequentes), e criar novas variáveis nessas novas janelas (GRUPO2, total=GRUPO1+GRUPO2) essas variáveis só serão destruídas se a janela/dialog for fechada. Fazendo que as variáveis totais voltem a ser só GRUPO1.

Agora se a tarefa rodar dentro da janela principal ai acontece como você falou, GRUPO1+GRUPO2 até o fim.

Eu acredito que para evitar isso, você tenha que planejar suas tarefas de forma que apenas variáveis vitais para a aplicação persistam depois de determinadas tarefas.



Vale lembrar que esse gerenciamento de memória é exclusivo do Qt, em C++ teríamos que excluir as variáveis manualmente.

Vamos ver o que o pessual do fórum QtBrasil acha disso:

http://forum.qtbrasil.com/viewtopic.php?f=6&t=40

Valew pelo comment!
Nome: Raniere
2011-04-02 08:55:32, disse:

E ai kra,

muito bom seus tutoriais.
Tentei fzer este, so q na compilação da dois erros, e nas variaveis de ambiente, eu verifiquei q n tem a pasta chamada qt\bin e a bin onde foi instalado meu sdk, pode ser isso q esta dando erro, vc sab como arrumar isso???

Valew
Nome: Danilo Domingos
2011-12-05 15:09:35, disse:

Olá Raniere. Poste o erro que está dando! Assim posso ter mais informações sobre o erro.
Nome: Ana
2012-04-23 17:36:15, disse:

Onde eu vou digitar esses comandos?
não encontro o prompt de comando do qt
Nome: Danilo Domingos
2012-04-23 17:47:36, disse:

Olá Ana. O Objetivo neste estágio era digitar o código num editor qualquer, como num bloco de notas. E compilar na raça, manualmente. Apenas para fins didáticos.

Mas no final das contas vc vai acabar digitando tudo no Qt Creator mesmo. E compilando por lá também. O Qt Creator é uma ferramenta incrível e deve ser utilizada, sem dúvidas.
Nome: Ana
2012-04-25 12:46:51, disse:

Danilo,
na seguinte parte:

Abra o Prompt de comando do Qt
Vá até o diretório do seu arquivo "main.cpp"
Digite o comando: qmake -project
Digite o comando: qmake
Digite o comando: make

é nela que eu estou com dúvida
onde fica o prompt de comando do Qt, para que eu possa abri-lo?
e esses comandos
Digite o comando: qmake -project
Digite o comando: qmake
Digite o comando: make

onde devo digita-los?

eu criei o arquivo main.cpp pelo DEV-C++
e salvei em um diretório que contem outros arquivos(que é a pasta onde coloco todos os programas que crio)algum problema quanto a isso?

Nome: Danilo Domingos
2012-05-02 13:16:22, disse:

Olá Ana, não tem problema ter vários arquivos na pasta. Talvez seja interessante separar os programinhas por pasta, pois se o compilador criar algum arquivo extra, fica mais organizado.

O Prompt do Qt a que me refiro nessa página é um prompt normal como o DOS mas ele já deixa ajustado as variáveis de ambiente do windows automaticamente. Para acessar esse prompt basta procurar no Iniciar, sob a guia dos programas instalados com o pacote do Qt.

Observação: Na época que eu fiz estes tutoriais o pacote era bem menos organizado e completo do que é hoje. Acho que hoje você nem precisa mais ajustar as variáveis de ambiente manualmente. Vou buscar saber se esse procedimento acima descrito ainda se aplica. Depois venho aqui postar a resposta.

Obrigado Ana.
Nome: Jamine Cristine
2013-09-29 23:37:33, disse:

Meu nome é Jamine, vocês tem algum e-mail pra contato? Pois eu tenho um trabalho pra desenvolver em QT e precisava de auxilio.
Obrigada desde já.