Development/Tutorials/Plasma4/GettingStarted (de)
Proposed for Deletion |
---|
This page has been proposed for deletion for the following reason:
|
Tutorial Series | Plasma Tutorial |
Previous | C++, Qt, KDE4 development environment |
What's Next | |
Further Reading | CMake |
Übersicht
Dieses Tutorial setzt KDE 4.2 voraus. Wir werden ein einfaches Plasmoid erstellen. Um es einfach zu halten, programmieren wir lediglich ein statisches Plasmoid, welches folgende Eigenschaften mitbringt:
- Eine SVG-Grafik
- ein Icon
- einen freudlichen Text
Der Code
Die .desktop Datei
Für jedes Plasmoid wird eine .desktop Datei benötigt, die Plasma beschreibt, wie es zu starten ist und welchen Namen es besitzt.
plasma-applet-tutorial1.desktop
[Desktop Entry]
Name=Tutorial 1
Comment=Plasma Tutorial 1
Type=Service
ServiceTypes=Plasma/Applet
X-KDE-Library=plasma_applet_tutorial1
X-KDE-PluginInfo-Author=Bas Grolleman
X-KDE-PluginInfo-Email=[email protected]
X-KDE-PluginInfo-Name=plasma_applet_tutorial1
X-KDE-PluginInfo-Version=0.1
X-KDE-PluginInfo-Website=http://plasma.kde.org/
X-KDE-PluginInfo-Category=Examples
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
Die wichtigsten Einträge sind X-KDE-Library und X-KDE-PluginInfo-Name, diese beiden stellen die Nahtstelle zwischen deiner Klasse und Plasma dar. Ohne diese Einträge würde nichts funktionieren. Weitere Infos zu X-KDE-PluginInfo-Category siehe PIG.
Die Header-Datei
plasma-tutorial1.h
// Hiermit wird vermieden, dass der header mehrmals eingelesen wird
#ifndef Tutorial1_HEADER
#define Tutorial1_HEADER
// Laden der Plasma Applet Header
#include <KIcon>
#include <Plasma/Applet>
#include <Plasma/Svg>
class QSizeF;
// Unser Plasma Applet
class PlasmaTutorial1 : public Plasma::Applet
{
Q_OBJECT
public:
// Konstruktor / Destruktor
PlasmaTutorial1(QObject *parent, const QVariantList &args);
~PlasmaTutorial1();
// paintInterface zeichnet das Applet auf den Bildschirm
void paintInterface(QPainter *painter,
const QStyleOptionGraphicsItem *option,
const QRect& contentsRect);
void init();
private:
Plasma::Svg m_svg;
KIcon m_icon;
};
// Mit diesem Befehl wird das Applet mit dem .desktop-File verbunden
K_EXPORT_PLASMA_APPLET(tutorial1, PlasmaTutorial1)
#endif
QRectF boundingRect()
Die Funktion boundingRect() teilt Plasma die aktuelle Größe des Plasmoid mit. Das ist notwendig, weil wir wissen müssen, wieviel Platz auf dem Bildschirm verwendet wird.
void paintInterface(QRectF contentsRect)
Diese Funktion kann als Hauptroutine angesehen werden, weil sie das Plasmoid auf den Bildschirm zeichnet. Hier wird bestimmt, wie dein Plasmoid aussieht. Du solltest nur innerhalb der Grenzen, die durch contentsRect bestimmt sind, zeichnen, geometry() sollte hier vermieden werden. Wenn ein Plasmoid keinen Standard-Hintergrund besitzt, z.B. weil es mit einem Aufruf von setBackgroundHints() deaktiviert wurde oder es sich im Panel befindet, verhalten sich geometry() und boundingRect() identisch. Wenn der Standard-Hintergrund jedoch aktiviert ist, also der Normalfall, soll das Applet im Randbereich nicht gezeichnet werden.
K_EXPORT_PLASMA_APPLET ( <name>, <class> )
Dieser kleine, aber doch wichtige Teil, ist essentiell, denn er verknüpft den Klassennamen mit dem Applet-Namen, der im .desktop-File definiert wurde. Wenn das Applet anscheinend nicht geladen wird, könnte hier das Problem liegen.
Das eigentliche Programm
Hier die Implementiertug der Funktionen, wieder mit einigen Kommentaren versehen
plasma-tutorial1.cpp
#include "plasma-tutorial1.h"
#include <QPainter>
#include <QFontMetrics>
#include <QSizeF>
#include <plasma/svg.h>
#include <plasma/theme.h>
PlasmaTutorial1::PlasmaTutorial1(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args),
m_svg(this),
m_icon("document")
{
m_svg.setImagePath("widgets/background");
// Den Standard-Applet-Hintergrund verwenden
setBackgroundHints(DefaultBackground);
resize(200, 200);
}
PlasmaTutorial1::~PlasmaTutorial1()
{
if (hasFailedToLaunch()) {
// Hier wird aufgeräumt
} else {
// Einstellungen speichern
}
}
void PlasmaTutorial1::init()
{
// Eine kleine Demonstration der Funktion setFailedToLaunch
if (m_icon.isNull()) {
setFailedToLaunch(true, "No world to say hello");
}
}
void PlasmaTutorial1::paintInterface(QPainter *p,
const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
p->setRenderHint(QPainter::SmoothPixmapTransform);
p->setRenderHint(QPainter::Antialiasing);
// Jetzt kann das Applet gezeichnet werden, zuerst das SVG
m_svg.resize((int)contentsRect.width(), (int)contentsRect.height());
m_svg.paint(p, (int)contentsRect.left(), (int)contentsRect.top());
// Icon und Text einfügen
p->drawPixmap(7, 0, m_icon.pixmap((int)contentsRect.width(),(int)contentsRect.width()-14));
p->save();
p->setPen(Qt::white);
p->drawText(contentsRect,
Qt::AlignBottom | Qt::AlignHCenter,
"Hello Plasmoid!");
p->restore();
}
#include "plasma-tutorial1.moc"
Plasma/Svg
Wie du im Code gesehen hast, verwenden wir das Objekt Plasma::Svg. Hierzu sollte man folgendes wissen:
Wir verwenden einen relativen Pfad widgets/background, was dazu führt, dass Plasma::Svg Plasma::Theme verwendet, um die SVG-Datei zu finden. Plasma::Svg lädt beliebige Dateien, wenn ein absoluter Pfad übergeben wird. Um den unterschiedlichen Plasmoids ein einheitliches Aussehen zu geben anstatt wie eine zusammengewürfelte Sammlung von unabhängigen Programmen zu wirken, sollten daher so oft wie möglich relative Pfadangaben verwendet werden. Eine Übersicht der verfügbaren Image-Komponenten findest du unter Plasma Theme page.
Plasma::Svg kann auch dazu verwendet werden, um ein Subset der SVG-Datei zu zeichnen, wenn man eine entsprechend in der SVG hinterlegte ID übergibt. Ein gutes Beispiel hierfür ist die clock.svg, welche im Standardtheme enthalten ist. Sie enthält einen Hintergrund, drei Handles für Stunden, Minuten und Sekunden, sowie den Vordergrund (das Glas). Durch die Möglichkeit, alle in eine Datei zu stecken, zeigt das File eine komplette Uhr. Das ist wesentlich einfacher zu handhaben, als 5 verschiedene Dateien editieren zu müssen. Außerdem steigt die Verarbeitungsgeschwindigkeit, da nur ein SVG-Renderer arbeiten muss.
setBackgroundHints(DefaultBackground)
Einen Hintergrund zu zeichnen, ist eine Standard-Funktionalität. Daher gibt es einen einfacheren und schneller Weg, dies zu bewerkstelligen, indem man einfach setBackgroundHints(DefaultBackground) zu seinem Code hinzufügt. Dadurch wird der Standard-Plasma-Hintergrund hinter dein Plasmoid gezeichnet. Dies spart nicht nur Zeit und Codezeilen, es hilft auch, dem Benutzer ein konsistentes Aussehen zu präsentieren.
Die init()-Methode
Im Konstruktor teilen wir Plasma Informationen über den Hintergrund und ggf. Konfigurationdateien mit. Auch die Startgröße wird im Konstruktor gesetzt. Danach wird jede Größenänderung von Plasma selbst übernommen. In der Methode init() wird alles initialisiert, was irgendwie initialisiert werden muss, wie z.B. Konfigurationsdaten lesen.
hasFailedToLaunch()
Diese Methode liefert den Wert true zurück, falls, aus welchem Grund auch immer, das Applet nicht korrekt starten kann (z.B. weil die Bibliothek nicht geladen werden kann, nowendige Hardwareunterstützung nicht gefunden wird, ...). Nutze die Methode, um vor dem Beenden noch Aufräumarbeiten zu erledigen.
setFailedToLaunch(bool, QString)
Wenn dein Programm nicht gestartet werden kann, kann mit Hilfe dieser Methode Plasma darüber informiert werden. mit einem optionalen String kann auch der Grund angegeben werden. Plasma wird dann eine standardisierte Fehlermeldung anzeigen, die den Benutzer über die Situation informiert. Dein Applet wird ab diesem Zeitpunkt nicht mehr aufgerufen, irgendetwas zu zeichnen. Bei komplexeren Plasmoids, deren korrekte Anzeige von mehreren Faktoren abhängt, ist das ist der eleganteste Weg, aufzuräumen.
dataUpdated
Wenn du dein Plasmoid an eine von Plasmas Data Engine anschließen willst, musst du diese Methode implementieren. Sie wird aufgerufen, wenn die Data Engine dir Daten sendet. Hier würdest du z.B. implementieren, dass dein Plasmoid aufgrund der aktuellen Daten neu gezeichnet wird.
Bestimmen von Größe und Geometrie: geometry() and contentsRect()
Wenn du in deinem Applet-Code die Größe und Geometrie wissen musst, dann rufe contentsRect() und contentsRect().size() auf. Vermeide den Aufruf von geometry() und size(), weil diese den Randbereich des Applet nicht berücksichtigen. Vermeide genauso, Objekte im Applet mit absoluten Werten zu platzieren, wie z.B. QPoint(0, 0). Verwende stattdessen contentsRect().topLeft().
Building it all, the CMakeLists.txt
Zu guter Letzt musst du jetzt noch alles zusammenfügen, was zum Kompilieren notwendig ist. Um cmake mitzuteilen, was es machen soll, benötigen wir die Datei CMakeLists.txt.
Weitere Infos zu cmake siehe Development/Tutorials/CMake
# Das Projekt benötigt natürlich einen Namen
project(plasma-tutorial1)
# Die benötigten Bibliotheken suchen
find_package(KDE4 REQUIRED)
include(KDE4Defaults)
add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories(
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${KDE4_INCLUDES}
)
# Hier fürden wir den Sourcecode ein
set(tutorial1_SRCS plasma-tutorial1.cpp)
# Jetzt noch sicherstellen, dass alles an den richtigen Platz installiert wird
kde4_add_plugin(plasma_applet_tutorial1 ${tutorial1_SRCS})
target_link_libraries(plasma_applet_tutorial1
${KDE4_PLASMA_LIBS} ${KDE4_KDEUI_LIBS})
install(TARGETS plasma_applet_tutorial1
DESTINATION ${PLUGIN_INSTALL_DIR})
install(FILES plasma-applet-tutorial1.desktop
DESTINATION ${SERVICES_INSTALL_DIR})
Das Applet testen
Wenn deine aktuelle Desktop-Umgebung von der Testinstallation abweicht, musst du cmake mit der Option -DCMAKE_INSTALL_PREFIX=/usr/lib/kde4/ (ersetzen mit deinem $KDEDIR) aufrufen. Danach make starten. Wenn alles geklappt hat, kann das Applet mit sudo make install oder
- cp ./lib/plasma_applet_tutorial1.so $KDEDIR/lib
- cp ./plasma-applet-tutorial1.desktop $KDEDIR/share/kde4/services/
installiert werden.
Anschließend kbuildsycoca4 starten, damit KDE-Programme etwas von den neuen Dateien wissen. Um dein Applet zu testen, kannst du das Programm plasmoidviewer verwenden:
plasmoidviewer applet_name
Du kannst dein Applet sogar in einem eigenen kleinen Desktop starten:
plasmoidviewer -c desktop applet_name
applet_name ist natürlich der Name, der in der .desktop-Datei unter dem Schlüsselwort X-KDE-PluginInfo-Name eingetragen ist.
Ansonsten kannst du Plasma auch einfach neu starten, dann wird das neue Applet im Applet-Browser angezeigt:
kbuildsycoca4
kquitapp plasma # in trunk (KDE4.3): kquitapp plasma-desktop
plasma # in trunk (KDE4.3): plasma-desktop
Wenn das auch nicht funktioniert, solltest du KDE neu starten, indem du dich ab- und wieder anmeldest.