Vou partir do princípio que já temos as nossas revisões de C++, Classes e o básico do Qt em dia (“Hello World!”), pois não vou dar grande ênfase ou explicação a esse tipo de detalhes, evitando desta forma correr o risco de não conseguir fazer passar a minha mensagem.
Na terminologia utilizada em QT um widget é um elemento visual que faz parte de uma interface com o utilizador.
Uma aplicação geralmente possui um menu principal a partir do qual podemos chamar vários “dialogs”, que são nada mais nada menos que formulários utilizados para interagir com o utilizador, solicitando-lhe os dados necessários ou apresentando resultados do processamento.
Cada “dialog” é construído utilizando um conjunto de “widgets” e estabelecendo ligações (SIGNALS/SLOTS) entre eles.
Geralmente só é possível garantir a funcionalidade do nosso “dialog” recorrendo a mecanismos de herança, ou seja, por “subclassing” da classe QDialog.
Convém ter presente que é possível construir uma aplicação sem recorrer ao Qt Designer, mas a sua utilização pode tornar mais rápida a tarefa de desenvolvimento de interfaces gráficas complexas.
Todo este artigo vai girar em torno de um pequeno formulário (dialog) que serve para introduzir a matrícula de um automóvel. Além dos botões para aceitar ou cancelar, será necessária uma área para digitarmos a identificação do veículo, que naturalmente obedece a regras muito específicas.
O resultado final será algo do tipo:
Convém dar uma vista de olhos sobre a teoria, ou seja, como estão organizadas as matrículas dos automóveis em Portugal, pois de outra forma não nos será possível entender a fase de validação dos dados.
Neste exemplo concreto temos um “dialog” designado “Matrícula”, que utiliza pelo menos quatro “widgets”, isto porque podem existir alguns que não são visíveis nesta fase. Estes correspondem a botões, elementos de texto e caixas de entrada de texto que podem observar na figura.
Quando terminarmos este exemplo vamos ter os seguintes ficheiros principais:
- main.cpp – Que nos irá permitir testar o nosso “dialog”;
- IdDoAutomovelDialog.ui – O ficheiro gerado pelo QtDesigner;
- IdDoAutomovelDialog.h – A definição de uma classe correspondente ao nosso “dialog”;
- IdDoAutomovelDialog.cpp – A implementação da classe;
Após a sequência “qmake -project > make automovel.pro > make” muitos outros ficheiros serão gerados, mas os que eu indiquei são os que devemos guardar para recordar :)
Já chega de conversa e vamos começar a construir o nosso pequeno projecto.
#1 Criar directoria para armazenar o projecto
- Crie a directoria “automovel” numa localização à sua escolha.
#2 Criar o “dialog” utilizando o Qt Designer
- Inicie o Qt Designer.
- Seleccione “templates/forms” > “Widget”.
- Criar os “child widgets” e posicioná-los no formulário, sem grandes preocupações quanto ao alinhamento.

- Definir as propriedades dos “widgets” recorrendo ao “property editor”. A tabela seguinte resume estas operações.
| Widget | Propriedade | Valor |
| Label | objectNametext | label
“&Matrícula :” |
| Line Edit | objectName | lineEdit |
| Push Button | objectNametext
enabled |
okButton“OK”
False (desmarcar) |
| Push Button | objectNametext | cancelButton“Cancel” |
| Horizontal Spacer | - | - |
| Form(background) | objectNamewindowTitle | IdDoAutomovelDialog“Matrícula” |
O nosso “Dialog” fica com este aspecto.

- Definir os Widgets amigos (Buddies)
- Edit > Edit Buddies
- Clicar em label e arrastar a seta vermelha até lineEdit
- Edit > Edit Widgets (para abandonar o modo “Edit Buddies”)
- Dispor os Widgets no formulário (layout).
- Seleccionar: label + lineEdit
- Form > Lay Out Horizontally
- Seleccionar: spacer + okButton + cancelButton
- Form > Lay Out Horizontally
- Seleccionar: Form (background)
- Form > Lay Out Vertically
- Form > Adjust Size

- Alterar a ordem das tabulações (tab order)
- Edit > Edit Tab Order

