Getting Started on the Commandline/pt
Iniciando o desenvolvimento com Qt
Bem vindo ao mundo Qt — o framework multiplataforma. Neste guia introdutório você irá aprender o básico de Qt implementado um bloco de notas simples. Após a leitura deste guia você deverá estar preparado para aprofundar-se no ambiente e na documentação da API, além de saber localizar toda a documentação que você precisa para as aplicações que estiver desenvolvendo.
Olá Notepad
Neste primeiro exemplo criaremos e mostraremos simplesmente uma caixa de texto em uma janela do desktop. É a aplicação gráfica mais simples possível.
Vamos caminhar pelo código linha por linha. Nas primeiras duas linhas nós incluimos os headers QApplication [doc.qt.nokia.com] e QTextEdit [doc.qt.nokia.com], que são as duas classes que usaremos neste exemplo. Todas as classes possuem um aquivo de header com seu nome.
A linha 6 cria um objeto QApplication [doc.qt.nokia.com]. Este objeto gerencia os recursos da aplicação e é necessário para rodar qualquer programa Qt que possua uma interface gráfica. O uso de argv e argc também é necessário porque o framework Qt aceita alguns argumentos da linha de comando.
Linha 8 cria um objeto QTextEdit [doc.qt.nokia.com]. Uma caixa de texto é um elemento visual em uma interface gráfica. Em Qt, estes elementos são chamados de widgets. Exemplo de outros widgets são as barras de rolagem (scroll bars), labels, e radio buttons. Um widget também pode ser um recipiente para outros widgets; Uma janela de diálogo, ou a janela principal, por exemplo.
A linha 9 mostra a caixa de texto dentro do seu próprio frame. Como widgets funcionam também como recipientes, é possível mostar um widget simples na sua própria janela. Widgets não são visíveis por padrão, portanto o método show() [doc.trolltech.com] deve ser chamado para fazer o widget visível.
A linha 11 faz com que a QApplication entre em seu loop de eventos. Quando uma aplicação Qt está rodando, os eventos são gerados e enviados para os widgets da aplicação. Exemplo de eventos são os clicks do mouse e entradas de teclado. Quando você digita algo dentro de uma caixa de texto, esta recebe os eventos de teclado e responde desenhando o texto digitado.
Para rodar a aplicação: Abra um terminal e entre no diretório onde está seu .cpp. Para compilar a aplicação execute os seguintes passos:
Isso deverá gerar um executável no diretório part1 (note que no windows você deve usar nmake ao invés de make. O executável também será gerado em part1/debug ou part1/release). qmake é a ferramenta Qt para construção do ambiente de compilação da sua aplicação, e depende de um arquivo de configuração (.pro) para funcionar. Este arquivo pode ser gerado com o argumento -project. Dado esse arquivo, qmake produz um Makefile que será utilizado para compilar o programa pra você. Futuramente veremos como construir nossos próprios arquivos .pro.
Aprenda mais
Sobre | Onde |
Widgets e geometria de janelas |
Janelas e Diálogos [doc.qt.nokia.com] |
Eventos e manipulação de eventos |
O Sistema de eventos [doc.qt.nokia.com] |
Adicionando um botão de saída
Em uma aplicação real você normalmente precisaria de mais de um único widget. Então introduziremos um QPushButton abaixo da caixa de edição de texto. O botão irá fechar o bloco de notas quando pressionado (ex.: quando houver um click com o mouse).
Editor de texto com botão para fechar
Vamos analizar o código linha a linha:
A linha 1 inclui QtGui [doc.qt.nokia.com], que contém todas as classes de elementos gráficos Qt.
A Linha 10 usa o mecanismo de sinais e slots (signals & slots) para fechar a aplicação quando o botão Sair for pressionado. Um slot é um método que pode ser invocado em tempo de execução usando seu nome (como uma string literal). Um sinal é uma função que, quando chamada, irá invocar os slots registrados nela ela; Nós chamamos isso de “conectar o slot no sinal e emitir o sinal”.
quit() [doc.qt.nokia.com] é o slot de QApplication que finaliza a aplicação.clicked() [doc.qt.nokia.com] é o sinal emitido por QPushButton [doc.qt.nokia.com] quando este for pressionado. O método estático QObject::connect() [doc.qt.nokia.com] é responsável por conectar o slot ao sinal. SIGNAL e SLOT são duas macros que retornam as assinaturas dos sinais e slots, respectivamente. Nós também precisamos passar os ponteiros para os objetos que devem receber e enviar o sinal.
A linha 12 cria um QVBoxLayout [doc.qt.nokia.com]. Como mencionado, widgets podem conter outros widgets. É possível definir os limites (posição e tamanho) dos widgets filhos diretamente, mas é mais fácil usar um layout. Um layout gerencia os limites dos widgets filhos. QVBoxLayout [doc.qt.nokia.com], por exemplo, posiciona os filhos verticalmente.
As linhas 13 e 14 adicionam a caixa de texto e o botão ao layout. Na linha 17 definimos o layout em um widget.
Aprenda Mais
Sobre | Onde |
Sinais e slots |
Slots e Sinais [doc.qt.nokia.com] |
Layouts |
Gerenciamento de Layout [doc.qt.nokia.com], widgets e Layouts [doc.qt.nokia.com], exemplos de layouts [doc.qt.nokia.com] |
Os widgets do Qt |
Galeria de Widgets [doc.qt.nokia.com], exemplos [doc.qt.nokia.com] |
Herdando de QWidget
Quando o usuário desejar sair da aplicação, pode ser necessário mostrar um diálogo perguntando se ele realmente quer sair. Neste exemplo, nós especializamos QWidget [doc.qt.nokia.com] e adicionamos um slot que foi conectado ao botão Sair.
O código:
A macro Q_OBJECT deve ser colocada no início da definição da classe, e essa ser uma especialização de QObject (QWidget herda de QObject). O QObject adiciona algumas habilidades a uma classe C++ padrão. Notavelmente, o nome da classe e dos slots podem ser requisitados em tempo de execução. Também é possível consultar um tipo de parâmetro do slot e invocá-lo.
A linha 9 declara o slot quit(). Isso é fácil usando a macro slots. O slot quit() agora pode ser conectado aos sinais que possuem uma assinatura equivalente (no caso, qualquer sinal que não receba parâmetros)
Ao invés de iniciarmos a interface gráfica e conectarmos o slot dentro da função main(), agora usamos o contrutor do Notepad.
Como podemos ver na definição da classe, usamos ponteiros para os nossos QObjects [doc.qt.nokia.com] (textEdit e quitButton). Como regra: sempre devemos alocar os QObjects [doc.qt.nokia.com] na heap e nunca copiá-los.
Usamos a função tr() [doc.qt.nokia.com] em torno de nossas strings visíveis ao usuário. Esta função é necessária quando queremos distribuir nossa aplicação em mais de um idioma (por exemplo: inglês e alemão). Não vamos entrar em detalhes aqui, mas você pode seguir o link Qt Linguist na tabela Aprenda Mais.
Aprenda Mais
Sobre | Onde |
tr() e i18n |
Manual do Qt Linguist [doc.qt.nokia.com], Escrevendo código fonte para tradução [doc.qt.nokia.com], Example Olá tr() [doc.qt.nokia.com], Internationalização com Qt [doc.qt.nokia.com] |
QObjects [doc.qt.nokia.com] e o modelo do Qt Object (Isto é essencial para entender Qt) |
Modelo de Objeto [doc.qt.nokia.com] |
qmake e o systema de construção do Qt |
Manual qmake [doc.qt.nokia.com] |
Criando um arquivo .pro
Para este exemplo escreveremos nosso próprio arquivo .pro ao invés de usarmos a opção -project do qmake.
Para compilar o programa siga os seguintes passos:
Usando o QMainWindow
Várias aplicações serão beneficiadas ao usar a QMainWindow [doc.qt.nokia.com], que possui seu próprio layout no qual pode-se adicionar uma barra de menu, dock widgets, barra de ferramentas e barra de status. QMainWindow [doc.qt.nokia.com] possui também uma área central que pode ser ocupada por qualquer tipo de widget. No nosso caso, colocaremos lá nossa caixa de edição de texto.
Vamos à nova definição da classe Notepad.
Incluímos mais dois slots que podem salvar e abrir um documento. Iremos implementá-los na próxima sessão.
Em uma janela principal (main window) o mesmo slot costuma ser invocado por vários widgets. Exemplos disso são os ítens de menu e os botões em uma barra de ferramentas. Para facilitar, Qt provê o QAction, que pode ser passado para vários widgets e ser conectado aos slots. Por exemplo, QMenu e QToolBar podem criar ítens de menu através dos mesmos QActions. Iremos ver como isso funciona mais a frente.
Como antes, usamos o costrutor do Notepad para iniciar a interface gráfica.
QActions [doc.qt.nokia.com] são criadas com o texto que deve aparecer nos widgets em que forem adicionadas (no nosso caso, o menu). Se nós também quisermos adicioná-los à barra de ferramentas poderemos utilizar ícones [doc.qt.nokia.com] nos QActions.
Quando um ítem do menu for pressionado, o ítem irá ativar a ação e o respectivo slot será invocado.
Aprenda Mais
Sobre | Onde |
Main windows e suas classes |
Aplicação comMain Window [doc.qt.nokia.com], Exemplos da Main Window [doc.qt.nokia.com] |
Aplicações MDI |
QMdiArea [doc.qt.nokia.com], Exemplo MDI [doc.qt.nokia.com] |
Salvando e Abrindo
Neste exemplo iremos implementar a funcionalidade de abrir e salvar, implementando os slots open() e save() que foram adicionados no exemplo anterior.
Vamos começar com o slot open():
O primeiro passo é perguntar ao usuário pelo nome do arquivo que deseja abrir. Qt vem com o QFileDialog [doc.qt.nokia.com], que é um diálogo onde o usuário pode selecionar um arquivo. A imagem acima mostra o diálogo no Kubuntu. O método estático getOpenFileName() [doc.qt.nokia.com] mostra um diálogo de arquivo modal, e não retorna até que o usuário seleciona um arquivo. Ele retorna o caminho para o arquivo selecionado, ou uma string vazia caso o usuário cancele o diálogo.
Se nós tivermos um nome de arquivo então tentaremos abrí-lo uando o método open() [doc.qt.nokia.com], que retorna True se o arquivo pode ser aberto. Não iremos tratar gerenciamento de erro neste artigo, para isso você pode seguir os links da seção Aprenda Mais. Se o arquivo não pode ser aberto, usaremos uma QMessageBox [doc.qt.nokia.com] para mostar um diálogo com uma mensagem de erro (veja a descrição da classe QMessageBox [doc.qt.nokia.com] para maiores detalhes).
Ler os dados do arquivo é trivial usando o método readAll() [doc.qt.nokia.com] que retorna todos os dados do arquivo em um QByteArray [doc.qt.nokia.com]. constData() [doc.qt.nokia.com] retorna todos os dados em um array como um const char*, que pode ser usado para gerar uma QString [doc.qt.nokia.com]. O conteúdo pode ser mostrado na caixa de edição de texto. Então o método close() [doc.qt.nokia.com]é invocado para retornar o descritor de arquivo para o sistema operacional.
Agora, vejamos o método save():
Quando escrevemos o conteúdo da caixa de edição de texto no arquivo usamos a classe QTextStream [doc.qt.nokia.com] que recebe um objeto tipo QFile. O stream de text pode escrever QStrings diretamente no arquivo enquanto QFile [doc.qt.nokia.com] somente aceita dado puro (char *) com o método write() [doc.qt.nokia.com] do QIODevice [doc.qt.nokia.com].
Aprenda Mais
Sobre | Onde |
Arquivos e dispositivos de entrada e saída |