Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.

Getting Started on the Commandline/pt: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 1: Line 1:
=Iniciando o desenvolvimento com Qt=
[toc align_right="yes" depth="4"]


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 <span class="caps">API</span>, além de saber localizar toda a documentação que você precisa para as aplicações que estiver desenvolvendo.
= Iniciando o desenvolvimento com Qt =


==Olá Notepad==
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.
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.


[[Image:gs1.png]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs1.png|http://doc.qt.nokia.com/4.7/images/gs1.png]]


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] ''[doc.qt.nokia.com]'' e [http://doc.qt.nokia.com/4.7/qtextedit.html 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.
<code><br />#include &lt;QApplication&amp;gt;<br />#include &lt;QTextEdit&amp;gt;


A linha 6 cria um objeto [http://doc.qt.nokia.com/4.7/qapplication.htm 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.
int main(int argv, char **args)<br />{<br /> QApplication app(argv, args);


Linha 8 cria um objeto [http://doc.qt.nokia.com/4.7/qtextedit.html 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.
QTextEdit textEdit;<br /> textEdit.show();<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}<br /></code>


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()] ''[doc.trolltech.com]'' deve ser chamado para fazer o widget visível.
Vamos caminhar pelo código linha por linha. Nas primeiras duas linhas nós incluimos os headers &quot;QApplication&amp;quot;:http://doc.qt.nokia.com/4.7/qapplication.html e &quot;QTextEdit&amp;quot;: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.


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 6 cria um objeto &quot;QApplication&amp;quot;: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.


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:
Linha 8 cria um objeto &quot;QTextEdit&amp;quot;: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.


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.
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 &quot;show()&quot;:http://doc.trolltech.com/4.7/qwidget.html#show deve ser chamado para fazer o widget visível.


===Aprenda mais===
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.


{| class="infotable line"
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:
| '''Sobre'''
| '''Onde'''
|-
| Widgets e geometria de janelas
|
[http://doc.qt.nokia.com/4.7/application-windows.html Janelas e Diálogos] ''[doc.qt.nokia.com]''
|-
| Eventos e manipulação de eventos
|
[http://doc.qt.nokia.com/4.7/eventsandfilters.html 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).
 
[[Image:gs2.png|Editor de texto com botão para fechar]]
 
Vamos analizar o código linha a linha:
 
A linha 1 inclui [http://doc.qt.nokia.com/4.7/qtgui.html 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 &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”.
 
[http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit quit()] ''[doc.qt.nokia.com]'' é o ''slot'' de QApplication que finaliza a aplicação.[http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked clicked()] ''[doc.qt.nokia.com]'' é o sinal emitido por [http://doc.qt.nokia.com/4.7/qpushbutton.html QPushButton] ''[doc.qt.nokia.com]'' quando este for pressionado. O método estático [http://doc.qt.nokia.com/4.7/qobject.html#connect QObject::connect()] ''[doc.qt.nokia.com]'' é responsável por conectar o slot ao sinal. <span class="caps">SIGNAL</span> e <span class="caps">SLOT</span> 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 [http://doc.qt.nokia.com/4.7/qvboxlayout.html 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. [http://doc.qt.nokia.com/4.7/qvboxlayout.html 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===
<code>qmake -project<br />qmake<br />make</code>


{| class="infotable line"
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 <s>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.
| '''Sobre'''
<br />h3. Aprenda mais
| '''Onde'''
<br />|'''Sobre'''|'''Onde'''|<br />|Widgets e geometria de janelas|&quot;Janelas e Diálogos&amp;quot;:http://doc.qt.nokia.com/4.7/application-windows.html|<br />|Eventos e manipulação de eventos|&quot;O Sistema de eventos&amp;quot;:http://doc.qt.nokia.com/4.7/eventsandfilters.html|
|-
<br />h2. Adicionando um botão de saída
| Sinais e slots
<br />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).
|
<br />p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs2.png|Editor de texto com botão para fechar]]
[http://doc.qt.nokia.com/4.7/signalsandslots.html Slots e Sinais] ''[doc.qt.nokia.com]''
<br />Vamos analizar o código linha a linha:
|-
<br /><code>#include &lt;QtGui&amp;gt;
| Layouts
<br />int main(int argv, char **args)<br />{<br /> QApplication app(argv, args);
|
<br /> QTextEdit textEdit;<br /> QPushButton quitButton(&quot;Sair&amp;quot;);
[http://doc.qt.nokia.com/4.7/layout.html Gerenciamento de Layout] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/widgets-and-layouts.html widgets e Layouts] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/examples-layouts.html exemplos de layouts] ''[doc.qt.nokia.com]''
<br /> QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));
|-
<br /> QVBoxLayout layout;<br /> layout.addWidget(&amp;textEdit);<br /> layout.addWidget(&amp;quitButton);
| Os widgets do Qt
<br /> QWidget window;<br /> window.setLayout(&amp;layout);
|
<br /> window.show();
[http://doc.qt.nokia.com/4.7/gallery.html Galeria de Widgets] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/examples-widgets.html exemplos] ''[doc.qt.nokia.com]''
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}</code>
|}
<br />A linha 1 inclui &quot;QtGui&amp;quot;:http://doc.qt.nokia.com/4.7/qtgui.html, que contém todas as classes de elementos gráficos Qt.
<br />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 &quot;conectar o slot no sinal e emitir o sinal&amp;quot;.
<br />&quot;quit()&quot;:http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit é o ''slot'' de QApplication que finaliza a aplicação.&quot; clicked()&quot;:http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked é o sinal emitido por &quot;QPushButton&amp;quot;:http://doc.qt.nokia.com/4.7/qpushbutton.html quando este for pressionado. O método estático &quot;QObject::connect() &quot;: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.
<br />A linha 12 cria um &quot;QVBoxLayout&amp;quot;: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. &quot;QVBoxLayout&amp;quot;:http://doc.qt.nokia.com/4.7/qvboxlayout.html, por exemplo, posiciona os filhos verticalmente.
<br />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.
<br />h3. Aprenda Mais
<br />|'''Sobre'''|'''Onde'''|<br />|Sinais e slots|&quot;Slots e Sinais&amp;quot;:http://doc.qt.nokia.com/4.7/signalsandslots.html|<br />|Layouts|&quot;Gerenciamento de Layout&amp;quot;:http://doc.qt.nokia.com/4.7/layout.html, &quot;widgets e Layouts&amp;quot;:http://doc.qt.nokia.com/4.7/widgets-and-layouts.html, &quot;exemplos de layouts&amp;quot;:http://doc.qt.nokia.com/4.7/examples-layouts.html|<br />|Os widgets do Qt|&quot;Galeria de Widgets&amp;quot;:http://doc.qt.nokia.com/4.7/gallery.html, &quot;exemplos&amp;quot;:http://doc.qt.nokia.com/4.7/examples-widgets.html|
<br />h2. Herdando de QWidget
<br />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 &quot;QWidget&amp;quot;:http://doc.qt.nokia.com/4.7/qwidget.html e adicionamos um slot que foi conectado ao botão '''Sair'''.
<br />p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs3.png|Herdando de QWidget]]
<br />O código:<br /><code>class Notepad : public QWidget<br />{<br /> Q_OBJECT
<br />public:<br /> Notepad();
<br />private slots:<br /> void quit();
<br />private:<br /> QTextEdit *textEdit;<br /> QPushButton *quitButton;<br />};</code>
<br />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.
<br />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)
<br />Ao invés de iniciarmos a interface gráfica e conectarmos o slot dentro da função main(), agora usamos o contrutor do ''Notepad''.
<br /><code>Notepad::Notepad()<br />{<br /> textEdit = new QTextEdit;<br /> quitButton = new QPushButton(tr(&quot;Quit&amp;quot;));
<br /> connect(quitButton, SIGNAL (clicked()), this, SLOT (quit()));
<br /> QVBoxLayout *layout = new QVBoxLayout;<br /> layout</s>&gt;addWidget(textEdit);<br /> layout-&gt;addWidget(quitButton);


==Herdando de QWidget==
setLayout(layout);


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] ''[doc.qt.nokia.com]'' e adicionamos um slot que foi conectado ao botão '''Sair'''.
setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}<br /></code>


[[Image:gs3.png|Herdando de QWidget]]
Como podemos ver na definição da classe, usamos ponteiros para os nossos &quot;QObjects&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html (textEdit e quitButton). Como regra: sempre devemos alocar os &quot;QObjects&amp;quot;:http://doc.qt.nokia.com/4.7/qobject.html na ''heap'' e nunca copiá-los.


O código:<br />
Usamos a função &quot;tr()&quot;: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'''.


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.
=== Aprenda Mais ===


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)
{|
 
|'''Sobre'''
Ao invés de iniciarmos a interface gráfica e conectarmos o slot dentro da função main(), agora usamos o contrutor do ''Notepad''.
|'''Onde'''
 
Como podemos ver na definição da classe, usamos ponteiros para os nossos [http://doc.qt.nokia.com/4.7/qobject.html QObjects] ''[doc.qt.nokia.com]'' (textEdit e quitButton). Como regra: sempre devemos alocar os [http://doc.qt.nokia.com/4.7/qobject.html QObjects] ''[doc.qt.nokia.com]'' na ''heap'' e nunca copiá-los.
 
Usamos a função [http://doc.qt.nokia.com/4.7/qobject.html#tr 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===
 
{| class="infotable line"
| '''Sobre'''
| '''Onde'''
|-
|-
| tr() e i18n
|tr() e i18n
|
|&quot;Manual do Qt Linguist&amp;quot;:http://doc.qt.nokia.com/4.7/linguist-manual.html, &quot;Escrevendo código fonte para tradução&amp;quot;:http://doc.qt.nokia.com/4.7/i18n-source-translation.html, &quot;Example Olá tr()&quot;:http://doc.qt.nokia.com/4.7/linguist-hellotr.html, &quot;Internationalização com Qt&amp;quot;:http://doc.qt.nokia.com/4.7/internationalization.html
[http://doc.qt.nokia.com/4.7/linguist-manual.html Manual do Qt Linguist] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/i18n-source-translation.html Escrevendo código fonte para tradução] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/linguist-hellotr.html Example Olá tr()] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/internationalization.html Internationalização com Qt] ''[doc.qt.nokia.com]''
|-
|-
|
|&quot;QObjects&amp;quot;: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] ''[doc.qt.nokia.com]'' e o modelo do Qt Object (Isto é essencial para entender Qt)
|&quot;Modelo de Objeto&amp;quot;:http://doc.qt.nokia.com/4.7/object.html
|
[http://doc.qt.nokia.com/4.7/object.html Modelo de Objeto] ''[doc.qt.nokia.com]''
|-
|-
| qmake e o systema de construção do Qt
|qmake e o systema de construção do Qt
|
|&quot;Manual qmake&amp;quot;:http://doc.qt.nokia.com/4.7/qmake-manual.html
[http://doc.qt.nokia.com/4.7/qmake-manual.html Manual qmake] ''[doc.qt.nokia.com]''
|}
|}


==Criando um arquivo .pro==
== 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 este exemplo escreveremos nosso próprio arquivo .pro ao invés de usarmos a opção <s>project do qmake.
<br /><code>HEADERS = notepad.h<br />SOURCES = notepad.cpp main.cpp<br /></code>
<br />Para compilar o programa siga os seguintes passos:
<br /><code>qmake<br />make</code>
<br />h2. Usando o QMainWindow
<br />Várias aplicações serão beneficiadas ao usar a &quot;QMainWindow&amp;quot;: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. &quot;QMainWindow&amp;quot;: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.
<br />p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs4.png|Usando QMainWindow]]
<br />Vamos à nova definição da classe Notepad.
<br /><code>#include &lt;QtGui&amp;gt;
<br />class Notepad : public QMainWindow<br />{<br /> Q_OBJECT
<br />public:<br /> Notepad();
<br />private slots:<br /> void open();<br /> void save();<br /> void quit();
<br />private:<br /> QTextEdit *textEdit;
<br /> QAction *openAction;<br /> QAction *saveAction;<br /> QAction *exitAction;
<br /> QMenu *fileMenu;<br />};<br /></code>
<br />Incluímos mais dois slots que podem salvar e abrir um documento. Iremos implementá-los na próxima sessão.
<br />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.
<br />Como antes, usamos o costrutor do Notepad para iniciar a interface gráfica.
<br /><code>Notepad::Notepad()<br />{<br /> saveAction = new QAction(tr(&quot;&amp;Open&amp;quot;), this);<br /> saveAction = new QAction(tr(&quot;&amp;Save&amp;quot;), this);<br /> exitAction = new QAction(tr(&quot;E&amp;amp;xit&amp;quot;), this);
<br /> connect(openAction, SIGNAL (triggered()), this, SLOT (open()));<br /> connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));<br /> connect(exitAction, SIGNAL (triggered()), qApp, SLOT (quit()));
<br /> fileMenu = menuBar()</s>&gt;addMenu(tr(&quot;&amp;File&amp;quot;));<br /> fileMenu-&gt;addAction(openAction);<br /> fileMenu-&gt;addAction(saveAction);<br /> fileMenu-&gt;addSeparator();<br /> fileMenu-&gt;addAction(exitAction);


Para compilar o programa siga os seguintes passos:
textEdit = new QTextEdit;<br /> setCentralWidget(textEdit);


==Usando o QMainWindow==
setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}</code>


Várias aplicações serão beneficiadas ao usar a [http://doc.qt.nokia.com/4.7/qmainwindow.html 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. [http://doc.qt.nokia.com/4.7/qmainwindow.html 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.
&quot;QActions&amp;quot;: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 &quot;ícones&amp;quot;:http://doc.qt.nokia.com/4.7/qicon.html nos QActions.
 
[[Image:gs4.png|Usando QMainWindow]]
 
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.
 
[http://doc.qt.nokia.com/4.7/qaction.html 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 [http://doc.qt.nokia.com/4.7/qicon.html í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.
Quando um ítem do menu for pressionado, o ítem irá ativar a ação e o respectivo slot será invocado.


===Aprenda Mais===
=== Aprenda Mais ===


{| class="infotable line"
{|
| '''Sobre'''
|'''Sobre'''
| '''Onde'''
|'''Onde'''
|-
|-
| Main windows e suas classes
|Main windows e suas classes
|
|&quot;Aplicação comMain Window&amp;quot;:http://doc.qt.nokia.com/4.7/mainwindow.html, &quot;Exemplos da Main Window&amp;quot;:http://doc.qt.nokia.com/4.7/examples-mainwindow.html
[http://doc.qt.nokia.com/4.7/mainwindow.html Aplicação comMain Window] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/examples-mainwindow.html Exemplos da Main Window] ''[doc.qt.nokia.com]''
|-
|-
| Aplicações <span class="caps">MDI</span>
|Aplicações MDI
|
|&quot;QMdiArea&amp;quot;:http://doc.qt.nokia.com/4.7/qmdiarea.html, &quot;Exemplo MDI&amp;quot;:http://doc.qt.nokia.com/4.7/mainwindows-mdi.html
[http://doc.qt.nokia.com/4.7/qmdiarea.html QMdiArea] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/mainwindows-mdi.html Exemplo <span class="caps">MDI</span>] ''[doc.qt.nokia.com]''
|}
|}


==Salvando e Abrindo==
== 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.
Neste exemplo iremos implementar a funcionalidade de abrir e salvar, implementando os slots open() e save() que foram adicionados no exemplo anterior.


[[Image:gs5.png|Abrir e salvar]]
p=. [[Image:http://doc.qt.nokia.com/4.7/images/gs5.png|Abrir e salvar]]


Vamos começar com o slot open():
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 [http://doc.qt.nokia.com/4.7/qfiledialog.html 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 [http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName 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.
<code>QString fileName = QFileDialog::getOpenFileName(this, tr(&quot;Open File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp '''.h)&quot;));
 