- Pré-Visualizar
- Form > Preview
- Guardar o “Dialog”
- File > Save As …
- Abrir a pasta do projecto (automovel)
- Guardar com o nome “IdDoAutomovelDialog.ui“
#3 Testar o nosso formulário (ainda sem vida)
Já é possível nesta fase testarmos o nosso formulário, embora os botões não funcionem e também não seja feito qualquer tipo de validação aos dados introduzidos pelo utilizador.
Para o efeito podemos fazer o seguinte.
- Abrir uma consola
- Entrar na directoria “automovel“ que contém o ficheiro “IdDoAutomovelDialog.ui“.
- Criar o ficheiro “main.cpp” com o seguinte código
#include <QApplication>
#include <QDialog>
#include "ui_IdDoAutomovelDialog.h"
int main(int argc, char *argv[]){
QApplication app(argc, argv);
Ui::IdDoAutomovelDialog ui;
QDialog *dialog = new QDialog;
ui.setupUi(dialog);
dialog->show();
return app.exec();
}
- Executar a sequencia de comandos (os ls servem para visualizar os ficheiros criados em cada passo)
$ ls
IdDoAutomovelDialog.ui main.cpp
$ qmake -project
$ ls
automovel.pro IdDoAutomovelDialog.ui main.cpp
$ qmake automovel.pro
$ ls
automovel.pro IdDoAutomovelDialog.ui main.cpp Makefile
$ make
/usr/bin/uic-qt4 IdDoAutomovelDialog.ui -o ui_IdDoAutomovelDialog.h
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -I. -o main.o main.cpp
g++ -o automovel main.o -L/usr/lib -lQtGui -lQtCore -lpthread
$ ls
automovel IdDoAutomovelDialog.ui main.o ui_IdDoAutomovelDialog.h
automovel.pro main.cpp Makefile
#4 Implementar as funcionalidade do formulário
Vamos agora tratar dos seguintes aspectos:
- Aceitar apenas matrículas válidas
- Activar o botão “OK” quando a matrícula for válida
- Definir as acções para os botões “Cancel” e “OK”
Uma das abordagens possíveis consiste em criar uma nova classe que herde as classes QDialog e Ui::IdDoAutomovelDialog.
Teremos que criar os ficheiro IdDoAutomovelDialog.h e IdDoAutomovelDialog.cpp que correspondem à nossa classe derivada, e que vai permitir implementar todas as funcionalidades pretendidas.
IdDoAutomovelDialog.h
#ifndef IDDOAUTOMOVELDIALOG_H
#define IDDOAUTOMOVELDIALOG_H
#include <QDialog>
#include "ui_IdDoAutomovelDialog.h"
class IdDoAutomovelDialog : public QDialog, Ui::IdDoAutomovelDialog{
Q_OBJECT
public:
IdDoAutomovelDialog(QWidget *parent = 0);
private slots:
void on_lineEdit_textChanged();
};
#endif
IdDoAutomovelDialog.cpp
#include <QtGui>
#include "IdDoAutomovelDialog.h"
IdDoAutomovelDialog::IdDoAutomovelDialog(QWidget *parent) : QDialog(parent){
setupUi(this);
//Validar a matrícula introduzida ( http://pt.wikipedia.org/wiki/Matr%C3%ADculas_autom%C3%B3veis_em_Portugal )
QStringList listaMatriculasValidas;
listaMatriculasValidas << "[A-Za-z]{2,2}[-][0-9]{2,2}[-][0-9]{2,2}";
listaMatriculasValidas << "[0-9]{2,2}[-][0-9]{2,2}[-][A-Za-z]{2,2}";
listaMatriculasValidas << "[0-9]{2,2}[-][A-Za-z]{2,2}[-][0-9]{2,2}";
QRegExp regExp(listaMatriculasValidas.join("|"));
lineEdit->setValidator(new QRegExpValidator(regExp, this));
//Definir acções
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
}
void IdDoAutomovelDialog::on_lineEdit_textChanged(){
okButton->setEnabled(lineEdit->hasAcceptableInput());
}
Vai ser necessário simplificar o código do nosso main.cpp, uma vez que a única classe que é necessário utilizar é a nossa, ou seja, a classe IdDoAutomovel.
main.cpp
#include <QApplication>
#include "IdDoAutomovelDialog.h"
int main(int argc, char *argv[]){
QApplication app(argc, argv);
IdDoAutomovelDialog *dialog = new IdDoAutomovelDialog;
dialog->show();
return app.exec();
}
#5 Testar o resultado
Vamos repetir o processo apresentado no #3.
- Abrir uma consola
- Entrar na directoria “automovel“ que contém agora so ficheiros “IdDoAutomovelDialog.h“, “IdDoAutomovelDialog.cpp“, “IdDoAutomovelDialog.ui” e “main.cpp” .
- Criar o ficheiro “main.cpp” com o seguinte código
- Executar a sequencia de comandos
$ ls IdDoAutomovelDialog.cpp IdDoAutomovelDialog.ui IdDoAutomovelDialog.h main.cpp $ qmake -project $ ls automovel.pro IdDoAutomovelDialog.h main.cpp IdDoAutomovelDialog.cpp IdDoAutomovelDialog.ui $ qmake automovel.pro $ ls automovel.pro IdDoAutomovelDialog.h main.cpp IdDoAutomovelDialog.cpp IdDoAutomovelDialog.ui Makefile torrao@debian:~/Desktop/automovel/v2/automovel$ make /usr/bin/uic-qt4 IdDoAutomovelDialog.ui -o ui_IdDoAutomovelDialog.h g++ -c -pipe -O2 -Wall -W -D_REENTRANT ... ... ... ... ... moc_IdDoAutomovelDialog.o -L/usr/lib -lQtGui -lQtCore -lpthread $ ls automovel IdDoAutomovelDialog.o Makefile automovel.pro IdDoAutomovelDialog.ui moc_IdDoAutomovelDialog.cpp<a href="http://gracianotorrao.wordpress.com/2009/01/14/qt-creator/" target="_blank"> IdDoAutomovelDialog.cpp main.cpp moc_IdDoAutomovelDialog.o IdDoAutomovelDialog.h main.o ui_IdDoAutomovelDialog.h<span style="color:#000000;"> <pre>
Conclusão
O código fonte fica disponibilizado neste link.
Agradeço o feedback daqueles que seguirem este pequeno tutorial.
Uma alternativa à utilização da linha de comandos poderá ser o Qt Creator ( ver artigo anterior ), tal como mostrado na imagem.

