Page 1

Testando novos recursos do KDE 4.4

PROGRAMAÇÃO

Qt animado

James Thew – Fotolia

O Qt 4.6 apresenta uma coleção de novos recursos ao KDE 4.4. Conheça o framework de animação e o novo recurso multi-touch do KDE. por Johan Thelin

O

desktop KDE e o framework Qt são desenvolvidos de forma independente, mas paralela. As necessidades do KDE resultam em novos recursos para o Qt, que por sua vez levam rapidamente a novos recursos no KDE. A última versão 4.6 do Qt traz novos recursos que estão invadindo todos os ambientes KDE pelo mundo. Muitos destes recursos serão vistos no KDE 4.4. Muitas mudanças no KDE 4.4 concentram-se na melhora da experiência do usuário. Por exemplo, a bandeja do sistema recebeu grande atenção e, nesta era de redes sociais, estreia o cliente de bloga Blogilo. Este artigo apresenta algumas novidades disponíveis no KDE 4.4. Especificamente, ele mostra um exemplo prático de como usar o framework de animação do Qt e descreve o cenário de integração da 74

tecnologia multi-touch. A menos que você seja um programador do KDE, não precisará interagir diretamente com esses componentes, mas uma simples olhada nos bastidores para ver como tudo funciona oferecerá um contexto para compreender a nova geração de efeitos especiais que logo começarão a aparecer em atualizações futuras de seu aplicativo favorito do KDE.

Framework de animação O grande foco do KDE 4.4 é oferecer uma experiência de uso mais suave e bem-acabada. Parte deste trabalho tem sido feito com transições de animação – por exemplo, passar o mouse pelos botões de uma janela faz com que eles se apaguem e se acendam, em vez de simplesmente mudar de estado.

Outra área do KDE onde a suavidade é uma prioridade é o desktop Plasma. O objetivo é simplificá-lo para que os desenvolvedores adicionem animações e efeitos, o que, por sua vez, tornará o uso do KDE mais intuitivo para o usuário. No Qt 4.6, isso é abordado por meio de um framework de animação novo em folha, baseado na classe QAbstractAnimation. Durante o desenvolvimento do Qt 4.6, este framework ficou conhecido por Qt Kinetic. O framework de animação está centrado no conceito de propriedades de animação. A animação não se limita ao movimento, rotação e redimensionamento, mas também está relacionada à transparência e cor. Qual a aparência de tudo isso do ponto de vista do desenvolvedor? Para começar, o desktop plasmoid é montado em torno das classes de visualizações gráficas.

http://www.linuxmagazine.com.br


Qt | PROGRAMAÇÃO

Como exemplo do funcionamento de tudo isso, vamos animar uma sequência de itens gráficos em uma cena. O código-fonte que importa para este exemplo é mostrado na listagem 1. Ele descreve duas animações diferentes de dois widgets mostrados por meio de visualizações gráficas. A janela resultante, sem os efeitos, é mostrada na figura 1. A listagem 1 Mostra o construtor do widget de visualização, que herda qgraphicsview. A classe qgraphicsview é usada para mostrar o conteúdo de qgraphicsscene. O conteúdo das cenas é montado a partir de objetos qgraphicsitem. A linha 4 Simplesmente estabelece a visualização, com anti-alias para suavizar os pixels ao máximo. Isso garante a melhor qualidade da

imagem, com um custo computacional que pode ser suportado pela maioria dos computadores desktop. As linhas 6 e 7 criam uma cena e certificam-se de que ela será mostrada no visualizador. A cena é retangular, com 200 pixels de largura e altura da coordenada (-100,-100). Caso nenhum retângulo de cena seja especificado, a cena crescerá conforme o necessário – fazendo com que a animação mude as dimensões da cena. Isso, por outro lado, resultará no acréscimo de slides ou na movimentação do conteúdo – o que precisamos evitar. As linhas 9 a 11 criam o primeiro item da cena. Um item pode ser qualquer coisa – um bitmap, um desenho SVG, uma forma básica, como um retângulo ou um círculo,

Figura 1 As duas animações em ação.

ou até mesmo um conteúdo gerado por código. Neste exemplo, embarcamos um widget considerado pesado e não recomendado quando o desempenho entra em questão. No entanto, desejamos ter acesso ao símbolo clicável para poder atuar com eventos do mouse. Isso pode ser feito utilizando um item que não seja um widget, mas que exija que o item esteja em uma subclasse

