Development/Tutorials/Plasma4/GettingStarted (es)

From KDE TechBase
Creando tu primer Plasmoid
Serie   Tutorial de Plasma
Requisitos previos   C++, Qt, entorno de desarrollo de KDE4
Siguiente  
Lectura avanzada   CMake

Resumen

Este tutorial necesita KDE 4.2 (trunk) para poder construirlo. En este tutorial vamos a crear un simple plasmoid. Para hacer las cosas faciles, sólo crearemos un plasmoid estático que contendrá los siguientes elementos:

  • Una imagen SVG
  • Icono
  • Un texto

El Código

El archivo .desktop

Cada Plasmoid necesita un archivo .desktop para indicarle a Plasma como debe iniciarlo y que nombre tomará.

plasma-applet-tutorial1.desktop

[Desktop Entry]
Name=Tutorial 1
Comment=Plasma Tutorial 1
Type=Service

X-KDE-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=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

Las partes mas importantes son X-KDE-Library y X-KDE-PluginInfo-Name, ellas son el "pegamento" entre tu clase y plasma, sin ellos, no se iniciará nada. X-KDE-PluginInfo-Category se refiere a PIG.

El archivo cabecera

Aquí tienes el archivo cabecera de este tutorial. Se han añadido Los comentarios por claridad.

plasma-tutorial1.h

// Evitamos cargar la cabecera varias veces
#ifndef Tutorial1_HEADER
#define Tutorial1_HEADER
// Necesitamos las cabeceras de Plasma Applet
#include <Plasma/Applet>
#include <Plasma/Svg>

#include <KIcon>
  
class QSizeF;
 
// Definimos nuestro applet de plasma
class PlasmaTutorial1 : public Plasma::Applet
{
    Q_OBJECT
    public:
		// Constructor/Destructor básico
        PlasmaTutorial1(QObject *parent, const QVariantList &args);
        ~PlasmaTutorial1();
 
        // El procedimiento paintInterface dibuja el applet en la pantalla
        void paintInterface(QPainter *painter,
                const QStyleOptionGraphicsItem *option,
                const QRect& contentsRect);
	void init();

    private:
        Plasma::Svg m_svg;
        KIcon m_icon;
};
 
// Esta es la orden que enlaza el applet con el archivo .desktop
K_EXPORT_PLASMA_APPLET(tutorial1, PlasmaTutorial1)
#endif

QRectF boundingRect()

La función boundingRect() le dice a plasma el tamaño actual del plasmoid. Esto es importante porque necesitamos saber cuanto espacio se ocupa en la pantalla.

noframe
noframe

Si tienes problemas con tu plasmoid dejando pixeles atras cuando lo arrastras, se trata por lo general de un boundingRect() incorrecto.

Consejo


void paintInterface(QRectF contentsRect)

Puede considerarse la función principal, ya que dibuja el plasmoid en la pantalla. Aquí defines que aspecto quieres que tenga tu plasmoid. Solo debes dibujar en los límites definidos por contentsRect y evitar usar geometry(). Cuando un plasmoid no tiene un fondo estándar, por ejemplo, si se ha desactivado mediante la llamada setBackgroundHints() o está en el panel, geometry() y boundingRect() se comportan igual; sin embargo, cuando el fondo estándar está activado (el caso habitual), el applet tendrá un margen donde no debería pintarse.

K_EXPORT_PLASMA_APPLET ( <name>, <class> )

Es una pequeña parte pero muy importante ya que enlaza tu clase con el nombre del applet del archivo .desktop. Si tu applet parece que no se carga, puede ser que haya una diferencia entre esta declaración y tu archivo .desktop.


noframe
noframe
K_EXPORT_PLASMA_APPLET añade "plasma_applet_", por favor presta atención cuando establezcas el nombre en tu archivo .desktop para evitar una diferencia de nombres.
Consejo


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");
	// Establecerá el fondo por defecto del applet, gratis!
	setBackgroundHints(DefaultBackground);
	resize(400, 400);
}


PlasmaTutorial1::~PlasmaTutorial1()
{
	if (hasFailedToLaunch()) {
		// Hacer algo de limpieza aquí
	} else {
		// Guardar la configuracion
	}
}

void PlasmaTutorial1::init()
{
	// Una pequeña demostracion de la función setFailedToLaunch
	if (m_icon.isNull()) {
		setFailedToLaunch(true, "Sin mundo al que decir hola");
	}
} 
 
 
void PlasmaTutorial1::paintInterface(QPainter *p,
        const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
{
	p->setRenderHint(QPainter::SmoothPixmapTransform);
	p->setRenderHint(QPainter::Antialiasing);
	
	// Ahora dibujamos el applet, empezando por nuestro svg
	m_svg.resize((int)contentsRect.width(), (int)contentsRect.height());
	m_svg.paint(p, (int)contentsRect.left(), (int)contentsRect.top());
	
	// Colocamos el icono y el texto
	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, "Hola Plasmoid!");
	p->restore();
}
 
#include "plasma-tutorial1.moc"

Plasma/Svg

Como se puede ver en el código de ejemplo estamos usando el objeto Plasma::Svg, que tiene algunas cosas importantes a señalar.