No próximo artigo vou apresentar uma forma de escrever o mesmo programa sem recorrer ao Qt Designer.
Boa sorte :)
Julho 7, 2009 ás 8:18 pm
Parabéns cara, ótimo tutorial!
Julho 7, 2009 ás 8:19 pm
Uma dúvida, ao trabalhar com slots e signals via qtcreator, ele não mostra o código que ele gerou (queria aprender visualizando o código gerado).
Julho 7, 2009 ás 8:33 pm
Seo Dialog se chamar myDialog então vias ter sempre os seguintes ficheiros (entre outros):
- mydialog.h
- mydialog.cpp
- mydialog.ui
Após a compilação este mydialog.ui é transformado pelo UIC( http://doc.trolltech.com/4.5/uic.html ) num ui_mywidget.h.
Este último contém a classe que é utilizada para gerar a inferface com o utilizador.
Caso tenha criado os SLOTS/SIGNALS no QtDesigner podes encontrar o código gerado neste ficheiro.
Eu prefiro nunca fazer isto dessa forma e trato dessa parte no construtor da classe, logo a seguir a …
ui->setupUi(this);
connect(ui->objecto, SIGNAL(clicked()), this, SLOT(exp1()));
Julho 7, 2009 ás 8:39 pm
Quando escrevi este post ainda fazia dessa forma … mas estamos sempre a mudar não é?
;)
Julho 7, 2009 ás 8:19 pm
Ex: utilizando o botão “Edit signal/slots (F4) para ao clicar em um botão ele “limpar um “lineedit”, é só clicar no botão e arrastar para o lineedit e
Julho 9, 2009 ás 10:52 pm
Cara, antes de ler sua resposta, achei essa classe e vi que ele gera o código nela, mesmo assim valeu mesmo! Gerar o código via qtcreator achei bem interessante, pois desta forma ganhamos tempo para trabalhar mais com o que é mais importante.
Julho 9, 2009 ás 10:54 pm
Completando: Estou me referindo a clicar os SLOTS/SIGNALS, via interface qtdesigner, pois assim temos mais tempo para lidar com as outras questões do programa.
Agosto 31, 2009 ás 8:43 pm
Olá Graciano!
Infelizmente seu exemplo não funcionou em minha máquina. Quando dou um make para testar o formulário (ainda sem vida), obtenho a seguinte resposta do console:
/usr/bin/uic idDoAutomovelDialog.ui -o ui_idDoAutomovelDialog.h
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/default -I. -I/usr/include/QtCore -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include/QtGui -I/usr/include -I. -I. -I. -o main.o main.cpp
main.cpp:2:19: error: Qdialog: Arquivo ou diretório não encontrado
main.cpp:4:36: error: ui_IdDoAutomovelDialog.h: Arquivo ou diretório não encontrado
main.cpp: In function ‘int main(int, char**)’:
main.cpp:9: error: ‘Ui’ has not been declared
main.cpp:9: error: expected `;’ before ‘ui’
main.cpp:10: error: invalid use of undefined type ‘struct QDialog’
/usr/include/QtGui/qwindowdefs.h:38: error: forward declaration of ‘struct QDialog’
main.cpp:11: error: ‘ui’ was not declared in this scope
main.cpp:12: error: invalid use of undefined type ‘struct QDialog’
/usr/include/QtGui/qwindowdefs.h:38: error: forward declaration of ‘struct QDialog’
make: ** [main.o] Erro 1
O que eu esqueci de configurar?
Setembro 1, 2009 ás 7:03 am
“main.cpp:2:19: error: Qdialog: Arquivo ou diretório não encontrado”
Verifica este “d” minúsculo no nome da classe em QDialog.
Setembro 1, 2009 ás 4:41 pm
Era isso! Não acredito que tenha sido essa besteira… E eu imaginando mil coisas! Bom, valeu cara!