Listagem 1: Animação 01 ViewWidget::ViewWidget(QWidget *parent) 02 : QGraphicsView(parent) 03 { 04 setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform) 05 06 QGraphicsScene *scene = new QGraphicsScene(-100-100200200this) 07 setScene(scene) 08 09 QPushButton *blurButton = new QPushButton(“Blur”) 10 QGraphicsProxyWidget *blurItem = scene->addWidget(blurButton) 11 blurItem->setPos(-blurButton->width()/2-10-blurButton->height()) 12 QGraphicsBlurEffect *blurEffect = new QGraphicsBlurEffect(this) 13 blurEffect->setBlurRadius(0) 14 blurItem->setGraphicsEffect(blurEffect) 15 16 QPushButton *rotateButton = new QPushButton(“Rotation”) 17 QGraphicsProxyWidget *rotateItem = scene->addWidget(rotateButton) 18 rotateItem->setPos(-rotateButton->width()/210) 19 rotateItem->setTransformOriginPoint( rotateButton->width()/2rotateButton->height()/2) 20 21 QPropertyAnimation *blurAnimation = new QPropertyAnimation(blurEffect”blurRadius”this) 22 blurAnimation->setStartValue(0.0) 23 blurAnimation->setKeyValueAt(0.510.0) 24 blurAnimation->setEndValue(0.0) 25 blurAnimation->setDuration(1500) 26 connect(blurButtonSIGNAL(clicked())blurAnimationSLOT(start())) 27 28 QPropertyAnimation *rotateAnimation = new Q PropertyAnimation(rotateItem”rotation”this) 29 rotateAnimation->setStartValue(0.0) 30 rotateAnimation->setEndValue(360.0) 31 rotateAnimation->setDuration(2000) 32 rotateAnimation->setEasingCurve(QEasingCurve::OutBounce) 33 connect(rotateButtonSIGNAL(clicked())rotateAnimationSLOT(start())) 34 }

Linux Magazine #65 | Abril de 2010

75


PROGRAMAÇÃO  | Qt

Listagem 2: Pulsação 01 Animation *pulseAnimation = Animator::create(Animator::PulseAnima tion) 02 pulseAnimation->setWidgetToAnimate(button) 03 connect(buttonSIGNAL(clicked())pulseAnimationSLOT(start()))

e perceba o evento de pressionar o botão do mouse. O botão é instanciado e adicionado à cena, que o colocará automaticamente dentro de QGraphicsProxyWidget. Esta classe cuida de todos os detalhes de passar eventos e desenhar operações entre o widget e a cena gráfica. Quando o botão é adicionado, a chamada a setPos centraliza o botão e o posiciona ligeiramente acima do centro. Entre as linhas 12 e 14, uma das qualidades do Qt 4.6 entra em cena: os efeitos gráficos. A última versão do Qt permite que o desenvolvedor adicione efeitos gráficos a qualquer widget ou item. Os efeitos padrão que já vêm no Qt são blur (borrar, desfocar), colorize (colorizar), drop shadow (sombra projetada) e add opacity (adicionar opacidade). Caso estes não sejam suficientes, é possível criar efeitos personalizados, além de combinar os já existentes. No código-fonte, o efeito blur é aplicado ao item proxy que sustenta o widget. No entanto, o raio de desfocagem está configurado para

Figura 2 O widget pinch em ação.

76

zero, portanto, a princípio, o efeito não será visto. As linhas 16 a 19 se dedicam a adicionar outro botão à cena com quase o mesmo código usado para o primeiro botão. Este botão aparece abaixo do primeiro. Por padrão, o ponto de origem de transformação se localiza no canto superior esquerdo, mas neste exemplo, ele está centralizado no meio do botão. O texto do botão é Rotation (Rotação), o que mostra por que é importante a mudança do ponto de origem. A rotação fica melhor se seu eixo estiver no centro e não no canto superior esquerdo do botão. Após criar os dois botões, já é possível começar a olhar as classes de animação. A linha 21 mostra a ideia por trás da nova classe de propriedade de animação. Dado um objeto alvo (neste caso, blureffect) e uma propriedade para a animação, (blurradius), a o animador já pode entrar em ação. Sobram apenas alguns dados sobre como a propriedade deve se alterar com o tempo. Em todas as animações, um valor de tempo varia entre zero e um. Nas linhas 22 a 24, os valores de início e fim são especificados, além do valor de 5.0 para o tempo de 0.5 – isto é, na metade do caminho. O resultado é que o raio da desfocagem aumenta de zero a cinco e depois volta para o zero. A linha 25 define quanto tempo levará esse processo: um segundo e meio. As linhas 28 a 31 definem outra animação para a propriedade de rotação do outro botão. O botão faz um círculo completo durante dois segundos. No entanto, a linha 32 Define uma curva suavizada, que

descreve como o valor do tempo da animação deve ir de 0 a 1. Neste caso, foi usado outbounce, o que significa que a rotação terminará com um leve balanço. Isso deixará a animação mais interessante do que uma simples rotação. Faça uma pausa na linha 33 (a última) para ver como o framework de animação se encaixa nas classes de efeitos gráficos. Além disso, perceba que a configuração da cena exigiu a mesma quantidade de código que a configuração da animação. No KDE 4.4, há muito mais recursos para animação. Há animações prontas para usar em plasmoids. Por exemplo, para fazer um item pulsar, basta usar o animador para criar a animação de pulsação, aplicar um widget a ela e conectá-la a um sinal inicial, como na listagem 2.

Multi-touch

