Qt und KDE entstehen unabhängig voneinander, gehen jedoch eine symbiotische Beziehung ein. Was KDE-Anwender wollen, resultiert in neuen Qt-Funktionen. Und mit den Neuerungen der jüngsten Qt-Release [1] wird sich auch das KDE-Projekt neue Features ausdenken. Die meisten Verbesserungen in Qt betreffen das Anwender-Erlebnis. Ein Blick auf die technische Seite offenbart, was Entwickler mit zwei der wichtigsten Verbesserungen - Animationseffekte und Multitouch-Unterstützung - anstellen dürfen. Der Quellcode für beide Beispiele liegt auf dem FTP-Server [2] bereit.
Bewegtes Plasma
Mit dem brandneuen Animations-Framework des Qt-Kinetic-Projekts [3] wird KDE 4.4 aller Voraussicht nach eine ordentliche Oberflächenpolitur in Form animierter Objektbewegungen erfahren. Zum Beispiel weichen Fenster langsam in den Hintergrund, statt mit einem Sprung die Ebene zu wechseln. Beim Plasma-Desktop stehen fließende Bewegungen ganz oben auf der Prioritätenliste.
Der Idee nach führen Programmierer damit das Auge des Anwenders zu Gunsten intuitiver Benutzung. Damit sich Effekte leicht verwirklichen lassen, baut Qt 4.6 das Animations-Framework um die Klasse »QAbstractAnimation« herum auf. Sie folgt dem Konzept von Eigenschaften. Das bedeutet, dass Animationen sich nicht auf Bewegung, Drehung oder Skalierung von Objekten beschränken, sondern sich auch im Grad der Transparenz oder farblich ändern lassen.
Aus Sicht des KDE-Programmierers beginnt die Implementation bei den grafischen Ansichtsklassen, auf die der Plasma-Desktop aufbaut. Das erste Programmierbeispiel zeigt, wie sich grafische Objekte animieren lassen. Listing 1 verwirklicht beispielhaft die Animationen zweier Widgets.
1 ViewWidget::ViewWidget(QWidget *parent)
2 : QGraphicsView(parent)
3 {
4 setRenderHints(QPainter::Antialiasing |
QPainter::SmoothPixmapTransform);
5
6 QGraphicsScene *scene =
new QGraphicsScene(-100, -100, 200, 200, this);
7 setScene(scene);
8
9 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()/2, 10);
19 rotateItem->setTransformOriginPoint(rotateButton->width()/2, rotateButton->height()/2);
20
21 QPropertyAnimation *blurAnimation =
new QPropertyAnimation(blurEffect, "blurRadius", this);
22 blurAnimation->setStartValue(0.0);
23 blurAnimation->setKeyValueAt(0.5, 10.0);
24 blurAnimation->setEndValue(0.0);
25 blurAnimation->setDuration(1500);
26 connect(blurButton, SIGNAL(clicked()), blurAnimation, SLOT(start()));
27
28 QPropertyAnimation *rotateAnimation =
new QPropertyAnimation(rotateItem, "rotation", this);
29 rotateAnimation->setStartValue(0.0);
30 rotateAnimation->setEndValue(360.0);
31 rotateAnimation->setDuration(2000);
32 rotateAnimation->setEasingCurve(QEasingCurve::OutBounce);
33 connect(rotateButton, SIGNAL(clicked()),
rotateAnimation, SLOT(start()));
34 }
|
Zeile 4 bewirkt zunächst die Kantenglättung für eine bestmögliche Darstellung bei sparsamem Ressourcenverbrauch. Die beiden Zeilen 6 und 7 erstellen ein Ansichtsfeld »scene«, das die gesetzten Bedingungen benutzt. Das Ansichtsfeld erhält eine quadratische Fläche der Kantenlänge 200 Pixel.
Spezifiziert der Entwickler keine Größe, würde Qt das Ansichtsfeld zunächst so klein wie möglich zeichnen. Es wüchse anschließend nach Bedarf, wenn die Animationen die Größe des Feldes verändern. Eventuell entstehen dann Rollbalken oder die Positionen der Inhalte im Feld ändern sich, damit immer alles sichtbar ist. Solche Mätzchen vermeidet, wer Qt ein festes Viereck vorgibt.
Die Zeilen 9 bis 11 erstellen das erste Element der Fläche. Das kann alles Mögliche sein, beispielsweise eine Bitmap, eine SVG-Zeichnung oder eine geometrische Form. Das angegebene Beispiel bettet den Knopf »blurItem» ein. Der Code instanziert erst die Schaltfläche und fügt sie dann dem Ansichtsfeld hinzu. Damit erhält es automatisch einen Platz in der Klasse »QGraphicsProxyWidget«. Sie ist für das Weiterreichen von Events und Vorgängen zwischen Widget und Ansichtsfeld zuständig. Wenn die Schaltfläche Teil des Ansichtfelds ist, zentriert sie die Funktion »setPos()«.
Qt betritt die Bühne
Die neuen grafischen Effekte von Qt 4.6 kommen in den Zeilen 12 bis 14 ins Spiel. Die Effekte können seit der neuen Qt-Version Eigenschaft eines jeden Gegenstands sein. Mitgelieferte Standardeffekte sind das Verschwimmen und Färben, Schatten werfen und Deckkraft ändern. Wem das nicht genügt, der programmiert eigene Effekte oder kombiniert vorhandene. Im Beispiel verschwimmt das Widget.
Zunächst erhält der verschwimmende Bereich um das Objekt herum jedoch die Ausdehnung 0, sodass der Effekt nicht sichtbar ist - er kommt später zum Zuge. Eine zweite Schaltfläche entsteht in den Zeilen 16 bis 19. Der Programmtext ist fast gleich, nur liegt der neue Button unterhalb des ersten. Standardmäßig ist die linke obere Ecke der Anker. Da die Schaltfläche aber rotieren soll, wird mit »setTransformOriginPoint()« stattdessen der Mittelpunkt zum Anker - das sieht besser aus (Zeile 19).