Getting Started on the Commandline/pt: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Add "cleanup" tag)
(Convert ExpressionEngine links)
Line 27: Line 27:
</code>
</code>


Vamos caminhar pelo código linha por linha. Nas primeiras duas linhas nós incluimos os headers "QApplication":http://doc.qt.nokia.com/4.7/qapplication.html e "QTextEdit":http://doc.qt.nokia.com/4.7/qtextedit.html, que são as duas classes que usaremos neste exemplo. Todas as classes possuem um aquivo de header com seu nome.
Vamos caminhar pelo código linha por linha. Nas primeiras duas linhas nós incluimos os headers [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] e [http://doc.qt.nokia.com/4.7/qtextedit.html QTextEdit], 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":http://doc.qt.nokia.com/4.7/qapplication.htm. 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.
A linha 6 cria um objeto [http://doc.qt.nokia.com/4.7/qapplication.htm QApplication]. 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":http://doc.qt.nokia.com/4.7/qtextedit.html. 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.
Linha 8 cria um objeto [http://doc.qt.nokia.com/4.7/qtextedit.html QTextEdit]. 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()":http://doc.trolltech.com/4.7/qwidget.html#show deve ser chamado para fazer o widget visível.
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 [http://doc.trolltech.com/4.7/qwidget.html#show show()] 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.
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.
Line 48: Line 48:


|'''Sobre'''|'''Onde'''|
|'''Sobre'''|'''Onde'''|
|Widgets e geometria de janelas|"Janelas e Diálogos":http://doc.qt.nokia.com/4.7/application-windows.html|
|Widgets e geometria de janelas|[http://doc.qt.nokia.com/4.7/application-windows.html| Janelas e Diálogos]
|Eventos e manipulação de eventos|"O Sistema de eventos":http://doc.qt.nokia.com/4.7/eventsandfilters.html|
|Eventos e manipulação de eventos|[http://doc.qt.nokia.com/4.7/eventsandfilters.html| O Sistema de eventos]


h2. Adicionando um botão de saída
h2. Adicionando um botão de saída
Line 82: Line 82:
}</code>
}</code>


A linha 1 inclui "QtGui":http://doc.qt.nokia.com/4.7/qtgui.html, que contém todas as classes de elementos gráficos Qt.
A linha 1 inclui [http://doc.qt.nokia.com/4.7/qtgui.html QtGui], que contém todas as classes de elementos gráficos Qt.


A Linha 10 usa o mecanismo de sinais e slots (''signals &amp; 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".
A Linha 10 usa o mecanismo de sinais e slots (''signals &amp; 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()":http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit é o ''slot'' de QApplication que finaliza a aplicação." clicked()":http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked é o sinal emitido por "QPushButton":http://doc.qt.nokia.com/4.7/qpushbutton.html quando este for pressionado. O método estático "QObject::connect() ":http://doc.qt.nokia.com/4.7/qobject.html#connect é 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.
[http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit quit()] é o ''slot'' de QApplication que finaliza a aplicação.[http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked clicked()] é o sinal emitido por [http://doc.qt.nokia.com/4.7/qpushbutton.html QPushButton] quando este for pressionado. O método estático [http://doc.qt.nokia.com/4.7/qobject.html#connect QObject::connect() ] é 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":http://doc.qt.nokia.com/4.7/qvboxlayout.html. 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":http://doc.qt.nokia.com/4.7/qvboxlayout.html, por exemplo, posiciona os filhos verticalmente.
A linha 12 cria um [http://doc.qt.nokia.com/4.7/qvboxlayout.html QVBoxLayout]. 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. [http://doc.qt.nokia.com/4.7/qvboxlayout.html QVBoxLayout], 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.
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.
Line 95: Line 95:


|'''Sobre'''|'''Onde'''|
|'''Sobre'''|'''Onde'''|
|Sinais e slots|"Slots e Sinais":http://doc.qt.nokia.com/4.7/signalsandslots.html|
|Sinais e slots|[http://doc.qt.nokia.com/4.7/signalsandslots.html| Slots e Sinais]
|Layouts|"Gerenciamento de Layout":http://doc.qt.nokia.com/4.7/layout.html, "widgets e Layouts":http://doc.qt.nokia.com/4.7/widgets-and-layouts.html, "exemplos de layouts":http://doc.qt.nokia.com/4.7/examples-layouts.html|
|Layouts|[http://doc.qt.nokia.com/4.7/layout.html Gerenciamento de Layout], [http://doc.qt.nokia.com/4.7/widgets-and-layouts.html widgets e Layouts], [http://doc.qt.nokia.com/4.7/examples-layouts.html| exemplos de layouts]
|Os widgets do Qt|"Galeria de Widgets":http://doc.qt.nokia.com/4.7/gallery.html, "exemplos":http://doc.qt.nokia.com/4.7/examples-widgets.html|
|Os widgets do Qt|[http://doc.qt.nokia.com/4.7/gallery.html Galeria de Widgets], [http://doc.qt.nokia.com/4.7/examples-widgets.html| exemplos]


h2. Herdando de QWidget
h2. 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":http://doc.qt.nokia.com/4.7/qwidget.html e adicionamos um slot que foi conectado ao botão '''Sair'''.
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 [http://doc.qt.nokia.com/4.7/qwidget.html QWidget] e adicionamos um slot que foi conectado ao botão '''Sair'''.


p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs3.png|Herdando de QWidget]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs3.png|Herdando de QWidget]]
Line 144: Line 144:
</code>
</code>


Como podemos ver na definição da classe, usamos ponteiros para os nossos "QObjects":http://doc.qt.nokia.com/4.7/qobject.html (textEdit e quitButton). Como regra: sempre devemos alocar os "QObjects":http://doc.qt.nokia.com/4.7/qobject.html na ''heap'' e nunca copiá-los.
Como podemos ver na definição da classe, usamos ponteiros para os nossos [http://doc.qt.nokia.com/4.7/qobject.html QObjects] (textEdit e quitButton). Como regra: sempre devemos alocar os [http://doc.qt.nokia.com/4.7/qobject.html QObjects] na ''heap'' e nunca copiá-los.


Usamos a função "tr()":http://doc.qt.nokia.com/4.7/qobject.html#tr 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'''.
Usamos a função [http://doc.qt.nokia.com/4.7/qobject.html#tr tr()] 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 ===
=== Aprenda Mais ===
Line 155: Line 155:
|-
|-
|tr() e i18n
|tr() e i18n
|"Manual do Qt Linguist":http://doc.qt.nokia.com/4.7/linguist-manual.html, "Escrevendo código fonte para tradução":http://doc.qt.nokia.com/4.7/i18n-source-translation.html, "Example Olá tr()":http://doc.qt.nokia.com/4.7/linguist-hellotr.html, "Internationalização com Qt":http://doc.qt.nokia.com/4.7/internationalization.html
|[http://doc.qt.nokia.com/4.7/linguist-manual.html Manual do Qt Linguist], [http://doc.qt.nokia.com/4.7/i18n-source-translation.html Escrevendo código fonte para tradução], [http://doc.qt.nokia.com/4.7/linguist-hellotr.html Example Olá tr()], [http://doc.qt.nokia.com/4.7/internationalization.html Internationalização com Qt]
|-
|-
|"QObjects":http://doc.qt.nokia.com/4.7/qtwebkit-bridge.html#qobjects e o modelo do Qt Object (Isto é essencial para entender Qt)
|[http://doc.qt.nokia.com/4.7/qtwebkit-bridge.html#qobjects QObjects] e o modelo do Qt Object (Isto é essencial para entender Qt)
|"Modelo de Objeto":http://doc.qt.nokia.com/4.7/object.html
|[http://doc.qt.nokia.com/4.7/object.html Modelo de Objeto]
|-
|-
|qmake e o systema de construção do Qt
|qmake e o systema de construção do Qt
|"Manual qmake":http://doc.qt.nokia.com/4.7/qmake-manual.html
|[http://doc.qt.nokia.com/4.7/qmake-manual.html Manual qmake]
|}
|}


Line 179: Line 179:
h2. Usando o QMainWindow
h2. Usando o QMainWindow


Várias aplicações serão beneficiadas ao usar a "QMainWindow":http://doc.qt.nokia.com/4.7/qmainwindow.html, 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":http://doc.qt.nokia.com/4.7/qmainwindow.html 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.
Várias aplicações serão beneficiadas ao usar a [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow], que possui seu próprio layout no qual pode-se adicionar uma barra de menu, ''dock widgets'', barra de ferramentas e barra de status. [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow] 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.


p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs4.png|Usando QMainWindow]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs4.png|Usando QMainWindow]]
Line 238: Line 238:
}</code>
}</code>


"QActions":http://doc.qt.nokia.com/4.7/qaction.html 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":http://doc.qt.nokia.com/4.7/qicon.html nos QActions.
[http://doc.qt.nokia.com/4.7/qaction.html QActions] 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 [http://doc.qt.nokia.com/4.7/qicon.html ícones] nos QActions.


Quando um ítem do menu for pressionado, o ítem irá ativar a ação e o respectivo slot será invocado.
Quando um ítem do menu for pressionado, o ítem irá ativar a ação e o respectivo slot será invocado.
Line 249: Line 249:
|-
|-
|Main windows e suas classes
|Main windows e suas classes
|"Aplicação comMain Window":http://doc.qt.nokia.com/4.7/mainwindow.html, "Exemplos da Main Window":http://doc.qt.nokia.com/4.7/examples-mainwindow.html
|[http://doc.qt.nokia.com/4.7/mainwindow.html Aplicação comMain Window], [http://doc.qt.nokia.com/4.7/examples-mainwindow.html Exemplos da Main Window]
|-
|-
|Aplicações MDI
|Aplicações MDI
|"QMdiArea":http://doc.qt.nokia.com/4.7/qmdiarea.html, "Exemplo MDI":http://doc.qt.nokia.com/4.7/mainwindows-mdi.html
|[http://doc.qt.nokia.com/4.7/qmdiarea.html QMdiArea], [http://doc.qt.nokia.com/4.7/mainwindows-mdi.html Exemplo MDI]
|}
|}


Line 278: Line 278:
}</code>
}</code>


O primeiro passo é perguntar ao usuário pelo nome do arquivo que deseja abrir. Qt vem com o "QFileDialog":http://doc.qt.nokia.com/4.7/qfiledialog.html, 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()":http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName 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.
O primeiro passo é perguntar ao usuário pelo nome do arquivo que deseja abrir. Qt vem com o [http://doc.qt.nokia.com/4.7/qfiledialog.html QFileDialog], 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 [http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName getOpenFileName()] 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()":http://doc.qt.nokia.com/4.7/qiodevice.html#open, 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":http://doc.qt.nokia.com/4.7/qmessagebox.html para mostar um diálogo com uma mensagem de erro (veja a descrição da classe "QMessageBox":http://doc.qt.nokia.com/4.7/qmessagebox.html para maiores detalhes).
Se nós tivermos um nome de arquivo então tentaremos abrí-lo uando o método [http://doc.qt.nokia.com/4.7/qiodevice.html#open open()], 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 [http://doc.qt.nokia.com/4.7/qmessagebox.html QMessageBox] para mostar um diálogo com uma mensagem de erro (veja a descrição da classe [http://doc.qt.nokia.com/4.7/qmessagebox.html QMessageBox] para maiores detalhes).


Ler os dados do arquivo é trivial usando o método "readAll()":http://doc.qt.nokia.com/4.7/qiodevice.html#readAll que retorna todos os dados do arquivo em um "QByteArray":http://doc.qt.nokia.com/4.7/qbytearray.html. "constData()":http://doc.qt.nokia.com/4.7/qbytearray.html#constData retorna todos os dados em um array como um const char''', que pode ser usado para gerar uma "QString":http://doc.qt.nokia.com/4.7/qstring.html. O conteúdo pode ser mostrado na caixa de edição de texto. Então o método "close() ":http://doc.qt.nokia.com/4.7/qiodevice.html#closeé invocado para retornar o descritor de arquivo para o sistema operacional.
Ler os dados do arquivo é trivial usando o método [http://doc.qt.nokia.com/4.7/qiodevice.html#readAll readAll()] que retorna todos os dados do arquivo em um [http://doc.qt.nokia.com/4.7/qbytearray.html QByteArray]. [http://doc.qt.nokia.com/4.7/qbytearray.html#constData constData()] retorna todos os dados em um array como um const char''', que pode ser usado para gerar uma [http://doc.qt.nokia.com/4.7/qstring.html QString]. O conteúdo pode ser mostrado na caixa de edição de texto. Então o método [http://doc.qt.nokia.com/4.7/qiodevice.html#closeé close() ] invocado para retornar o descritor de arquivo para o sistema operacional.


Agora, vejamos o método save():
Agora, vejamos o método save():
Line 301: Line 301:
}</code>
}</code>


Quando escrevemos o conteúdo da caixa de edição de texto no arquivo usamos a classe "QTextStream":http://doc.qt.nokia.com/4.7/qtextstream.html que recebe um objeto tipo QFile. O stream de text pode escrever QStrings diretamente no arquivo enquanto "QFile":http://doc.qt.nokia.com/4.7/qfile.html somente aceita dado puro (char''') com o método "write()":http://doc.qt.nokia.com/4.7/qiodevice.html#write do "QIODevice":http://doc.qt.nokia.com/4.7/qiodevice.html.
Quando escrevemos o conteúdo da caixa de edição de texto no arquivo usamos a classe [http://doc.qt.nokia.com/4.7/qtextstream.html QTextStream] que recebe um objeto tipo QFile. O stream de text pode escrever QStrings diretamente no arquivo enquanto [http://doc.qt.nokia.com/4.7/qfile.html QFile] somente aceita dado puro (char''') com o método [http://doc.qt.nokia.com/4.7/qiodevice.html#write write()] do [http://doc.qt.nokia.com/4.7/qiodevice.html QIODevice].


=== Aprenda Mais ===
=== Aprenda Mais ===
Line 310: Line 310:
|-
|-
|Arquivos e dispositivos de entrada e saída
|Arquivos e dispositivos de entrada e saída
|"QFile":http://doc.qt.nokia.com/4.7/qfile.html, "QIODevice":http://doc.qt.nokia.com/4.7/qiodevice.html
|[http://doc.qt.nokia.com/4.7/qfile.html QFile], [http://doc.qt.nokia.com/4.7/qiodevice.html QIODevice]
|}
|}

Revision as of 08:25, 4 March 2015

This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

[toc align_right="yes" depth="4"]

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.

p=. http://doc.qt.nokia.com/4.7/images/gs1.png

#include <QApplication>
#include <QTextEdit>

int main(int argv, char **args)
{
 QApplication app(argv, args);

QTextEdit textEdit;
 textEdit.show();
 return app.exec();
}

Vamos caminhar pelo código linha por linha. Nas primeiras duas linhas nós incluimos os headers QApplication e QTextEdit, 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. 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. 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() 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:

qmake -project
qmake
make

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.

h3. Aprenda mais

|Sobre|Onde| |Widgets e geometria de janelas|Janelas e Diálogos |Eventos e manipulação de eventos|O Sistema de eventos

h2. 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).

p=. Editor de texto com botão para fechar

Vamos analizar o código linha a linha:

#include <QtGui>

int main(int argv, char **args)
{
 QApplication app(argv, args);

 QTextEdit textEdit;
 QPushButton quitButton("Sair");

 QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));

 QVBoxLayout layout;
 layout.addWidget(&amp;textEdit);
 layout.addWidget(&amp;quitButton);

 QWidget window;
 window.setLayout(&amp;layout);

 window.show();

 return app.exec();
}

A linha 1 inclui QtGui, 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() é o slot de QApplication que finaliza a aplicação.clicked() é o sinal emitido por QPushButton quando este for pressionado. O método estático QObject::connect() é 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. 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, 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.

h3. Aprenda Mais

|Sobre|Onde| |Sinais e slots|Slots e Sinais |Layouts|Gerenciamento de Layout, widgets e Layouts, exemplos de layouts |Os widgets do Qt|Galeria de Widgets, exemplos

h2. 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 e adicionamos um slot que foi conectado ao botão Sair.

p=. Herdando de QWidget

O código:

class Notepad : public QWidget
{
 Q_OBJECT

public:
 Notepad();

private slots:
 void quit();

private:
 QTextEdit *textEdit;
 QPushButton *quitButton;
};

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.

Notepad::Notepad()
{
 textEdit = new QTextEdit;
 quitButton = new QPushButton(tr("Quit"));

 connect(quitButton, SIGNAL (clicked()), this, SLOT (quit()));

 QVBoxLayout *layout = new QVBoxLayout;
 layout->addWidget(textEdit);
 layout->addWidget(quitButton);

setLayout(layout);

setWindowTitle(tr("Notepad"));
}

Como podemos ver na definição da classe, usamos ponteiros para os nossos QObjects (textEdit e quitButton). Como regra: sempre devemos alocar os QObjects na heap e nunca copiá-los.

Usamos a função tr() 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, Escrevendo código fonte para tradução, Example Olá tr(), Internationalização com Qt
QObjects e o modelo do Qt Object (Isto é essencial para entender Qt) Modelo de Objeto
qmake e o systema de construção do Qt Manual qmake

Criando um arquivo .pro

Para este exemplo escreveremos nosso próprio arquivo .pro ao invés de usarmos a opção -project do qmake.

HEADERS = notepad.h
SOURCES = notepad.cpp main.cpp

Para compilar o programa siga os seguintes passos:

qmake
make

h2. Usando o QMainWindow

Várias aplicações serão beneficiadas ao usar a QMainWindow, 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 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.

p=. Usando QMainWindow

Vamos à nova definição da classe Notepad.

#include <QtGui>

class Notepad : public QMainWindow
{
 Q_OBJECT 

public:
 Notepad();

private slots:
 void open();
 void save();
 void quit();

private:
 QTextEdit *textEdit;

 QAction *openAction;
 QAction *saveAction;
 QAction *exitAction;

 QMenu *fileMenu;
};

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.

Notepad::Notepad()
{
 saveAction = new QAction(tr("&amp;Open"), this);
 saveAction = new QAction(tr("&amp;Save"), this);
 exitAction = new QAction(tr("E&amp;amp;xit"), this);

 connect(openAction, SIGNAL (triggered()), this, SLOT (open()));
 connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));
 connect(exitAction, SIGNAL (triggered()), qApp, SLOT (quit()));

 fileMenu = menuBar()->addMenu(tr("&amp;File"));
 fileMenu->addAction(openAction);
 fileMenu->addAction(saveAction);
 fileMenu->addSeparator();
 fileMenu->addAction(exitAction);

textEdit = new QTextEdit;
 setCentralWidget(textEdit);

setWindowTitle(tr("Notepad"));
}

QActions 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 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, Exemplos da Main Window
Aplicações MDI QMdiArea, Exemplo MDI

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.

p=. Abrir e salvar

Vamos começar com o slot open():

QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "",
 tr("Text Files ('''.txt);;C++ Files ('''.cpp '''.h)"));

if (fileName != "") {
 QFile file(fileName);
 if (!file.open(QIODevice::ReadOnly)) {
 QMessageBox::critical(this, tr("Error"),
 tr("Could not open file"));
 return;
 }
 QString contents = file.readAll().constData();
 textEdit->setPlainText(contents);
 file.close();
}

O primeiro passo é perguntar ao usuário pelo nome do arquivo que deseja abrir. Qt vem com o QFileDialog, 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() 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(), 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 para mostar um diálogo com uma mensagem de erro (veja a descrição da classe QMessageBox para maiores detalhes).

Ler os dados do arquivo é trivial usando o método readAll() que retorna todos os dados do arquivo em um QByteArray. constData() retorna todos os dados em um array como um const char, que pode ser usado para gerar uma QString. O conteúdo pode ser mostrado na caixa de edição de texto. Então o método close() invocado para retornar o descritor de arquivo para o sistema operacional.

Agora, vejamos o método save():

QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "",
 tr("Text Files ('''.txt);;C++ Files ('''.cpp '''.h)")); 

if (fileName != "") {
 QFile file(fileName);
 if (!file.open(QIODevice::WriteOnly)) {
 // error message
 } else {
 QTextStream stream(&amp;file);
 stream << textEdit->toPlainText();
 stream.flush();
 file.close();
 }
}

Quando escrevemos o conteúdo da caixa de edição de texto no arquivo usamos a classe QTextStream que recebe um objeto tipo QFile. O stream de text pode escrever QStrings diretamente no arquivo enquanto QFile somente aceita dado puro (char) com o método write() do QIODevice.

Aprenda Mais

Sobre Onde
Arquivos e dispositivos de entrada e saída QFile, QIODevice