<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Qt Labs Blog Brasil</title>
	<atom:link href="http://blog.qtlabs.org.br/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.qtlabs.org.br</link>
	<description></description>
	<lastBuildDate>Thu, 05 Apr 2012 12:47:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Qt 5 Alpha</title>
		<link>http://blog.qtlabs.org.br/2012/04/04/qt-5-alpha/</link>
		<comments>http://blog.qtlabs.org.br/2012/04/04/qt-5-alpha/#comments</comments>
		<pubDate>Wed, 04 Apr 2012 21:43:38 +0000</pubDate>
		<dc:creator>Rodrigo Belem</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[Qt5]]></category>

		<guid isPermaLink="false">http://blog.qtlabs.org.br/?p=957</guid>
		<description><![CDATA[<br/>Hoje nós lançamos o Alpha do Qt 5, o primeiro grande release desde que o Qt Project foi lançado. Muita gente tem trabalhado duro para fazer este lançamento acontecer. Uma grande quantidade de trabalho e features que entraram neste alfa têm vindo de pessoas que não trabalham para a Nokia. É ótimo ver que o [...]]]></description>
			<content:encoded><![CDATA[<p></p><br/><p>Hoje nós lançamos o Alpha do Qt 5, o primeiro grande release desde que o Qt Project foi lançado. Muita gente tem trabalhado duro para fazer este lançamento acontecer. Uma grande quantidade de trabalho e features que entraram neste alfa têm vindo de pessoas que não trabalham para a Nokia. É ótimo ver que o projeto se tornou um lugar onde muitas pessoas se encontram e juntos levam o Qt em frente.</p>
<p>O principal objetivo do lançamento do Qt 5 Alpha é obter feedback que nos ajude a fazer as próximas versões melhores. Para o Alpha focamos em entregar os módulos Qt Essential, que formam a base da funcionalidade que o Qt 5 vai oferecer.</p>
<p>O alfa pode ser baixado de <a href="http://qt-project.org/wiki/Qt-5-Alpha" target="_blank">http://qt-project.org/wiki/Qt-5-Alpha</a> . Note que a versão alfa é um release apenas dos fonte e sem binários para baixar, então você precisa compilar os binários por si próprio. As instruções para compilar podem ser encontradas em <a href="http://qt-project.org/wiki/Qt-5-Alpha-building-instructions" target="_blank">http://qt-project.org/wiki/Qt-5-Alpha-building-instructions</a>.</p>
<p>Temos até agora cerca de 9 meses de trabalho no Qt 5, seguindo as ideias que descrevi num <a href="http://labs.qt.nokia.com/2011/05/09/thoughts-about-qt-5/" target="_blank">blog</a> em maio do ano passado. O blog falava sobre alguns dos objetivos que tínhamos para o Qt 5, e eu gostaria de descrever um pouco sobre o que conseguimos.</p>
<h2>A Visão</h2>
<p>Havia uma visão básica que conduzia muito do trabalho feito no Qt 5:</p>
<blockquote><p>&#8220;Qt 5 deve ser a base para uma nova forma de desenvolver de aplicações. Embora ofereça todo o poder do Qt nativo usando C++, o foco deve ser mudado para um modelo, onde C++ é usado principalmente para implementar uma funcionalidade modular para Qt Quick.&#8221;</p></blockquote>
<p>Eu posso dizer que chegamos bem perto desta visão com o Qt 5.0. Este modelo está funcionando muito bem do lado embarcado onde as UIs feitas em Qt são em tela cheia. No lado do Desktop, lançamos a maior parte das fundações necessárias para este modelo, mas levaremos até o 5,1 ou 5,2 para realmente estar pronto para uso.</p>
<h2>Desenvolvimento aberto</h2>
<p>Queríamos desenvolver Qt 5 de maneira aberta, com uma forte comunidade em torno dele. Desde o lançamento do <a href="http://qt-project.org/" target="_blank">qt-project.org</a> , vimos uma comunidade vibrante se formando lá, e muitos dos patches e novos recursos que teremos no Qt 5 são provenientes da comunidade.</p>
<h2>Quatro grandes mudanças na arquitetura</h2>
<p>Então nós definimos quatro mudanças importantes na arquitetura interna do Qt:</p>
<ol>
<li><strong>Fazer todos os portes do Qt baseados no Qt Platform Abstraction layer (QPA) &#8211; Facilitar o port do Qt para outros gerenciadores de janelas e dispositivos</strong><br />
Com o <a href="http://qt-project.org/wiki/Qt-Platform-Abstraction">QPA</a> mudamos como fundamentalmente o Qt se integra com o gerenciador de janelas do sistema operacional subjacente. O QPA foi introduzido no Qt 4.8 como substituto para QWS/Qt Embedded, mas agora é utilizado exclusivamente para todas as plataformas. Esta mudança causou muito trabalho e nos obrigou a reescrever uma parte muito grande de código específico de plataforma. Mas também nos ajudou a criar uma arquitetura mais limpa, onde o código específico de plataforma é muito bem abstraído. Podemos ver que a nova abstração tornou significativamente mais fácil escrever a integração com novos gerenciadores de janelas, backends sendo escritos para QNX, Android e iOS são a prova disso.</li>
<li><strong>Redesenhar nossa pilha gráfica &#8211; Aumentar o desempenho em comparação com o Qt 4, usando Qt Quick e OpenGL (ES) 2.0</strong><br />
O Qt 5 introduz uma nova arquitetura gráfica para o Qt Quick, usando uma Scenegraph no topo do OpenGL. Isto requer OpenGL (ES) 2,0, no mínimo para funcionar. O QtGui agora contém um conjunto de classes QOpenGL *, que substituem as antigas classes QGL* (ainda disponíveis para compatibilidade). Criamos também uma nova classe QGuiApplication que é mais leve do que a QApplication e uma classe QWindow para gerenciar janelas top level na tela. A pilha baseada em QWidget continua funcionando como no Qt 4.x, baseado na QPainter. O QPainter entretanto tem menos backends menos do que se tinha antes. Ela agora está limitada a rasterização por software (Raster backend) para desenhar na tela, pixmaps e imagens, um backend OpenGL para superfícies GL e um backend para geração de PDF e impressão. Os backends dependentes de plataforma usando X11 ou CoreGraphics não existem mais. Isso nos permite introduzir a nova arquitetura gráfica para longo prazo, mantendo total compatibilidade com o Qt 4.x na parte do QWidget.</li>
<li><strong>Estrutura do repositório modular para maior flexibilidade e para atender a junção de desktop e mobile &#8211; adicionar/remover conforme a necessidade os módulos específicos de usuários e uma integração completa da API do Qt mobility</strong><br />
Este é principalmente um item de organização interna, que não será diretamente visível para os desenvolvedores que usam Qt. Mas a modularização dos repositórios do Qt torna mais fácil para nós mantermos diferentes partes do Qt e uma forma mais independente. Isto se tornará cada vez mais importante agora que o Qt 5 está sendo estabilizado e, uma vez que for liberado o Qt 5.0 começar a manter a compatibilidade binária. A modularização ainda não está totalmente completa, o repositório do qtbase ainda contém muitos módulos que devem ser separados. Portanto, este trabalho provavelmente irá continuar após 5.0 sair. A modularização do Qt também torna muito mais fácil de integrar as contribuições em forma de módulos vindos de terceiros. Ela também é uma resposta a tendência de ter diferentes requisitos em laptops e tablets/celulares especialmente com relação aos aspectos móveis, tais como localização, sensores e etc. No Qt 5 veremos A API do Qt Mobility como parte integrada do Qt &#8211; alguns deles como parte do grupo de módulos que são vistos como essenciais para o Qt = &#8220;Qt Essentials&#8221;. Ao oferecer a abordagem modular, outros módulos podem ser adicionados de forma simples, e hoje já temos certeza de que o Qt5 irá oferecer uma lista mais rica de funcionalidade do que qualquer outras versão anterior do Qt. Note que este release da versão alpha do Qt está focada no Qt Essentials.</li>
<li><strong>Separar todas as funcionalidades relacionadas ao QWidget em sua própria biblioteca</strong><br />
Ao separar os QWidgets em um repositório separado, garantimos a continuidade dos QWidgets para aqueles que quiserem, mas também um caminho para um modelo onde todas as interfaces são feitas em QML e Qt Quick. Separar toda a funcionalidade beseadas em QWidget em sua própria biblioteca é, portanto, a longo prazo é uma boa medida para atingir uma arquitetura limpa no Qt 5.</li>
</ol>
<p>O anúncio destas mudanças criaram um monte de feedback, nos já <a href="http://labs.qt.nokia.com/2011/05/11/responses-to-qt-5/">listamos</a> muitas das dúvidas comuns sobre Qt 5 e essas mudanças estruturais anteriormente.</p>
<h2>Nova funcionalidade</h2>
<p>Além das mudanças de estrutura, o Qt 5 também oferece uma série de novas funcionalidades. Eu gostaria de destacar apenas algumas delas aqui, você pode encontrar uma lista detalhada das descrições em nosso <a href="http://qt-project.org/wiki/Qt-5Features">wiki</a>.</p>
<ul>
<li><strong>Qt Core</strong><br />
Muitos novos recursos foram adicionados ao QtCore. Temos agora a classe QStandardPaths que lhe dá os caminhos padrões para coisas como a mídias e documentos em sua plataforma. Um parser JSON e um formato binário otimizado para JSON estão inclusos. Adicionamos suporte para reconhecimento de Mimetype, tanto em extensão e como no conteúdo do arquivo. Uma nova sintaxe de conexão sinal/slot que é verificada em tempo de compilação foi adicionado e temos, uma completamente nova, engine de expressão regular compatível com Perl. Muitas das nossas estruturas de dados foram reescritas e otimizadas para um melhor desempenho. Nós também adicionamos suporte C++11 onde achamos necessário. Mas o Qt continua a compilar e funcionar com compiladores compatíveis com o C++98.</li>
<li><strong>Qt Gui</strong><br />
Todas as classes baseadas em QWidget removidas para a biblioteca QtWidgets. QtGui ganhou apoio para superfícies top level através da classe QWindow, e agora tem suporte embutido ao OpenGL.</li>
<li><strong>Qt Network</strong><br />
Nós adicionamos suporte para pesquisas de DNS e removemos as classes QHttp e QFtp (elas estão disponíveis de forma standalone para aqueles que precisarem delas). Também tivemos muitas pequenas melhorias.</li>
<li><strong>Qt Widgets</strong><br />
Foi portado para a nova arquitetura QPA e deve funcionar como antes no Qt 4.x.</li>
<li><strong>Qt Quick</strong><br />
O Qt Quick dos tempos do Qt 4.x agora está disponível módulo Qt Quick 1 e continua totalmente compatível. Este módulo está pronto e não será mais desenvolvido. O foco aqui agora são nos novos módulos Qt Quick e Qt QML. No Qt 5 nós separamos em módulos separados as partes gráficas do Qt Quick das linguagens QML e JS. As novas classes JS (QJSEngine e QJSValue) estão agora utilizando a engine V8 do Google por baixo dos panos, dando-nos um desempenho muito melhor no JavaScript. A engine do QML também passou por muitas melhorias de desempenho e algumas melhorias na linguagem. O módulo Qt Quick contém a Scenegraph baseada em OpenGL e todos os itens básicos que são conhecidos do Qt Quick do Qt 4.x. Nós adicionamos suporte a efeitos de sombreamento baseados em GL, partículas e muitas outras coisas. No lado do QML os fonte são praticamente compatíveis, mas quando se escreve itens QML em C++ alguns ajustes são necessárias para o novo scene graph.</li>
<li><strong>Qt 3D e Qt Location</strong><br />
Alguns módulos foram adicionados ao conjunto do Qt Essentials, mais notavelmente o Qt 3D para integrar conteúdo 3D com o Qt e o Qt Location que dá acesso a GPS, mapas e outros serviços baseados em localização.</li>
<li><strong>Qt WebKit</strong><br />
A API C++ do  WebKit não mudou desde o Qt 4.x, mas o Qt Webkit foi atualizado para a versão mais recente do webkit.org nos dando muitas melhorias e melhor conformidade com o HTML 5. A compilação está desativada no Windows para este alfa, fazer um build é bastante complicado neste momento. Estamos trabalhando para reativá-lo e tê-lo totalmente funcional para o beta.</li>
</ul>
<h2>Portando a partir Qt 4.x para o Qt 5</h2>
<p>Existe um binário E para uma menor quebra de compatibilidade entre Qt 4.x e Qt 5. Contudo temos trabalhado duro para fazer com que a transição seja fácil e suave do código existente para o Qt 5. Como exemplo temos atualmente o Qt Creator compilando em Qt 4.x e Qt 5 usando a mesma base de código.</p>
<p>Se você quiser experimentar o seu próprio projeto contra Qt 5, você pode encontrar instruções detalhadas de como portar <a href="http://wiki.qt-project.org/Transition_from_Qt_4.x_to_Qt5">aqui</a>.</p>
<p>Note também que não há necessidade imediata de portar seu aplicativo para Qt 5. O Qt 4.8 ainda será apoiado pela comunidade e empresas como a Digia por algum tempo. Mas acreditamos firmemente que o Qt 5 vai oferecer benefícios suficientes para considerar a migração.</p>
<h2>Próximos passos</h2>
<p>Como você pode ver um monte de coisas aconteceram desde o trabalho no Qt 5.0 iniciados. Estou muito feliz com o que conseguimos até agora. Agora você pode nos ajudar a finalizar o Qt 5 baixando o alfa, experimentando-o e dando-nos feedback.</p>
<p>Todos os comentários devem ser enviados para a lista de desenvolvimento do Qt (development@qt-project.org, veja também <a href="http://lists.qt-project.org/mailman/listinfo/development">lists.qt-project.org</a>) ou, simplesmente, reporte como bug no nosso <a href="http://bugreports.qt-project.org/" target="_blank">sistema de rastreamento de bugs</a> . Todos os patches e correções de bugs são, naturalmente, também muito bem-vindas, por favor envie-os para <a href="http://codereview.qt-project.org/" target="_blank">codereview.qt-project.org</a>.</p>
<p>O alfa é o primeiro passo para a versão final do Qt 5, e o foco a partir de agora será totalmente em &#8220;aparar&#8221; as questões pendentes para que possamos entregar o Qt 5.0 final para você o mais breve possível.</p>
<p>Houve muitas pessoas envolvidas até este ponto para mencioná-los todos aqui, mas eu gostaria de agradecer a cada um que contribuiu de alguma forma para este release.</p>
<p>Divirtam-se!</p>
<p>Lars</p>
<p>&nbsp;</p>
<p>Fonte: <a href="http://labs.qt.nokia.com/2012/04/03/qt-5-alpha/">http://labs.qt.nokia.com/2012/04/03/qt-5-alpha/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qtlabs.org.br/2012/04/04/qt-5-alpha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qt Games Brasil</title>
		<link>http://blog.qtlabs.org.br/2012/04/04/qt-games-brasil/</link>
		<comments>http://blog.qtlabs.org.br/2012/04/04/qt-games-brasil/#comments</comments>
		<pubDate>Wed, 04 Apr 2012 19:12:45 +0000</pubDate>
		<dc:creator>Daker Pinheiro</dc:creator>
				<category><![CDATA[Geral]]></category>

		<guid isPermaLink="false">http://blog.qtlabs.org.br/?p=964</guid>
		<description><![CDATA[<br/>Desde o dia 27/03/2012 está ocorrendo uma Oficina de Jogos Qt no Centro de Informática, na Universidade Federal de Pernambuco (UFPE), organizada pela Nokia. O objetivo desta oficina é fazer com que os alunos aprendam como desenvolver jogos e aplicações utilizando Qt e saiam do curso com pelo menos um jogo publicado na loja de [...]]]></description>
			<content:encoded><![CDATA[<p></p><br/><p>Desde o dia 27/03/2012 está ocorrendo uma Oficina de Jogos Qt no Centro de Informática, na Universidade Federal de Pernambuco (UFPE), organizada pela Nokia. O objetivo desta oficina é fazer com que os alunos aprendam como desenvolver jogos e aplicações utilizando Qt e saiam do curso com pelo menos um jogo publicado na loja de aplicativos da Nokia. Temos como exemplos de jogos feitos em Qt de sucesso como o <a href="http://store.ovi.com/content/216045">Heebo</a> e o <a href="http://n9-apps.com/pathwind">Pathwind</a>, além do <a href="http://store.ovi.com/content/214283">The Incredible Circus</a>, recordista de downloads, passando da marca dos 600 mil.</p>
<div class="wp-caption alignnone" style="width: 410px">
	<img title="Incredible Circus" src="http://3.bp.blogspot.com/-3wS1pGGNLLY/TxwlaYoT64I/AAAAAAAAAjc/ho9Im6PTzxQ/s1600/nokia%2Bn8%2Bincredible%2Bcircus.jpg" alt="" width="410" height="281" />
	<p class="wp-caption-text">Incredible Circus</p>
</div>
<p>Como existem várias pessoas interessadas no desenvolvimento de jogos utilizando Qt em todo o Brasil, criamos a <a href="http://groups.google.com/group/qtgamesbr">lista de discussão QtGamesBR</a>. Essa lista servirá de canal de comunicação sobre o desenvolvimento de jogos em Qt, problemas e dúvidas. Também postaremos as novidades da oficina de jogos na UFPE na lista, então fiquem ligados.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qtlabs.org.br/2012/04/04/qt-games-brasil/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Palestras na EST &#8211; UEA</title>
		<link>http://blog.qtlabs.org.br/2012/04/03/palestras-na-est-uea/</link>
		<comments>http://blog.qtlabs.org.br/2012/04/03/palestras-na-est-uea/#comments</comments>
		<pubDate>Tue, 03 Apr 2012 18:05:54 +0000</pubDate>
		<dc:creator>Anderson Briglia</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[QML]]></category>

		<guid isPermaLink="false">http://blog.qtlabs.org.br/?p=949</guid>
		<description><![CDATA[<br/>Na última sexta-feira aconteceu em Manaus, na Escola Superior de Tecnologia da Universidade Estadual do Amazonas, um evento com várias palestras sobre desenvolvimento de aplicações utilizando Qt. As palestras foram as seguintes (Clique nos links para baixar o arquivo PDF): Introdução ao Qt Utilizando o recurso da camera dos smartphones da Nokia com Qt Quase-engine: [...]]]></description>
			<content:encoded><![CDATA[<p></p><br/><p>Na última sexta-feira aconteceu em Manaus, na Escola Superior de Tecnologia da Universidade Estadual do Amazonas, um evento com várias palestras sobre desenvolvimento de aplicações utilizando Qt.</p>
<p>As palestras foram as seguintes (Clique nos links para baixar o arquivo PDF):</p>
<ul>
<li><a href="http://www.slideshare.net/andersonbriglia/introduo-ao-qt">Introdução ao Qt</a></li>
<li><a href="http://www.slideshare.net/andersonbriglia/utilizando-a-camera-usando-qt">Utilizando o recurso da camera dos smartphones da Nokia com Qt</a></li>
<li><a href="http://www.slideshare.net/andersonbriglia/quasi-engine-ueapt">Quase-engine: Desenvolvendo jogos em QML</a></li>
<li><a href="http://www.slideshare.net/andersonbriglia/qt-location-api">Qt Location API</a></li>
</ul>
<p>Algumas fotos do evento estão disponíveis <a href="https://plus.google.com/photos/115572007345716524483/albums/5727235655064055345">aqui</a>.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qtlabs.org.br/2012/04/03/palestras-na-est-uea/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>QML Location API</title>
		<link>http://blog.qtlabs.org.br/2012/03/23/qml-location-api/</link>
		<comments>http://blog.qtlabs.org.br/2012/03/23/qml-location-api/#comments</comments>
		<pubDate>Fri, 23 Mar 2012 21:27:00 +0000</pubDate>
		<dc:creator>Andre Loureiro</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[QML]]></category>

		<guid isPermaLink="false">http://blog.qtlabs.org.br/?p=913</guid>
		<description><![CDATA[<br/>O uso de localização em aplicações móveis tem crescido conforme o uso de smartphones vem se popularizando, ou seja, é &#8220;legal&#8221; compartilhar com seus amigos sua localização e inserir lugares bem frequentados ou desconhecidos do restante das pessoas. É nesse cenário que vamos explorar um pouco da API de localização do Qt. Antes de iniciar [...]]]></description>
			<content:encoded><![CDATA[<p></p><br/><h1><strong><br />
</strong></h1>
<p>O uso de localização em aplicações móveis tem crescido conforme o uso de smartphones vem se popularizando, ou seja, é &#8220;legal&#8221; compartilhar com seus amigos sua localização e inserir lugares bem frequentados ou desconhecidos do restante das pessoas. É nesse cenário que vamos explorar um pouco da API de localização do Qt.</p>
<p>Antes de iniciar os trabalhos precisamos ter o módulo Location do Qt Mobility. Você pode obtê-lo clonando os fontes direto do <a href="http://qt.gitorious.org/qt-mobility">qt.gitorious.org/qt-mobility</a> ou pode usar o simulador do QtSDK.</p>
<h3><strong>Projeção de Mercator</strong></h3>
<p>A <a href="http://en.wikipedia.org/wiki/Mercator_projection"><strong>projeção de Mercator</strong></a> é usada pelos serviços de mapas online para retornar os <em>tiles names</em> a partir das coordenadas de longitude e latitude. O nível de detalhes é medido pelo zoom. Quanto maior for, mais <em>tiles</em> teremos:<br />
zoom 0: 1&#215;1<br />
zoom 10: 1024&#215;1024</p>
<h3><strong>QML Location Plugin</strong></h3>
<p>Agora que já sabemos como funciona um serviço de mapas, vamos mostrar como usá-los através da API de localização do Qt, especificamente o Plugin QML.<br />
Será demonstrado o uso de dois componentes básicos do plugin.<br />
Vamos usar o componente <a href="http://doc.qt.nokia.com/qtmobility/qml-map.html"><strong>Map</strong></a> para mostrar um mapa na view principal.</p>
<pre class="brush:js">import QtQuick 1.0
import QtMobility.location 1.2

Item {
    width: 800
    height: 600

    Map {
        plugin: Plugin { name: "nokia"}
        zoomLevel: 0
        anchors.fill: parent
    }
}</pre>
<p>Com isso podemos visualizar apenas um <em>tile</em> contendo todo o mapa da Terra.<br />
Aumentando o valor da propriedade <a href="http://doc.qt.nokia.com/qtmobility/qml-map.html#zoomLevel-prop"><em><strong>zoomLevel</strong></em></a> mais <em>tiles</em> são mostrados na view, ou seja, um mapa mais detalhado.</p>
<p>O componente <a href="http://doc.qt.nokia.com/qtmobility/qml-map.html"><strong>Map</strong></a> possui uma propriedade chamada <a href="http://doc.qt.nokia.com/qtmobility/qml-map.html#plugin-prop"><strong><em>plugin</em></strong></a>, a qual é responsável por carregar o serviço de mapas a ser utilizado.</p>
<p>A Qt Location API dispõe, por enquanto, apenas do plugin para o serviço do Nokia Maps. Este é definido pela declaração de um componente <a href="http://doc.qt.nokia.com/qtmobility/qml-plugin.html"><strong>Plugin</strong> </a>e setando o valor da propriedade <a href="http://doc.qt.nokia.com/qtmobility/qml-plugin.html#name-prop"><em><strong>name</strong></em></a> para &#8220;nokia&#8221;.<br />
A implementação de plugins alternativos será tópico de um próximo post.<br />
Agora vamos deixar nosso exemplo um pouco mais interessante usando o GPS do celular. Para fazer isso usaremos o componente <a href="http://doc.qt.nokia.com/qtmobility/qml-positionsource.html"><strong>PositionSource.</strong></a></p>
<pre class="brush:js">PositionSource {
    id: gps
    updateInterval: 30000
    active: true
}</pre>
<p>Na propriedade <em><a href="http://doc.qt.nokia.com/qtmobility/qml-positionsource.html#updateInterval-prop"><strong>updateInterval</strong></a></em> configuramos o intervalo de tempo que atualizaremos a posição, ou seja, a cada 30 segundos acessaremos o GPS e pegaremos as coordenadas, latitude e longitude.<br />
Agora a ideia é pegar a posição atual e desenhar no mapa um círculo com a cor vermelha simbolizando a posição atual do dispositivo, então pra isso vamos integrar o código de acesso ao GPS com o mapa.</p>
<pre class="brush:js">import QtQuick 1.0
import QtMobility.location 1.2

Item {
    width: 800
    height: 600

    PositionSource {
        id: gps
        updateInterval: 30000
        active: true
    }

    Map {
        plugin: Plugin { name: "nokia"}
        zoomLevel: 0
        center: gps.position.coordinate
        anchors.fill: parent
        MapCircle {
            id: currentPosition
            radius: 100
            color: "red"
            center: gps.position.coordinate
        }
    }
}</pre>
<p>Com isso mostraremos um círculo na posição atual do dispositivo, com um raio de 100 metros. Também configuramos o mapa para ter seu centro o mesmo da coordenada do GPS.<br />
Isso é apenas um pequeno exemplo de como usar a API de localização do Qt. Uma sugestão seria, pintar uma imagem no lugar de um círculo, e trabalhar com zoom. Até a próxima.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qtlabs.org.br/2012/03/23/qml-location-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qt Platform Abstraction, Lighthouse para os íntimos</title>
		<link>http://blog.qtlabs.org.br/2012/03/16/qt-platform-abstraction-lighthouse-para-os-intimos/</link>
		<comments>http://blog.qtlabs.org.br/2012/03/16/qt-platform-abstraction-lighthouse-para-os-intimos/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 16:30:14 +0000</pubDate>
		<dc:creator>Anselmo L. S. Melo</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[Qt5]]></category>
		<category><![CDATA[lighthouse]]></category>
		<category><![CDATA[qpa]]></category>
		<category><![CDATA[qt5]]></category>

		<guid isPermaLink="false">http://blog.qtlabs.org.br/?p=391</guid>
		<description><![CDATA[<br/>É do conhecimento de muitos que Qt é oficialmente suportado em várias plataformas. Recentemente, graças aos esforços da comunidade, novas plataformas passaram a ser suportadas &#8211; ainda de forma não oficial &#8211; com destaque para Android e iOS. No post de hoje, faremos uma breve introdução à nova estrutura que tem como objetivo simplificar novos ports de [...]]]></description>
			<content:encoded><![CDATA[<p></p><br/><p>É do conhecimento de muitos que Qt é oficialmente suportado em várias plataformas. Recentemente, graças aos esforços da comunidade, novas plataformas passaram a ser suportadas &#8211; ainda de forma não oficial &#8211; com destaque para Android e iOS. No <em>post </em>de hoje, faremos uma breve introdução à nova estrutura que tem como objetivo simplificar novos <em>ports</em> de Qt, o QPA &#8211; Qt Platform Abstraction, <em>codename</em> Lighthouse.</p>
<p><strong>Começo</strong></p>
<p>Em meados de 2009 alguns dos desenvolvedores baseados em Oslo resolveram refatorar o código existente no chamado Qt for Embedded, que é, resumidamente, focada em dispositivos embarcados sem Xorg (no caso do Qt for Embedded Linux), usando <em>framebuffer </em>para a saída gráfica. Nele, existe o QWS &#8211; Q Windowing System &#8211; que faz as vezes de sistema de janelas simples. A idéia de refatorar tal código era justamente para reduzir a dependência do QWS, porém foram anos de &#8220;contaminação&#8221; de código e essa tarefa demonstrou-se maior do que o esperado. Foi então que surgiu uma ideia:</p>
<blockquote><p>Quão difícil seria remover todo o código específico de plataformas e ter um novo <em>port</em> compilável?</p></blockquote>
<p>Parte do plano era aproveitar que Qt já contava com a Raster Engine e os <a href="http://labs.qt.nokia.com/2007/08/09/qt-invaded-by-aliens-the-end-of-all-flicker/" target="_blank">Alien Widgets já haviam invadido e fixado residência no Qt 4.4</a>. Uma semana mais tarde, já existia um código para QtGui independente de plataforma e compilado com sucesso.</p>
<p><strong>Raster Engine? Alien widgets?</strong></p>
<p><strong></strong>Ambos são potenciais temas para novos posts, segue uma rápida (e, digamos, superficial) explicação para que possamos seguir com nosso assunto: <em> Raster Engine</em> é um sistema gráfico implementado totalmente em software, ou seja, de forma independente do hardware onde está sendo executado. Foi introduzido no Qt 4.0 após repetidas tentativas de utilizar GDI e GDI+ (APIs nativas do Microsoft Windows) para backend gráfico de Qt no MicrosoftWindows. <em>Alien Widgets</em> é o nome dado à uma forma como os widgets são criados na tela. Para nossa rápida explicação de hoje, usaremos terminologia do Xorg. Tradicionalmente, cada widget era na verdade uma &#8220;janela do X&#8221;. Assim, uma tela contendo o que costumamos chamar de janela, contendo um botão e um checkbox teria, em termos de estruturas do X, 3 janelas, sendo que 2 delas aninhadas em uma maior. Essa combinação toda era grande responsável por efeitos visuais indesejáveis quando redimensionávamos aplicações, pois o Xserver precisava coordenar a movimentação e redimensionamento desses componentes, o que não acabava bem. Com os Alien Widgets acontece diferente: O Xserver conhece apenas a janela <em>top level</em>, os widgets dentro dela ficam por conta da maquinaria interna do Qt.</p>
<p><strong>Voltando ao assunto</strong></p>
<p><strong></strong>O próximo passo seria conseguir criar um processo único com uma janela full-screen utlizando framebuffer, aproveitando-se dessa infra-estrutura. Com o sucesso desse experimento, o projeto tomou forma e recebeu o nome de <em>Lighthouse,</em> tendo como objetivo: &#8220;Como tornar mais fácil Qt suportar diferentes hardwares gráficos&#8221;. Com Lighthouse, um port passa a precisar de um plugin que implemente a representação de janelas (window surfaces) para dado cliente (ex: x11 client) e funcionalidades para envio e recebimento de mensagens para o servidor do sistema de janelas (window system server). Um primeiro <em>port</em> teste feito, utilizando QImage como <em>display device,</em>precisou deapenas 147 linhas de código. Prefere uma comparação de uma classe real? qwidget_x11.cpp: 2424 linhas, qwidget_qpa.cpp: 671 linhas. O código correspondente à essa reengenharia já encontra-se integrado no branch 4.8, com o nome Qt Platform Abstraction. Portanto, aqueles que tiverem o repositório clonado podem observar em src/gui/kernel a existência de arquivos com o sufixo _qpa.h:</p>
<ul>
<li>qplatformclipboard_qpa.h</li>
<li>qplatformcursor_qpa.h</li>
<li>qplatformeventloopintegration_qpa.h</li>
<li>qplatformglcontext_qpa.h</li>
<li>qplatformintegrationplugin_qpa.h</li>
<li>qplatformintegration_qpa.h</li>
<li>qplatformnativeinterface_qpa.h</li>
<li>qplatformscreen_qpa.h</li>
<li>qplatformwindowformat_qpa.h</li>
<li>qplatformwindow_qpa.h</li>
</ul>
<p>Analisando os nomes desses arquivos (e das classes contidas neles) notamos os componentes que devem ser implementados em um novo port de Qt. Além dos já mencionados ports para Android (Necessitas) e iOS, são outros exemplos que aproveitaram do Lighthouse:</p>
<p>libCaca: convertendo widgets para modo texto. útil? Não sei, mas vale para exemplificar como ficou mais fácil <em>portar </em>Qt =)</p>
<p><object width="420" height="315" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/ZJyF99uqSbY?version=3&amp;hl=en_US" /><param name="allowfullscreen" value="true" /><embed width="420" height="315" type="application/x-shockwave-flash" src="http://www.youtube.com/v/ZJyF99uqSbY?version=3&amp;hl=en_US" allowFullScreen="true" allowscriptaccess="always" allowfullscreen="true" /></object></p>
<p>&nbsp;</p>
<p>Qt on NaCl:</p>
<p><object width="420" height="315" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/U6xZsqcA-Sk?version=3&amp;hl=en_US" /><param name="allowfullscreen" value="true" /><embed width="420" height="315" type="application/x-shockwave-flash" src="http://www.youtube.com/v/U6xZsqcA-Sk?version=3&amp;hl=en_US" allowFullScreen="true" allowscriptaccess="always" allowfullscreen="true" /></object></p>
<p>&nbsp;</p>
<p>A tarefa de suportar o Wayland também foi beneficiada por essa nova estrutura, que também está tendo um importante papel no desenvovimento do futuro Qt5. Para referência, os artigos no Qt Labs a respeito desse assunto estão dentro da <a href="http://labs.qt.nokia.com/category/labs/lighthouse/" target="_blank">categoria lighthouse</a>.</p>
<p>Até a próxima =)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qtlabs.org.br/2012/03/16/qt-platform-abstraction-lighthouse-para-os-intimos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Threaded OpenGL no 4.8</title>
		<link>http://blog.qtlabs.org.br/2012/03/01/threaded-opengl-no-4-8/</link>
		<comments>http://blog.qtlabs.org.br/2012/03/01/threaded-opengl-no-4-8/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 17:46:49 +0000</pubDate>
		<dc:creator>Anderson Briglia</dc:creator>
				<category><![CDATA[Geral]]></category>

		<guid isPermaLink="false">http://blog.qtlabs.org.br/?p=865</guid>
		<description><![CDATA[<br/>Este post é uma tradução deste aqui: http://labs.qt.nokia.com/2011/06/03/threaded-opengl-in-4-8/ escrito por Jason Barron. &#8212; Se você usou o módulo OpenGL no Qt em algum momento você deve ter tido a vontade de executá-lo como uma thread separada. A implementação básica do OpenGL é por si só (em sua maioria), reentrante, e desta forma não havia nada [...]]]></description>
			<content:encoded><![CDATA[<p></p><br/><p>Este post é uma tradução deste aqui: http://labs.qt.nokia.com/2011/06/03/threaded-opengl-in-4-8/ escrito por Jason Barron.</p>
<p>&#8212;</p>
<p>Se você usou o módulo OpenGL no Qt em algum momento você deve ter tido a vontade de executá-lo como uma thread separada. A implementação básica do OpenGL é por si só (em sua maioria), reentrante, e desta forma não havia nada impedindo você. Na realidade, há algum tempo atrás, na 6ª edição da Qt Quarterly nós tivemos um <a href="http://doc.qt.nokia.com/qq/qq06-glimpsing.html#writingmultithreadedglapplications">artigo</a> descrevendo como você poderia fazer isso. Tudo isso estava ok para a maioria das pessoas que gastavam mais tempo escrevendo código OpenGL &#8220;puro&#8221;, mas e se você quisesse usar algumas classes convenientes do Qt em uma thread separada? Infelizmente isso não era possível pois algumas classes não eram thread-safe. Com o Qt 4.8, isso mudou e agora nós temos suporte para a maioria dos cenários mais comuns. Para usar a nova funcionalidade no X11 você precisa habilitar o atributo Qt::AA_X11InitThreads na sua aplicação para garantir que as chamadas básicas para o GLX sejam thread-safe, mas para Windows e Mac OS X isto deve funcionar de forma natural.</p>
<p><strong>Buffer swapping thread</strong></p>
<p>Dependendo do seu driver e da GPU, a chamada para swapBuffers() pode ser uma chamada de função custosa às vezes (especialmente em processadores embarcados). Na maioria dos casos, esta é a função que diz para a GPU agrupar todos os comandos de renderização e executá-los para renderizar o frame corrente. Se esta operação é síncrona, então seu main thread é bloqueado enquanto a GPU está fazendo isso. Isto é ruim pois sua thread corrente tem muitos mais coisas para fazer do que esperar pela GPU. Por exemplo, ela poderia retornar para o loop de execução e processar algum input do usuário, tráfego de rede ou avançar a próxima cena de uma animação. A solução para fazer isso no 4.8 é ter uma thread separada que tem como único objetivo esperar pela GPU chamando swapBuffers. Na prática, você pode renderizar tudo normalmente na main thread, mas ao invés de chamar swapBuffers(), você deve chamar doneCurrent() no contexto GL. Você então deve notificar a thread de swapping que você terminou de renderizar e ela deveria chamar makeCurrent() para ativar o contexto atual e então chamar swapBuffers(). A thread de swapping pode então chamar doneCurrent() e notificar a main thread que terminou. Note que, há uma troca de contexto e esse overhead pode, na realidade, ser maior do que se a main thread tivesse apenas esperado a GPU finalizar então é importante que você teste isto para ver se existe algum ganho.</p>
<p><strong>Texture uploading thread</strong></p>
<p>Fazer o upload de muitas ou texturas grandes geralmente é uma operação custosa por conta da quantidade de dados sendo enviada para a GPU. Novamente, está é uma daquelas operações que bloqueiam a sua main thread. No 4.8 você pode resolver esse problema criando um par de shared QGLWidgets. Um desses widgets é construído numa thread separada, mas nunca visível na tela. A main thread informa à thread de upload quais imagens devem ser carregadas e a thread de upload simplesmente chama bindTexture() em cada uma dessas imagens e notifica de volta a main thread quando cada uma delas estiverem prontas para serem desenhadas na tela.</p>
<p><strong>QPainter thread</strong></p>
<p>No 4.8 agora é possível usar o QPainter numa thread separada para renderizar para um QGLWidget, QGLPixelBuffer e QGLFrameBufferObject, assumindo que você esteja usando a engine de pintura do OpenGL [ES] 2.0. É importante salientar que um QGLWidget não é movido para uma thread secundária (ele é um QWidget no fim das contas). Entretanto, desde que seu contexto seja usado em algum lugar, é necessário chamar doneCurrent() no contexto do QGLWidget para liberar o contexto da main thread. Em seguida você deve criar  uma subclasse QObject separada que pode ser movida para a thread secundária do painter. Este QObject fará com que o contexto do QGLWidget seja o contexto corrente na thread do painter e então você pode abrir um QPainter no alvo e começar a pintura. Se você está usando um QGLWidget como alvo, então você deve adicionar o atributo &#8220;Qt::WA_PaintOutsidePaintEvent&#8221; no QGLWidget. Você ainda vai precisar de uma subclasse para reimplementar as funções de resizeEvent() e paintEvent() do QGLWidget. A implementação padrão tenta fazer o contexto do QGLWidget ser o corrente e desde que essas funções são chamadas pela main thread (onde o widget está), nós não queremos que isso aconteça pois estamos usando o contexto da thread do painter. Na reimplementação destas funções, você deve notificar a subclasse QObject que faz a renderização para que ela redimensione o viewport or re-pinte a cena quando necessário. O resultado disto tudo pode ser visto em um novo demo chamado glhypnotizer que executa várias subjanelas MDI contendo um QGLWidget renderizando a partir de uma thread secundária.</p>
<div class="wp-caption aligncenter" style="width: 698px">
	<img src="http://labs.qt.nokia.com/wp-content/uploads/2011/06/glhypnotizer-demo.png" alt="" width="698" height="333" />
	<p class="wp-caption-text">Schreenshot do demos/glhypnotizer no Qt 4.8</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.qtlabs.org.br/2012/03/01/threaded-opengl-no-4-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qt 4.8.0!</title>
		<link>http://blog.qtlabs.org.br/2011/12/16/qt-4-8-0/</link>
		<comments>http://blog.qtlabs.org.br/2011/12/16/qt-4-8-0/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 21:10:04 +0000</pubDate>
		<dc:creator>Anselmo L. S. Melo</dc:creator>
				<category><![CDATA[Geral]]></category>

		<guid isPermaLink="false">http://blog.qtlabs.org.br/?p=848</guid>
		<description><![CDATA[<br/>Ontém foi feito o anúncio da versão 4.8.0! Destaques dessa nova versão de Qt: Qt Platform Abstraction (QPA) QPA é o nome dado à reestruturação feita no módulo QtGui de modo a tornar mais fácil a tarefa de &#8220;portar&#8221; Qt para diferentes sistemas de janela e dispositivos. Um artigo em Português será publicado aqui em [...]]]></description>
			<content:encoded><![CDATA[<p></p><br/><p>Ontém foi feito o anúncio da versão 4.8.0!</p>
<p>Destaques dessa nova versão de Qt:</p>
<ul>
<li>
<h3>Qt Platform Abstraction (QPA)</h3>
<p>QPA é o nome dado à reestruturação feita no módulo QtGui de modo a tornar mais fácil a tarefa de &#8220;portar&#8221; Qt para diferentes sistemas de janela e dispositivos. Um artigo em Português será publicado aqui em breve, fique ligado!</li>
<li>
<h3>Threaded OpenGL</h3>
<p>Permite aos não OpenGL-ninjas renderizar OpenGL em mais de uma thread concomitantemente. Para mais informações (em Inglês): <a title="Description of threaded OpenGL in Qt 4.8" href="http://labs.qt.nokia.com/2011/06/03/threaded-opengl-in-4-8/" target="_blank">Threaded OpenGL in 4.8</a>.</li>
<li>
<h3>Multithreaded HTTP</h3>
<p>Requisições HTTP agora são, por padrão, manipuladas em uma <em>thread.</em> separada. Principal benefício é a redução do impacto nas interfaces gráficas pois a parte de rede não estará mais no <em>event loop</em> principal.</li>
<li>
<h3>Otimizações no acesso a sistemas de arquivo</h3>
<p>A pilha de sistemas de arquivo recebeu grandes modificações, resultando em melhorias em operações de Leitura/Escrita. A melhora de desempenho pode ser vista em todas as plataformas.</li>
</ul>
<p>Outro ponto importante é que Qt 4.8.0 contém a versão 2.2.1 de QtWebKit. Mais detalhes dessa versão <a href="http://labs.qt.nokia.com/2011/07/19/qt-4-8-beta-released/" target="_blank">nesse post</a>  (em Inglês).</p>
<p>E como parte do <a href="http://blog.qtlabs.org.br/2011/08/06/novidades-na-documentacao/" target="_blank">processo já tratado aqui no Qt Labs Brasil</a>, a <a href="http://developer.qt.nokia.com/doc/qt-4.8/" target="_blank">documentação</a> está integrada com a <a title="Qt Developer Network" href="http://developer.qt.nokia.com/" target="_blank">Qt Developer network</a>.</p>
<h2>Downloads</h2>
<p>Tanto código quanto pacotes binários estão disponíveis na <a href="http://qt.nokia.com/downloads" target="_blank">página de downloads</a>. Para aqueles que possuem <em>git clone</em> do <a href="https://qt.gitorious.org/" target="_blank">repositório</a>, essa versão está identificada pela <em>tag</em> &#8221;v4.8.0&#8243;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qtlabs.org.br/2011/12/16/qt-4-8-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Offline Storage em QML</title>
		<link>http://blog.qtlabs.org.br/2011/11/11/offline-storage-em-qml/</link>
		<comments>http://blog.qtlabs.org.br/2011/11/11/offline-storage-em-qml/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 18:14:45 +0000</pubDate>
		<dc:creator>Daker Pinheiro</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[qml]]></category>

		<guid isPermaLink="false">http://blog.qtlabs.org.br/?p=768</guid>
		<description><![CDATA[<br/>Muitas aplicações precisam armazenar dados para que os mesmos estejam disponíveis após o término de sua execução. Além da opção de lidarmos diretamente com arquivos, o Qt provê diversas maneiras de guardar informações offline como por exemplo o QSettings caso se deseje armazenar apenas chaves e valores. Também é possível utilizar o módulo Qt SQL [...]]]></description>
			<content:encoded><![CDATA[<p></p><br/><p>Muitas aplicações precisam armazenar dados para que os mesmos estejam disponíveis após o término de sua execução. Além da opção de lidarmos diretamente com arquivos, o Qt provê diversas maneiras de guardar informações offline como por exemplo o <a href="http://doc.qt.nokia.com/latest/qsettings.html">QSettings</a> caso se deseje armazenar apenas chaves e valores. Também é possível utilizar o módulo <a href="http://doc.qt.nokia.com/latest/qtsql.html">Qt SQL</a> para lidar com dados estruturados de forma mais complexa. No entanto, essas abordagens exigem integração do código QML com o C++, o que as vezes não é desejável. Uma alternativa é utilizar a <em>Offline Storage API</em> (Armazenamento Offline) para não precisar sair do ambiente QML. Essa API provê uma interface SQL, que permite manipular bancos de dados relacionais (BDs), utilizando o <a href="http://sqlite.org/">SQLite</a> como <em>backend</em>.</p>
<p>Detalhes sobre o <em>offline storage</em> pode ser encontrado na <a href="http://doc.qt.nokia.com/latest/qdeclarativeglobalobject.html">documentação oficial do Qt</a>. Apesar de ser bem escrita, a documentação não nos dá um exemplo prático que ilustre o uso dessa API, portanto, decidí criar um que mostra as boas práticas do uso da mesma.</p>
<h2>Lista de Contatos</h2>
<p>Imagine que você tem uma lista de contatos para armazenar em sua aplicação. As informações necessárias para armazenar esses contatos são seus nomes, número de telefone e email. O primeiro passo é criar uma conexão com o banco de dados do <em>offline storage</em>,</p>
<pre class="brush:js">// A função openDatabaseSync seguintes parametros
// 1 - Nome do banco de dados (BD)
// 2 - Versão do BD
// 3 - Descrição sobre o BD
// 4 - Estimativa de tamanho do BD
// Retorna um objeto do tipo Database
var db = openDatabaseSync("Contacts", "1.0", "Contact list database", 5*1024*1024);</pre>
<p>Para manipular um banco de dados no Javascript uma conexão com o banco deve ser criada. A API de <em>offline storage</em> disponibilizada para o QML é assíncrona no que se refere a criação e execução de <a href="https://pt.wikipedia.org/wiki/Transa%C3%A7%C3%A3o_at%C3%B4mica">transações</a>. As transações são criadas através do método <em>transaction</em> do objeto de conexão com o <em>offline storage</em>. Essa função segue o padrão de <em>callbacks</em> do Javascript para lidar com chamadas assíncronas. Assim que a transação está pronta para ser iniciada, ela chama uma função (o <em>callback</em>) passando o objeto que representa a transação como parâmetro. Com a referência do objeto da transação, as consultas e alterações no banco podem ser realizadas.</p>
<p>Para criar as tabelas é preciso abrir uma transação para executar o código SQL referente a sua criação. Isso pode ser feito da seguinte forma:</p>
<pre class="brush:js">// Abrindo transação
db.transaction(function (tx) { // tx é um objeto do tipo transação
    tx.executeSql("CREATE TABLE IF NOT EXISTS Contacts ( \
        id INTEGER PRIMARY KEY AUTOINCREMENT, \
        name STRING, \
        phone STRING, \
        email STRING, \
        UNIQUE (name) ON CONFLICT REPLACE)");
});</pre>
<h2>Abstraíndo o Banco de Dados</h2>
<p>Em minha experiência com o <em>offline storage</em>, recomendo que as funções que operam o BD deveriam ficar em um módulo (ou um conjunto de módulos) Javascript a parte. Nesses módulos, além da criação do esquema do banco de dados, recomendo definir funções de acesso aos dados que escondam o SQL da aplicação QML, ao criar funções que manipulem esses dados em formatos amigáveis ao QML:</p>
<pre class="brush:js">// O callback é chamado quando o contato é inserido ou atualizado e o id gerado é passado como parâmetro da callback.
function insertOrUpdateContact(name, phone, email, callback) {
    db.transaction(function (tx) {
        // Note que o ID é auto gerado
        var resultSet = tx.executeSql("INSERT OR REPLACE INTO Contact(name, phone, email) VALUES (?, ?, ?)", [name, phone, email]);
        callback(resultSet.insertId); // Retorna o id gerado para o novo usuário como parâmetro da callback
    });
}

// Retorna a informação sobre um contato cujo id é passado como parâmetro
function getContactInfo(id, callback, errorCallback) {
    db.trasaction(function (tx) {
        var resultSet = tx.executeSql("SELECT * FROM Contacts WHERE id = ?", [id]);
        if (resultSet.rows.length &gt; 0) {
            // A função resultSet.rows.item retorna um array JS com chaves
            // sendo o nome das colunas e os valores os dados das colunas
            callback(resultSet.rows.item(0));
        } else {
            errorCallback();
        }
    });
}</pre>
<p>Isso nos permite utilizar as informações do BD no QML sem misturar QML com SQL diretamente:</p>
<pre class="brush:js">import QtQuick 1.0
import "db.js" as DB

Column {
    property int contactId
    property string name
    property string email
    property string phone

    width: 300; height: 90

    onContactIdChanged: {
        // A variável DB referencia o módulo Javascript
        DB.getContactInfo(contactId, function (info) {
            name = info.name;
            email = info.email;
            phone = info.phone;
        });
    }

    Text { text: name; height: 30 }
    Text { text: email; height: 30 }
    Text { text: phone: height: 30 }
}</pre>
<h2>Migração entre esquemas</h2>
<p>Suponha, que sua aplicação já está em uso, e agora você precisa suportar vários telefones para cada contato. Para fazer isso de maneira que o esquema do BD seja atualizado e os dados não sejam perdidos. Isso é importante, em ambientes onde você não tem acesso direto a maquina para executar backups ou algo do gênero, como por exemplo aplicativos publicados na Nokia Store. Para isso, a API de offline storage define uma maneira de executar migrações a partir do versionamento dos esquemas. O objeto do tipo database já provê um método (changeVersion) que nos ajuda a atualizar os metadados do banco e chamar a função responsável pela migração dos esquemas. Essa função será utilizada da seguinte forma:</p>
<pre class="brush:js">// Versão vazia significa, pegar a versão mais atual
var db = openDatabaseSync("Contacts", "", "Contact list database", 5*1024*1024);

// Caso não exista a versão será uma string vazia
if (db.version == '') {
    db.changeVersion('','1.1', create_scheme_1_1);
} else if (db.version ==  '1.0') {
    db.changeVersion('1.0','1.1', migrate_scheme_1_0_to_1_1);
}</pre>
<p>Isso nos permite identificar a versão atual e chamar o procedimento correto para tratar a criação ou migração do esquema, já passando a transação como parâmetro. Da seguinte forma:</p>
<pre class="brush:js">function create_scheme_1_1(tx) {
    tx.executeSql("CREATE TABLE IF NOT EXISTS Contacts ( \
        id INTEGER PRIMARY KEY AUTOINCREMENT, \ // Criando chave primária automática
        name STRING, \
        email STRING, \
        UNIQUE (name) ON CONFLICT REPLACE)"); // Essa restrição impede que dois contatos tenham o mesmo nome

    tx.executeSql("CREATE TABLE IF NOT EXISTS ContactsPhones ( \
        contact_id INTEGER, \ // Criando chave primária automática
        phone STRING, \
        FOREIGN KEY (contact_id) REFERENCES Contacts(id))");
}

function migrate_scheme_1_0_to_1_1(tx) {
    // Cria tabela auxiliar para armazenar multiplos telefones por usuário
    tx.executeSql("CREATE TABLE IF NOT EXISTS ContactsPhones ( \
        contact_id INTEGER, \
        phone STRING, \
        FOREIGN KEY (contact_id) REFERENCES Contacts(id))");

    // Move os dados para a nova tabela
    tx.executeSql("INSERT INTO ContactsPhones (contact_id, phone) SELECT id, phone FROM Contacts");
}</pre>
<p>É importante notar que não é possível remover colunas no SQLite, e que o desenvolvedor terá que tomar a decisão de conviver com uma coluna desenecessária ou criar uma nova tabela com as informação necessárias. No caso do último, é importante ter um pouco mais de conhecimento sobre SQL para fazer renomeação de tabelas e alteração de tabelas.</p>
<p>Por termos um esquema diferente, é importante atualizar as consultas realizadas. Daí a importancia de termos uma API como interface para abstraírmos o código das consultas do restante da aplicação, e termos que alterar as consultas apenas em alguns pontos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qtlabs.org.br/2011/11/11/offline-storage-em-qml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qt Project foi lançado!</title>
		<link>http://blog.qtlabs.org.br/2011/10/21/qt-project-foi-lancado/</link>
		<comments>http://blog.qtlabs.org.br/2011/10/21/qt-project-foi-lancado/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 14:18:30 +0000</pubDate>
		<dc:creator>Anselmo L. S. Melo</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[Qt-project]]></category>
		<category><![CDATA[Qt5]]></category>
		<category><![CDATA[opengovernance]]></category>
		<category><![CDATA[qt-project]]></category>
		<category><![CDATA[qt5]]></category>

		<guid isPermaLink="false">http://blog.qtlabs.org.br/?p=786</guid>
		<description><![CDATA[<br/>Tradução do post de Lars Knoll em http://labs.qt.nokia.com/2011/10/21/the-qt-project-is-live/, Portanto, toda referência feita em primeira pessoa deve ser interpretada como um ponteiro para o autor do texto original. &#8211; Estou feliz em anunciar que o Qt Project oficialmente lançado hoje. A partir de hoje, o desenvolvimento de Qt será governado como um verdadeiro projeto open source. Agora [...]]]></description>
			<content:encoded><![CDATA[<p></p><br/><p>Tradução do post de <a href="http://labs.qt.nokia.com/author/lars/">Lars Knoll</a> em <a href="http://labs.qt.nokia.com/2011/10/21/the-qt-project-is-live/">http://labs.qt.nokia.com/2011/10/21/the-qt-project-is-live/</a>, Portanto, toda referência feita em primeira pessoa deve ser interpretada como um ponteiro para o autor do texto original.</p>
<p>&#8211;</p>
<p>Estou feliz em anunciar que o Qt Project oficialmente lançado hoje. A partir de hoje, o desenvolvimento de Qt será governado como um verdadeiro projeto <em>open source</em>.</p>
<p>Agora temos <a href="http://qt-project.org/">qt-project.org</a> – um <em>website</em> que centralizará todo o desenvolvimento de Qt, provendo a mesma infra-estrutura e processos para todos que desejem contribuir com Qt.</p>
<h2>Agora que estamos aqui, o que vem em seguida?</h2>
<p>Se você está interessado em participar e tornar-se parte da comunidade Qt,  o primeiro lugar para olhar é o <em>website</em> <a href="http://qt-project.org/">qt-project.org</a>. Essa página oferece uma visão geral de como começar e como você pode tornar-se parte da comunidade e contribuir com Qt.</p>
<p>Se você já trabalha com Qt, provavelmente já possui uma conta no <a href="https://bugreports.qt.nokia.com/">Jira</a>, nossa ferramenta de rastreamento de <em>bugs</em>. Essa conta é necessária para acessar o local onde todo o desenvolvimento acontece: <a href="http://codereview.qt-project.org/">codereview.qt-project.org</a>.</p>
<p>Nosso servidor Gerrit em <a href="http://codereview.qt-project.org/">codereview.qt-project.org</a> funcionará como o ponto central para onde os <em>patches</em> enviados, revisados e testados. Todos os que possuem conta Jira podem submeter <em>patches</em> para revisão como <em>Contributor</em>.</p>
<p><em>Patches</em> podem ser revisados por qualquer um e finalmente aceitos ou rejeitados por <em>Approvers</em> e <em><a href="http://developer.qt.nokia.com/wiki/Maintainers">Maintainers</a></em>. Você notará que nós já temos alguns não-Nokians como <em>Approvers</em> e <em>Maintainers</em>. Eu gostaria de mencionar especialmente que Thiago, o mantenedor de QtCore (a biblioteca que todos utilizam), não está trabalhando para a Nokia. Esta é a mais tangível evidência do que a governaça aberta significa. Eu espero ver ainda mais não-Nokians tornando-se <em>Approvers</em> e <em>Maintainers</em> no futuro.</p>
<p>Para detalhes sobre como contribuir, por favor visite <a href="http://www.qt-project.org/">www.qt-project.org</a>.</p>
<p>Por enquanto nós temos apenas algumas listas de e-mails disponíveis em <a href="http://lists.qt-project.org/">lists.qt-project.org</a>, mas espero que isso mude e que vejamos listas especializadas surgirem conforme avançamos. A lista mais importante é a de desenvolvimento geral <a href="http://lists.qt-project.org/mailman/listinfo/development">development@qt-project.org</a>. Observe que essa lista também é parte de <a href="http://lists.qt-project.org/mailman/listinfo/announce">announcement mailing list</a>, portanto você automaticamente receberá tais e-mails.</p>
<p>Nós continuaremos a utilizar Jira para rastrear <em>bugs</em> e requisitos. A instalação corrente em <a href="http://bugreports.qt.nokia.com/">bugreports.qt.nokia.com</a> também será movida nas próximas semanas para o Qt Project.</p>
<h2>Abertura real</h2>
<p>Qt é um projeto <em>open source</em> real. Nós estamos convidando a todos para participarem e ajudarem a tornar Qt um produto cada vez melhor.</p>
<p>Todo o desenvolvimento acontecerá em um local central, com acesso aberto a todos ao mesmo tempo. Sem mais fluxos de código separados para “Nokians vs outros”, e sem mais atrasos! O que você vê é o que está de fato acontecendo. Discussões, decisões e <em>roadmapping</em> acontecerão todos na comunidade, pela comunidade e para a comunidade. Todos podem ser <em>Contributor</em>, e até mesmo <em>Approver </em>ou <em>Maintainer</em> se demonstrarem mérito suficiente.</p>
<h2>Converse conosco sobre a governança aberta no Qt Developer Days</h2>
<p>Apresentações sobre Qt Project e governança aberta acontecerão no Qt Developer Days, e também falarei a respeito em meu keynote. Se você vai ao evento, terá a oportunidade de aprender e participar das dicussões. Se você está considerando ir ao Dev Days, essa discussão é um dos vários bom motivos para decidir ir!</p>
<h2>Conclusões e agradecimentos</h2>
<p>Estou extremamente feliz em ver que essa mudança finalmente aconteceu. Gostaria de aproveitar a oportunidade para agradecer todos aqueles que ajudaram para concretizar isso. Há várias pessoas que contribuíram, mas algumas devem ser mencionadas: Thiago Macieira por ter conduzido os trabalhos iniciais a respeito da governança aberta, Marius Storm-Olsen por assumir muito desse trabalho, Cristy Hamley por cuidar das questões legais, e Olivia Puntanen por gerenciar o projeto. Obrigado a todos.</p>
<p>Estou muito ansioso para começar um novo capítulo no desenvolvimento de Qt, animado para trabalhar com todos vocês no sentido de tornar Qt um produto ainda melhor.</p>
<p>&#8212;</p>
<p>Nota da tradução: Os termos <em>Contributor, <em>Approver </em></em>e <em><em><em>Maintainer</em></em></em> &#8211; contribuidor, aprovador e mantenedor, respectivamente &#8211; foram mantidos em Inglês no corpo do texto apenas para fins didáticos a respeito da nova estrutura do projeto, uma vez que esses são os termos que os interessados encontrarão ao ler o site oficial do projeto.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qtlabs.org.br/2011/10/21/qt-project-foi-lancado/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>QML + RESTful Web Services</title>
		<link>http://blog.qtlabs.org.br/2011/10/07/qml-restful-web-services/</link>
		<comments>http://blog.qtlabs.org.br/2011/10/07/qml-restful-web-services/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 21:18:39 +0000</pubDate>
		<dc:creator>Daker Pinheiro</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[QML]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[qml]]></category>
		<category><![CDATA[restful]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.qtlabs.org.br/?p=714</guid>
		<description><![CDATA[<br/>RESTful Web Services Web Services é uma forma de comunicação entre dispositivos através da uma rede. Existem diversos padrões de comunicação que utilizam várias tecnologias e outros padrões já existentes na Web para fazer tal comunicação entre processos. Atualmente uma dos padrões mais populares é o Representational State Transfer (REST) que, em linhas gerais, define [...]]]></description>
			<content:encoded><![CDATA[<p></p><br/><h2><em>RESTful Web Services</em></h2>
<p><a href="http://pt.wikipedia.org/wiki/Webservices"><em>Web Services</em></a> é uma forma de comunicação entre dispositivos através da uma rede. Existem diversos padrões de comunicação que utilizam várias tecnologias e outros padrões já existentes na Web para fazer tal comunicação entre processos. Atualmente uma dos padrões mais populares é o <a href="http://pt.wikipedia.org/wiki/REST"><em>Representational State Transfer</em> (REST)</a> que, em linhas gerais, define que a comunicação utiliza o <a href="http://pt.wikipedia.org/wiki/Http">HTTP</a> como transporte das chamadas remotas, uma convenção sobre as URIs, além de não preservar estado entre as transações/requisições. Existe uma infinidade de <em>Web Services</em> que utilizam essa padronização para disponibilizar dados e serviços tais como o Flickr, Facebook, Google Maps, Google+, IMDB, What&#8217;s for Dinner, Yahoo Weather entre diversos outros. A maioria das aplicações atuais utilizam esses e outros serviços como extensões da aplicação para que essas informações fiquem conectadas e seja mais fácil compartilhar e consumir dados. Efeitos da Web 2.0.</p>
<p>O conjunto de requisições, buscas, consultas e operações que podemos executar, definem a API REST do serviço web. Esses serviços disponibilizam alguma documentação sobre quais operações estão definidas e que tipos de dados devem ser utilizados. Em geral, essas transações utilizam XML ou<em> Javascript Object Notation</em> (ou JSON) para fazer representar os dados a serem transmitidos.</p>
<h2>JSON</h2>
<p>O <a href="http://json.org/">JSON</a> nada mais é do que uma forma de representar informações semi estruturadas, podendo ser aplicado como substituto do XML em qualquer aplicação. A grande vantagem do JSON é consumir menos espaço, por ser menos verboso, que o XML além da maior facilidade de manipulá-lo já que se parecem com estruturas de várias linguagens além do próprio Javascript, como por exemplo Python e Ruby. Por isso é mais vantajoso onde há a necessidade de reduzir o tamanho da representação, como por exemplo na serialização de informações estruturadas em aplicações web. Além disso, muitas pessoas consideram o JSON mais legível que o XML. É exatamente nesse cenário que o JSON tem ganhado popularidade. É pouco conhecido, que o JavascriptCore &#8211; engine responsável por executar o Javascript presente no QML &#8211; já tem um parser e serializador de objetos JSON, tornando o seu uso ainda mais natural em aplicações QML.</p>
<h2>AJAX</h2>
<p>Outro recurso extensivamente utilizada nas páginas web modernas, é a comunicação assíncrona com o servidor através do Javascript. Essa técnica é popularmente chamada de <a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29"><em>Asynchronous Javascipt and XML</em></a> (AJAX), que apesar de levar XML no nome continua sendo utilizada para descrever requisições assíncronas ao servidor mesmo não utilizando XML como camada de apresentação dos dados. A grande vantagem do AJAX é permitir que o browser execute outras atividades enquanto uma dada requisição é feita ao servidor, que toma preciosos milisegundos apenas esperando a resposta da requisição. O JavascriptCore implementa um tipo chamado <a href="http://www.w3.org/TR/XMLHttpRequest/">XmlHttpRequest</a> que é utilizado para fazer as requisições AJAX. Quando a resposta do servidor chega ao browser, uma função de <em>callback</em> é chamada (setada através da propriedade <em>onreadystatechange</em> de um objeto XmlHttpRequest) e executa a rotina que vai lidar com a resposta do servidor. Uma <em>callback</em> é uma função que será chamada quando uma dada ação ocorrer. Na web você pode encontrar várias implementações de referência de chamadas AJAX além de abstrações de diversos frameworks Javascript. No nosso caso vamos criar nossa própria abstração utilizando apenas o XmlHttpRequest. A função getHttpJson receberá uma URL do recurso a ser requisitado (através do método GET do HTTP) e uma <em>callback</em> a ser executada quando houver uma resposta:</p>
<pre class="brush:js">function getHttpJson(request_url, callback)
{
    // Criação do XmlHttpRequest para realizar a requisição AJAX
    var request = new XMLHttpRequest();

    // O seguintes parâmetros recebem respectivamente:
    // 1 - Método HTTP a ser realizado
    // 2 - URL requisitada
    // 3 - Define se a chamada será executada assíncronamente
    request.open("GET", request_url, true);

    // Callback da requsição AJAX
    request.onreadystatechange = function () {
        // A callback 'onreadystatechange' sempre é chamado a qualquer atualização do status da requisição
        // O valor 4 do readyState simboliza que a requisição foi fializada
        // O status simboliza o status retornado no cabeçalho de resposta do HTTP, onde o valor 200 simboliza sucesso
        if (request.readyState == 4 &amp;&amp; request.status == 200) {

            // O objeto JSON faz parte da imlementação JavascriptCore
            // O 'responseText' contém o conteúdo da resposta da requisição
            var json = JSON.parse(request.responseText);

            // Chamada à callback real que está sendo encapsulado pelo getHttpJson
            callback(json);
        }
    }

    // Caso exista alguma informação a ser enviada no corpo da requisição HTTP, ela deve ir como parâmetro do send
    request.send();
}</pre>
<p>Essa abstração nos permite passar uma URL e uma <em>callback</em>, que nos retornará um objeto do tipo Array do Javascript (com as informações do JSON) como parâmetro dessa <em>callback</em>. É importante ressaltar que para o caso básico de acesso de recursos essa função é suficiente, porém pode será necessário incrementar o código acima para poder lidar com requisições mais complexas, que por exemplo, chame uma outra <em>callback</em> caso a requisição falhe ou ainda utilizar os demais métodos do HTTP na API RESTful.</p>
<h2>QML + !!</h2>
<p>O famoso site de tirinhas <a href="http://xkcd.com">XKCD </a>por exemplo, oferece uma <a href="http://xkcd.com/json.html">API web RESTful</a> para ler as tirinhas publicadas no site. Essa API é muito simples se comparada a outras APIs mas já nos permite fazer um leitor de tirinhas. Na especificação, a url <a href="http://xkcd.com/614/info.0.json">http://xkcd.com/303/info.0.json</a> nos permite retornar informações sobre a tirinha com id &#8220;303&#8243;. Dessa forma podemos fazer um <em>wrapper</em> mais elegante para nossa aplicação. Como exempl, considere a seguinte função, que abstrai qual esquema de construção da URL está sendo utilizada e se foca apenas nos parametros necessários (o numero da tirinha) e a <em>callback</em> que vai lidar com a resposta:</p>
<pre class="brush:js">function getXkcdComic(num, callback) {
    getHttpJson("http://xkcd.com/" + num + "/info.0.json", callback);
}</pre>
<p>Se formos inspecionar o objeto JSON retornado pela chamada podemos fazer da seguinte forma:</p>
<pre class="brush:js">getXkcdComic(303, function(json) {
    var responseText = JSON.stringify(json); // Reserializando para Json para fins de demontração
    console.debug(responseText); // Imprimindo resposta no console de debug
});</pre>
<p>obteremos a seguinte linha impressa no console de debug:</p>
<pre class="brush:js">{"img": "http://imgs.xkcd.com/comics/woodpecker.png", "title": "Woodpecker", "month": "7", "num": 614, "link": "", "year": "2009", "news": "", "safe_title": "Woodpecker", "transcript": "[[A man with a beret and a woman are standing on a boardwalk, leaning on a handrail.]]\nMan: A woodpecker!\n&lt;&lt;Pop pop pop&gt;&gt;\nWoman: Yup.\n\n[[The woodpecker is banging its head against a tree.]]\nWoman: He hatched about this time last year.\n&lt;&lt;Pop pop pop pop&gt;&gt;\n\n[[The woman walks away.  The man is still standing at the handrail.]]\n\nMan: ... woodpecker?\nMan: It's your birthday!\n\nMan: Did you know?\n\nMan: Did... did nobody tell you?\n\n[[The man stands, looking.]]\n\n[[The man walks away.]]\n\n[[There is a tree.]]\n\n[[The man approaches the tree with a present in a box, tied up with ribbon.]]\n\n[[The man sets the present down at the base of the tree and looks up.]]\n\n[[The man walks away.]]\n\n[[The present is sitting at the bottom of the tree.]]\n\n[[The woodpecker looks down at the present.]]\n\n[[The woodpecker sits on the present.]]\n\n[[The woodpecker pulls on the ribbon tying the present closed.]]\n\n((full width panel))\n[[The woodpecker is flying, with an electric drill dangling from its feet, held by the cord.]]\n\n{{Title text: If you don't have an extension cord I can get that too.  Because we're friends!  Right?}}", "alt": "If you don't have an extension cord I can get that too.  Because we're friends!  Right?", "day": "24"}</pre>
<p>que por sua vez não é tão legível. Recomendo fortemente o uso de alguma ferramenta de visualização de objetos JSON tais como o <a href="http://jsonviewer.stack.hu/">Online JSON Viewer</a> que ajudam a visualizar os dados e sua estrutura.</p>
<p>Com tais dados e funções utilitárias, fica fácil criar um leitor do XKCD que utiliza a API RESTful do XKCD. Recomendo agregar essas funções relativas a comunicação com o servidor em um arquivo Javascript separado para que a implementação fique distinta de seu uso no QML. Aqui vou chamar esse arquivo de &#8220;xkcd.js&#8221;. O seguinte código cria um leitor do XKCD bem simples e utiliza o &#8220;xkcd.js&#8221; com o alias XKCD, de modo que podemos chamar as funções definidas no arquivo Javascript através desse objeto.</p>
<pre class="brush:js">import QtQuick 1.0
import "xkcd.js" as XKCD

Rectangle {
    id: comicViewer

    property int num // Número da tirinha
    property url image // Imagem da tirinha
    property string title // Título da tirinha
    property string alt // Texto alternativo da tirinha (sarcasmo do XKCD)

    width: 300
    height: 300
    color: "white" 

    // Retorna as informações do servidor toda vez que o numero do quadrinho
    // é alterado
    onNumChanged: {
        XKCD.getXkcdComic(num, function (json) {
            comicViewer.image = json.img;
            comicViewer.title = json.title;
            comicViewer.alt = json.alt;
        });
    }

    // Troca o número da tirinha atual imediatamente após a incialização do
    // componente atual
    Component.onCompleted: comicViewer.num = 303;

    // Imagem da tirinha
    Image {
        id: comicImage
        anchors {
            fill: parent
            margins: 50
        }
        source: image
        fillMode: Image.PreserveAspectFit
        smooth: true
    }

    // Mostra o título sobre a tirinha
    Text {
        anchors {
            horizontalCenter: comicImage.horizontalCenter
            bottom: comicImage.top
        }
        text: title
        font.pixelSize: 30
    }

    // Mostra o texto alternativo abaixo da tirinha
    Text {
        anchors {
            top: comicImage.bottom
            bottom: parent.bottom
            left: parent.left
            right: parent.right
        }
        text: alt
        horizontalAlignment: Text.AlignHCenter
        wrapMode: Text.WordWrap
    }

    // Área esquerda da tela quando clicada vai para a tirinha anterior
    MouseArea {
        anchors {
            left: parent.left
            right: parent.horizontalCenter
            top: parent.top
            bottom: parent.bottom
        }
        onClicked: num -= 1;
    }

    // Área direita da tela quando clicada vai para a próxima tirinha
    MouseArea {
        anchors {
            right: parent.right
            left: parent.horizontalCenter
            top: parent.top
            bottom: parent.bottom
        }
        onClicked: num += 1;
    }
}</pre>
<p>Para testar esse exemplo, basta salvá-lo como, por exemplo &#8220;xkcd.qml&#8221; e abrí-lo com <em>qmlviewer </em>ou carregar em uma QDeclarativeView..</p>
<div id="attachment_735" class="wp-caption aligncenter" style="width: 502px">
	<a href="http://blog.qtlabs.org.br/wp-content/uploads/2011/10/xkcd.png"><img class="size-full wp-image-735" title="xkcd" src="http://blog.qtlabs.org.br/wp-content/uploads/2011/10/xkcd.png" alt="Visualizador de tirinhas XKCD feito em QML" width="502" height="487" /></a>
	<p class="wp-caption-text">Visualizador de tirinhas do XKCD feito em QML</p>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.qtlabs.org.br/2011/10/07/qml-restful-web-services/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