Outra tecnologia que finalmente aparece no Qt e no KDE é a multitouch. Popularizada nos telefones, a tecnologia multi-touch alcançou os tablet PCs e o software de desktop. A tecnologia multi-touch permite que o usuário opere um dispositivo com tela sensível ao toque usado dois ou mais dedos simultaneamente. A inclusão do multi-touch apresenta dois problemas ao desenvolvedor. Em primeiro lugar, múltiplas partes da interface do usuário podem ser alteradas pelo usuário ao mesmo tempo – como se houvesse múltiplos cursores de mouse – o que limita o número de suposições que podem ser feitas quando os widgets dependem uns dos outros. Esse problema não pode ser resolvido com o Qt nem com o KDE; em vez disso, cada desenvolvedor de aplicativos deve considerar as implicações antes de habilitar o suporte a multi-touch. Em segundo lugar, interpretar o que múltiplos pontos de toques querem dizer fica a cargo dos gestos, que permitem que o Qt interprete

http://www.linuxmagazine.com.br


Qt | PROGRAMAÇÃO

os movimentos de toque. Os gestos podem ser considerados em uma API de alto nível, o que é muito mais fácil do que tentar decodificar e interpretar manualmente a interação entre múltiplos pontos de toque. A listagem 3 inclui a melhor parte da classe PinchWidget (figura 2), em que o retângulo é dimensionado e rodado com o gesto de pinça (pinch). O retângulo escuro representa a localização original antes da rotação e do redimensionamento. O gesto de pinça é o que usa dois dedos e que fez a fama do iphone. Separe os dedos para aproximar e junte-os para afastar. Rodando os dedos, a imagem é rotacionada. O pinchwidget faz tudo isso, mas em um retângulo simples. Fora da listagem, no construtor PinchWidget, é feita uma chamada a grabGesture (Qt::PinchGesture). Sem essa chamada, o widget não receberá nenhum evento de gesto. Quando o gesto for captado, o programa pode interceptá-lo como um evento. O método do evento (linhas 1 a 6 na listagem 3) interpreta os eventos de gestos e os passa para o método gestureevent (linhas 8 a 16) que, por sua vez, determina se o gesto é uma pinça. Em caso afirmativo, ele irá passá-lo para o método pinchgesture. O método pinchgesture (linhas 18 a 37) interpreta o gesto e atualiza o estado do widget conforme o necessário. A classe qpinchgesture sabe o que foi alterado, que é usado no primeiro if (linha 21) para testar se o ângulo de rotação foi mudado. Em caso positivo, o programa atualiza a variável rotationangle. Se o tamanho do objeto tiver mudado (linha 27), o programa atualiza o currentscalefactor (o resultado da operação atual de redimensionamento). A declaração if na linha 31 verifica se o gesto foi concluído. Em caso positivo, atualiza-se o scaleFactor e altera-se o currentScaleFactor para 1 para prepará-lo para o próximo gesto.

Linux Magazine #65 | Abril de 2010

Listagem 3: Classe PinchWidget 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

bool PinchWidget::event(QEvent *event) { if(event->type() == QEvent::Gesture) return gestureEvent(static_cast<QGestureEvent*>(event)) return QWidget::event(event) } bool PinchWidget::gestureEvent(QGestureEvent *event) { if(QGesture *pinch = event->gesture(Qt::PinchGesture)) { pinchGesture(static_cast<QPinchGesture*>(pinch)) return true } return false } void PinchWidget::pinchGesture(QPinchGesture *gesture) { QPinchGesture ::ChangeFlags flags = gesture->changeFlags() if(flags & QPinchGesture::RotationAngleChanged) { qreal value = gesture->rotationAngle() qreal lastValue = gesture->lastRotationAngle() rotationAngle += value - lastValue } if(flags & QPinchGesture::ScaleFactorChanged) { currentScaleFactor = gesture->scaleFactor() } if(gesture->state() == Qt::GestureFinished) { scaleFactor *= currentScaleFactor currentScaleFactor = 1 } update() }

Independentemente do que ocorre depois, o programa pinça novamente o widget na linha 36.

Conclusão

Trabalhar com estes eventos será cada vez mais importante para novos aplicativospois os dispositivos de entrada estão se atualizando. No entantopara os desenvolvedores do KDEas coisas não precisam ser tão

complicadas. Por exemplotodos os plasmoids podem ser tocados para rotação e redimensionamento. Além do pincho Qt 4.6 também dispõe do panning – isto éo scrolling com toque (por exemplopara navegar entre imagens) – e o swiping. Todos esses gestos estão disponíveis aos desenvolvedores de aplicativos do KDE eem última instânciapara os usuários.  n

Gostou do artigo? Queremos ouvir sua opinião. Fale conosco em cartas@linuxmagazine.com.br Este artigo no nosso site: http://lnm.com.br/article/3387

77

http://www.linuxmagazine.com.br/images/uploads/pdf_aberto/LM_65_74_77_45_prog_qt  

http://www.linuxmagazine.com.br/images/uploads/pdf_aberto/LM_65_74_77_45_prog_qt.pdf