Criado em 28/09/2010 às 16:40
Nesta página, falarei um pouquinho sobre os tipos de "janelas" que encontramos no Qt. Também falarei sobre "separação" do seu código para uma melhor organização. Se você abrir o Qt Creator ou o Qt Designer você
terá que escolher logo de cara, qual é o template (modelo) que você usará. Tente você mesmo, você verá três opções basicamente:
Eu diria que no nível de complexidade, nós poderíamos organizá-los do mais simples para o mais complexo da seguinte forma: Widget, Dialog, MainWindow. Nada mais justo que começarmos pelo mais simples.
Você já conheçeu as Widgets das páginas anteriores, QLabel, QPushButton, QLineEdit. Você viu até um caso em que um botão estava dentro de uma label. Nesse caso, será que não poderíamos pegar a label, e seu filho botão,
e chamá-los de uma unica widget? Tipo uma nova classe(widget) chamada QLabotao! Sim, nós poderíamos, e desse modo podemos criar nossas proprias widgets, compostas por outras widgets. Isso será exemplificado mais adiante.
E o Dialog? O Dialog é uma janela que tem como objetivo pegar/receber informações de escolha do usuário. Exemplos de dialogs: Janela de tipo de fonte a ser usada num editor de texto, janela de abertura de arquivo, janela de salvamento de arquivo, janela de cores. Geralmente
dialogs servem como auxílio à tarefas de uma janela principal e tem dois botões, o aceitar e o cancelar.
Enfim, MainWindows são janelas principais do programa. É a janela que manda no programa, ela chama dialogs diversas vezes e quando é fechada o programa acaba. Ela tem mais algumas propriedades como statusbar, toolbars, docked windows entre outras..
Para criarmos novas Widgets, novos Dialogs ou novos MainWindows nós vamos, inicialmente, criar classes que herdam daquelas. Então é importante saber que herdaremos nossas novas classes das já existentes:
- QObject-QWidget
- QObject-QWidget-QDialog
- QObject-QWidget-QMainWindow
Veja que o proprio caminho de heranças sugere que as classes mais diferenciadas QDialog e QMainWindow sejam mais complicadinhas que a QWidget.
Figura Esquemática 1. Classes do Qt que já vimos até agora (Heranças).
Criando Nossa Widget
Você perceberá que ao fazer nossas próprias coisas (widgets, dialogs ou mainwindows), é sempre bom dividir nossa fonte em arquivos header e arquivos source, com isso
o código fica mais organizado e entendivel. Vejamos então, um exemplo de uma Widget criada por nós, seguido do comentário do código. Mas antes, o resultado:
Código 6. Código source principal(main.cpp).
#include <QApplication> //QObject-QCoreApplication-QApplication
#include "nossawidget.h" //"QObject-QWidget-"nossawidget
int main(int argc, char * argv[])
{
QApplication app(argc, argv);
NossaWidget janela;
janela.show();
return app.exec();
}
Tudo começa na função main (Código 6), onde criamos a nossa classe do tipo NossaWidget, o que acontece nesse momento? a construtora da nossa classe é chamada! Construtora essa que tem seu protótipo dentro
do header "nossawidget.h"(Código 7) e sua implementação dentro do arquivo source "nossawidget.cpp"(Código 8, implementados abaixo)
Código 7. Header da nossa classe(nossawidget.h).
#ifndef NOSSAWIDGET_H
#define NOSSAWIDGET_H
#include <QWidget> //QObject-QWidget
class NossaWidget : public QWidget
{
public:
NossaWidget(QWidget *parent = 0); //protótipo da função construtora
};
#endif
Perceba que nosso header está "protegido contra duplicação" nas diretivas #ifndef/#define/#endif (senão estiver definida, defina, fim do if), precisamos incluir a classe QWidget
porque nossa classe vai vir dela. O parâmetro da nossa construtora é inicializado com o valor zero porque, como vamos chamá-la do main, podemos criá-la sem parâmetros e não será filha de ninguém.
Código 8. Source da nossa classe(nossawidget.cpp).
#include <QLabel> //QObject-QWidget-QFrame-QLabel
#include <QPushButton> //QObject-QWidget-QAbstractButton-QPushButton
#include <QVBoxLayout> //QObject-QLayout-QBoxLayout-QVBoxLayout
#include <QHBoxLayout> //QObject-QLayout-QBoxLayout-QHBoxLayout
#include <QLineEdit> //QObject-QWidget-QLineEdit
#include "nossawidget.h" //Para ele saber de quem você está falando
NossaWidget::NossaWidget(QWidget *parent) : QWidget (parent)
{
QLabel *label = new QLabel("Insira o seu Nome:");
QPushButton *botao = new QPushButton("Ok");
QLineEdit *linha = new QLineEdit;
QVBoxLayout *layoutV = new QVBoxLayout(this);
QHBoxLayout *layoutH = new QHBoxLayout();
layoutH->addWidget(label);
layoutH->addWidget(linha);
layoutV->addLayout(layoutH);
layoutV->addWidget(botao);
QObject::connect(botao, SIGNAL(clicked()), this, SLOT(close()));
}
No arquivo source da nossa widget, 3 widgets e 2 layouts são criados e o botão é conectado. Você já é capaz de entender a suruba dos layouts ali sozinho(a)
mas, para judar, dê uma olhada na figura abaixo:
A linhas da figura acima representam:variável "janela" do main.cpp, Layout Vertical da nossa classe aplicado a quem o chamou (this = variável janela, do main.cpp) e Layout Horizontal da nossa clase. O "this" ali ta dizendo: O layout vertical vai ser aplicado a quem chamou a construtora (variável janela, no main), Quando for clicado,
o botão vai dar um "close()" em quem o chamou (variável janela, do main.cpp).
Criando Nosso Dialog
Para fazer um dialog diferente dos padrões (como o de abertura de arquivo, ou até algumas mensagens de notificação), o processo é o mesmo mas existe uma diferença sutil nas conexões dos botões de um Dialog. Acompanhe o
código do mesmo exemplo da Widget para um Dialog:
Código 9. Arquivo source principal(main.cpp).
#include <QApplication> //QObject-QCoreApplication-QApplication
#include "nossodialog.h" //"QObject-QWidget-QDialog-"nossodialog
int main(int argc, char * argv[])
{
QApplication app(argc, argv);
NossoDialog dialog;
dialog.show();
return app.exec();
}
Código 10. Header do nosso dialog(nossodialog.h).
#ifndef NOSSODIALOG_H
#define NOSSODIALOG_H
#include <QDialog> //QObject-QWidget-QDialog
class NossoDialog : public QDialog
{
public:
NossoDialog(QWidget *parent = 0); //protótipo da função construtora
};
#endif
Já aproveitando o balanço do busão vou mostrar, na implementação do source code do nosso dialog, o uso do layout grid (QGridLayout). Você já viu que o QHBoxLayout organiza as widgets horizontalmente e
que a QVBoxLayout organiza as widgets verticalmente. O layout em grid considera um esquema de linhas e colunas, como numa matriz, acompanhe abaixo:
Código 11. Arquivo source do nosso dialog(nossodialog.cpp).
#include <QLabel> //QObject-QWidget-QFrame-QLabel
#include <QPushButton> //QObject-QWidget-QAbstractButton-QPushButton
#include <QGridLayout> //QObject-QLayout-QGridLayout
#include <QLineEdit> //QObject-QWidget-QLineEdit
#include "nossodialog.h" //Para ele saber de quem você está falando
NossoDialog::NossoDialog(QWidget *parent) : QDialog (parent)
{
QLabel *label = new QLabel("Insira o seu Nome:");
QPushButton *botaoOk = new QPushButton("Ok");
QPushButton *botaoCan = new QPushButton("Cancelar");
QLineEdit *linha = new QLineEdit;
QGridLayout *layoutGrid = new QGridLayout(this);
layoutGrid->addWidget(label, 0, 0); //Linha 0, Coluna 0
layoutGrid->addWidget(linha, 0, 1); //Linha 0, Coluna 1
layoutGrid->addWidget(botaoOk, 1, 0); //Linha 1, Coluna 0
layoutGrid->addWidget(botaoCan, 1, 1); //Linha 1, Coluna 1
QObject::connect(botaoOk, SIGNAL(clicked()), this, SLOT(accept()));
QObject::connect(botaoCan, SIGNAL(clicked()), this, SLOT(reject()));
}
É importantíssimo frisar o modo com que um dialog é encerrado: Clicando no botão OK, ou CANCELAR. Enviando a mensagem de volta (para sua MainWindow) ACCEPTED ou REJECTED. Abaixo está uma representação do layout grid:
O uso dos layouts foi para simples demonstração, você pode usar o Layour que quiser. A criação de MainWindows vai ficar para páginas posteriores porque envolve outros conceitos. Calma que jájá faremos exemplos graficamente!, é importante saber oque acontece behind the scenes.
Por hoje é só pessoal!
Exercicio 2
Crie uma classe derivada de uma QLineEdit ("MeuLineEdit"). Desenvolva uma função construtora para sua classe de forma que ela seja inicializada com um texto inicial, sem usar a construtora própria para isso ( MeuLineEdit linha("não vale")). Que membro você escolheu para fazer essa alteração? (Use o Qt Assistant)
|