En primer lugar estamos usando una ruta relativa a widgets/background que obliga a Plasma::Svg a usar Plasma::Theme para localizar el archivo SVG. Si bien Plasma::Svg da soporte para cargar archivos pasandole una ruta absoluta, usa rutas relativas para el tema siempre que sea posible, ya que esto hace que Plasma soporte estilos y que los plasmoids individuales tengan el mismo aspecto, en vez de un grupo de aplicaciones sin relación alguna. Puedes ver una lista de los componentes de imagen disponibles en temas de Plasma.

Por otro lado, Plasma::Svg se puede usar para dibujar un subconjunto del archivo SVG pasandole un elemento identificador que aparezca en el documento SVG. Un buen ejemplo es el archivo clock.svg que viene en el tema por defecto, verás que tiene un fondo, tres agujas (hora, minuto y segundo) y un primer plano. Esto es mucho mas agradable para los artistas esta metodologia comparado con editar 5 archivos por separado, ya que tendrian que imaginar los archivos svg unos encima de otros, y mucho mejor para el rendimiento ya que solo se renderiza un archivo y solo se hace una lectura de archivo del disco.

setBackgroundHints(DefaultBackground)

Desde que dibujar el fondo es una función común, esta es mas rapida y fácil de hacer. Añadiendo setBackgroundHints(DefaultBackground) al código, el fondo por defecto de Plasma se dibuja detras de tu plasmoid. No solo te ahorra tiempo y código, sino que crea una presentación mas consistente para el usurario.

El método init()

En el constructor solo notificas a Plasma el fondo y el archivo de configuración (si existiese). También puedes establecer el tamaño inicial en el constructor. Despues de esto, Plasma se ocupará de cualquier cambio de tamaño y de que nunca tengas que preocuparte por él. En el método init() inicializas todo lo que necesite ser inicializado, como leer los datos del archivo de configuración por ejemplo.


hasFailedToLaunch()

Si por alguna razón el applet fallara al iniciarlo (la biblioteca no pudo cargarse, necesario soporte hardware que no se ha encontrado, etc..) este método devolvería true. Usar esta función proporciona a tu aplicación la oportunidad de limpiar lo que sea necesario antes de cerrarse.

setFailedToLaunch(bool, QString)

Cuando tu aplicación no esta en condiciones de iniciarse, esta función te permite informar a Plasma y dar un motivo del porque. Entonces Plasma lanzará una interfaz estándar de error para informar al usuario de la situación y en tu applet no se dibujará nada mas a partir de ese punto. Si tu plasmoid se convierte en algo mas complejo y depende de multiples factores, este método es la manera mas adecuada para limpiar lo que sea necesario.

dataUpdated

Si quisieras conectar tu applet a cualquiera de los data-engines de plasma, deberías implementar una función de nombre dataUpdate en tu plasmoid. Se llama a esta función si el data-engine te envia datos, es decir, tu plasmoid debería recalcular su contenido.

Determinar el tamaño y la geometría del applet: geometry() y contentsRect()

Si necesitas saber, en tu código, que tamaño y geometria que tiene el applet, puedes llamar a contentsRect() y a contentsRect().size(). Evita llamar a geometry() y size() porque en el cálculo no se tiene en cuenta el tamaño del margen establecido por el fondo por defecto del applet. También evita usar números absolutos para situar los elementos en el applet, como QPoint(0, 0) para indicar el punto superior izquierdo de tu applet, en vez de esto usa contentsRect().topLeft().

Construir el applet: CMakeLists.txt

Por último, para poner todo junto necesitas construirlo todo. Para decirle a cmake que necesita tenemos el archivo CMakeLists.txt

Para mas detalles de CMake lee por favor Development/Tutorials/CMake.

# El proyecto necesita un nombre
project(plasma-tutorial1)
 
# Encuentra las bibliotecas necesarias
find_package(KDE4 REQUIRED)
include(KDE4Defaults)
 
add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
include_directories(
   ${CMAKE_SOURCE_DIR}
   ${CMAKE_BINARY_DIR}
   ${KDE4_INCLUDES}
   )
 
# Añadimos nuestro código fuente aqui
set(tutorial1_SRCS plasma-tutorial1.cpp)
 
# Ahora nos aseguramos de poner todos los archivos en su lugar
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})

Testeando el Applet

Si tu actual entorno de desarrollo difiere de la instalacion de KDE4, tienes que ejecutar cmake con -DCMAKE_INSTALL_PREFIX=/usr/lib/kde4/ (reemplazar por tu $KDEDIR). Luego ejecuta make. Si todo fue bien, puedes instalar el applet ejecutando sudo make install o:

  • cp ./lib/plasma_applet_tutorial1.so $KDEDIR/lib
  • cp ./plasma-applet-tutorial1.desktop $KDEDIR/share/kde4/services/

y ejecuta kbuildsycoca4 (hará que todas las aplicacionesde KDE se enteren de los nuevos arvhivos desktop). Para testear tu Applet puedes usar el programa plasmoidviewer:

plasmoidviewer nombre_applet

Incluso puedes ver el applet en un pequeño escritorio mediante:

plasmoidviewer -c escritorio nombre_applet

Donde nombre_applet es el valor especificado en el campo X-KDE-PluginsInfo-Name del archivo .desktop.

También puedes reiniciar plasma, así el Applet se mostrará en el navegador de Applets:

kbuildsycoca4
kquitapp plasma # en trunk (KDE 4.3): kquitapp plasma-desktop
plasma          # en trunk (KDE 4.3): plasma-desktop

Si esto no funciona tendras que reiniciar tu sesión KDE.