<br />if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::ReadOnly)) {<br /> QMessageBox::critical(this, tr(&quot;Error&amp;quot;),<br /> tr(&quot;Could not open file&amp;quot;));<br /> return;<br /> }<br /> QString contents = file.readAll().constData();<br /> textEdit-&gt;setPlainText(contents);<br /> file.close();<br />}</code>
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()] ''[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 [http://doc.qt.nokia.com/4.7/qmessagebox.html QMessageBox] ''[doc.qt.nokia.com]'' 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] ''[doc.qt.nokia.com]'' para maiores detalhes).
<br />O primeiro passo é perguntar ao usuário pelo nome do arquivo que deseja abrir. Qt vem com o &quot;QFileDialog&amp;quot;: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 &quot;getOpenFileName()&quot;: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.
 
<br />Se nós tivermos um nome de arquivo então tentaremos abrí-lo uando o método &quot;open()&quot;: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 &quot;QMessageBox&amp;quot;: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 &quot;QMessageBox&amp;quot;:http://doc.qt.nokia.com/4.7/qmessagebox.html para maiores detalhes).
Ler os dados do arquivo é trivial usando o método [http://doc.qt.nokia.com/4.7/qiodevice.html#readAll readAll()] ''[doc.qt.nokia.com]'' que retorna todos os dados do arquivo em um [http://doc.qt.nokia.com/4.7/qbytearray.html QByteArray] ''[doc.qt.nokia.com]''. [http://doc.qt.nokia.com/4.7/qbytearray.html#constData constData()] ''[doc.qt.nokia.com]'' 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] ''[doc.qt.nokia.com]''. 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()] ''[doc.qt.nokia.com]''é invocado para retornar o descritor de arquivo para o sistema operacional.
<br />Ler os dados do arquivo é trivial usando o método &quot;readAll()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#readAll que retorna todos os dados do arquivo em um &quot;QByteArray&amp;quot;:http://doc.qt.nokia.com/4.7/qbytearray.html. &quot;constData()&quot;: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 &quot;QString&amp;quot;: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 &quot;close() &quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#closeé invocado para retornar o descritor de arquivo para o sistema operacional.


Agora, vejamos o método save():
Agora, vejamos o método save():


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] ''[doc.qt.nokia.com]'' 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] ''[doc.qt.nokia.com]'' somente aceita dado puro (char *) com o método [http://doc.qt.nokia.com/4.7/qiodevice.html#write write()] ''[doc.qt.nokia.com]'' do [http://doc.qt.nokia.com/4.7/qiodevice.html <span class="caps">QIOD</span>evice] ''[doc.qt.nokia.com]''.
<code>QString fileName = QFileDialog::getSaveFileName(this, tr(&quot;Save File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp '''.h)&quot;));
<br />if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::WriteOnly)) {<br /> // error message<br /> } else {<br /> QTextStream stream(&amp;file);<br /> stream &lt;&lt; textEdit-&gt;toPlainText();<br /> stream.flush();<br /> file.close();<br /> }<br />}</code>
<br />Quando escrevemos o conteúdo da caixa de edição de texto no arquivo usamos a classe &quot;QTextStream&amp;quot;: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 &quot;QFile&amp;quot;:http://doc.qt.nokia.com/4.7/qfile.html somente aceita dado puro (char''') com o método &quot;write()&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html#write do &quot;QIODevice&amp;quot;:http://doc.qt.nokia.com/4.7/qiodevice.html.


===Aprenda Mais===
=== Aprenda Mais ===


{| class="infotable line"
{|
| '''Sobre'''
|'''Sobre'''
| '''Onde'''
|'''Onde'''
|-
|-
| Arquivos e dispositivos de entrada e saída
|Arquivos e dispositivos de entrada e saída
|
|&quot;QFile&amp;quot;:http://doc.qt.nokia.com/4.7/qfile.html, &quot;QIODevice&amp;quot;:http://doc.qt.nokia.com/4.7/qiodevice.html
[http://doc.qt.nokia.com/4.7/qfile.html QFile] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/qiodevice.html <span class="caps">QIOD</span>evice] ''[doc.qt.nokia.com]''
|}
|}

Revision as of 10:08, 24 February 2015

[toc align_right="yes&quot; depth="4&quot;]

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

<br />#include &lt;QApplication&amp;gt;<br />#include &lt;QTextEdit&amp;gt;

int main(int argv, char **args)<br />{<br /> QApplication app(argv, args);

QTextEdit textEdit;<br /> textEdit.show();<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}<br />

Vamos caminhar pelo código linha por linha. Nas primeiras duas linhas nós incluimos os headers "QApplication&quot;:http://doc.qt.nokia.com/4.7/qapplication.html e "QTextEdit&quot;: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.

A linha 6 cria um objeto "QApplication&quot;: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.

Linha 8 cria um objeto "QTextEdit&quot;: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.

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 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<br />qmake<br />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&quot;:http://doc.qt.nokia.com/4.7/application-windows.html%7C
|Eventos e manipulação de eventos|"O Sistema de eventos&quot;:http://doc.qt.nokia.com/4.7/eventsandfilters.html%7C
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 &lt;QtGui&amp;gt;
<br />int main(int argv, char **args)<br />{<br /> QApplication app(argv, args);
<br /> QTextEdit textEdit;<br /> QPushButton quitButton(&quot;Sair&amp;quot;);
<br /> QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));
<br /> QVBoxLayout layout;<br /> layout.addWidget(&amp;textEdit);<br /> layout.addWidget(&amp;quitButton);
<br /> QWidget window;<br /> window.setLayout(&amp;layout);
<br /> window.show();
<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}


A linha 1 inclui "QtGui&quot;:http://doc.qt.nokia.com/4.7/qtgui.html, 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&quot;.
"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&quot;: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.
A linha 12 cria um "QVBoxLayout&quot;: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&quot;:http://doc.qt.nokia.com/4.7/qvboxlayout.html, 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&quot;:http://doc.qt.nokia.com/4.7/signalsandslots.html%7C
|Layouts|"Gerenciamento de Layout&quot;:http://doc.qt.nokia.com/4.7/layout.html, "widgets e Layouts&quot;:http://doc.qt.nokia.com/4.7/widgets-and-layouts.html, "exemplos de layouts&quot;:http://doc.qt.nokia.com/4.7/examples-layouts.html%7C
|Os widgets do Qt|"Galeria de Widgets&quot;:http://doc.qt.nokia.com/4.7/gallery.html, "exemplos&quot;:http://doc.qt.nokia.com/4.7/examples-widgets.html%7C
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&quot;:http://doc.qt.nokia.com/4.7/qwidget.html e adicionamos um slot que foi conectado ao botão Sair.
p=. Herdando de QWidget


O código:

class Notepad : public QWidget<br />{<br /> Q_OBJECT
<br />public:<br /> Notepad();
<br />private slots:<br /> void quit();
<br />private:<br /> QTextEdit *textEdit;<br /> QPushButton *quitButton;<br />};


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()<br />{<br /> textEdit = new QTextEdit;<br /> quitButton = new QPushButton(tr(&quot;Quit&amp;quot;));
<br /> connect(quitButton, SIGNAL (clicked()), this, SLOT (quit()));
<br /> QVBoxLayout *layout = new QVBoxLayout;<br /> layout</s>&gt;addWidget(textEdit);<br /> layout-&gt;addWidget(quitButton);

setLayout(layout);

setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}<br />

Como podemos ver na definição da classe, usamos ponteiros para os nossos "QObjects&quot;:http://doc.qt.nokia.com/4.7/qobject.html (textEdit e quitButton). Como regra: sempre devemos alocar os "QObjects&quot;:http://doc.qt.nokia.com/4.7/qobject.html 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.

Aprenda Mais

Sobre Onde
tr() e i18n "Manual do Qt Linguist&quot;:http://doc.qt.nokia.com/4.7/linguist-manual.html, "Escrevendo código fonte para tradução&quot;: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&quot;:http://doc.qt.nokia.com/4.7/internationalization.html
"QObjects&quot;:http://doc.qt.nokia.com/4.7/qtwebkit-bridge.html#qobjects e o modelo do Qt Object (Isto é essencial para entender Qt) "Modelo de Objeto&quot;:http://doc.qt.nokia.com/4.7/object.html
qmake e o systema de construção do Qt "Manual qmake&quot;:http://doc.qt.nokia.com/4.7/qmake-manual.html

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<br />SOURCES = notepad.cpp main.cpp<br />


Para compilar o programa siga os seguintes passos:


qmake<br />make


h2. Usando o QMainWindow
Várias aplicações serão beneficiadas ao usar a "QMainWindow&quot;: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&quot;: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.
p=. Usando QMainWindow
Vamos à nova definição da classe Notepad.


#include &lt;QtGui&amp;gt;
<br />class Notepad : public QMainWindow<br />{<br /> Q_OBJECT 
<br />public:<br /> Notepad();
<br />private slots:<br /> void open();<br /> void save();<br /> void quit();
<br />private:<br /> QTextEdit *textEdit;
<br /> QAction *openAction;<br /> QAction *saveAction;<br /> QAction *exitAction;
<br /> QMenu *fileMenu;<br />};<br />


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()<br />{<br /> saveAction = new QAction(tr(&quot;&amp;Open&amp;quot;), this);<br /> saveAction = new QAction(tr(&quot;&amp;Save&amp;quot;), this);<br /> exitAction = new QAction(tr(&quot;E&amp;amp;xit&amp;quot;), this);
<br /> connect(openAction, SIGNAL (triggered()), this, SLOT (open()));<br /> connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));<br /> connect(exitAction, SIGNAL (triggered()), qApp, SLOT (quit()));
<br /> fileMenu = menuBar()</s>&gt;addMenu(tr(&quot;&amp;File&amp;quot;));<br /> fileMenu-&gt;addAction(openAction);<br /> fileMenu-&gt;addAction(saveAction);<br /> fileMenu-&gt;addSeparator();<br /> fileMenu-&gt;addAction(exitAction);

textEdit = new QTextEdit;<br /> setCentralWidget(textEdit);

setWindowTitle(tr(&quot;Notepad&amp;quot;));<br />}

