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 1As 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 2O 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
[email protected]
Este artigo no nosso site:
http://lnm.com.br/article/3387
77
Download

Qt animado - Linux Magazine