"QActions&quot;: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&quot;:http://doc.qt.nokia.com/4.7/qicon.html 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&quot;:http://doc.qt.nokia.com/4.7/mainwindow.html, "Exemplos da Main Window&quot;:http://doc.qt.nokia.com/4.7/examples-mainwindow.html
Aplicações MDI "QMdiArea&quot;:http://doc.qt.nokia.com/4.7/qmdiarea.html, "Exemplo MDI&quot;:http://doc.qt.nokia.com/4.7/mainwindows-mdi.html

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(&quot;Open File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp '''.h)&quot;));
<br />if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::ReadOnly)) {<br /> QMessageBox::critical(this, tr(&quot;Error&amp;quot;),<br /> tr(&quot;Could not open file&amp;quot;));<br /> return;<br /> }<br /> QString contents = file.readAll().constData();<br /> textEdit-&gt;setPlainText(contents);<br /> file.close();<br />}


O primeiro passo é perguntar ao usuário pelo nome do arquivo que deseja abrir. Qt vem com o "QFileDialog&quot;: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.
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&quot;: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&quot;:http://doc.qt.nokia.com/4.7/qmessagebox.html 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&quot;: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&quot;: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.

Agora, vejamos o método save():

QString fileName = QFileDialog::getSaveFileName(this, tr(&quot;Save File&amp;quot;), &quot;&quot;,<br /> tr(&quot;Text Files ('''.txt);;C++ Files ('''.cpp '''.h)&quot;)); 
<br />if (fileName != &quot;&quot;) {<br /> QFile file&amp;amp;#40;fileName&amp;amp;#41;;<br /> if (!file.open(QIODevice::WriteOnly)) {<br /> // error message<br /> } else {<br /> QTextStream stream(&amp;file);<br /> stream &lt;&lt; textEdit-&gt;toPlainText();<br /> stream.flush();<br /> file.close();<br /> }<br />}


Quando escrevemos o conteúdo da caixa de edição de texto no arquivo usamos a classe "QTextStream&quot;: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&quot;: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&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html.

Aprenda Mais

Sobre Onde
Arquivos e dispositivos de entrada e saída "QFile&quot;:http://doc.qt.nokia.com/4.7/qfile.html, "QIODevice&quot;:http://doc.qt.nokia.com/4.7/qiodevice.html