Development/Tutorials/Plasma4/GettingStarted (pt BR): Difference between revisions

    From KDE TechBase
    No edit summary
    (No difference)

    Revision as of 23:27, 11 September 2014


    Criando seu primeiro plasmoid
    Tutorial Series   Plasma Tutorial
    Previous   C++, Qt, KDE4 development environment
    What's Next  
    Further Reading   CMake

    Introdução

    Este tutorial precisa de, no mínimo, KDE 4.2 para ser compilado. Nós vamos criar um plasmoid simples neste tutorial. Para deixar as coisas simples, nós só vamos criar um plasmoid estático contendo os seguintes ítens:

    • Uma imagem SVG
    • Um ícone
    • Algum texto legal

    O código

    O arquivo .desktop

    Todo plasmoid precisa de um arquivo .desktop para dizer ao Plasma como ele deve ser iniciado e qual é o seu nome.

    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
    

    As partes mais importantes são X-KDE-Library e X-KDE-PluginInfo-Name: eles são a "cola" entre sua classe e o Plasma. Sem eles, nada irá funcionar. For X-KDE-PluginInfo-Category, refer to the PIG.

    O cabeçalho

    Este é o cabeçalho de exemplo. Alguns comentários foram adicionados ao código para dar mais clareza.

    plasma-tutorial1.h

    // Aqui nós evitamos que o cabeçalho seja carregado mais de uma vez
    #ifndef Tutorial1_HEADER
    #define Tutorial1_HEADER
    // Nós precisamos dos cabeçalhos do Applet Plasma
    #include <KIcon>
     
    #include <Plasma/Applet>
    #include <Plasma/Svg>
     
    class QSizeF;
     
    // Definição do nosso applet Plasma
    class PlasmaTutorial1 : public Plasma::Applet
    {
        Q_OBJECT
        public:
            // Criar/Destruir básico
            PlasmaTutorial1(QObject *parent, const QVariantList &args);
            ~PlasmaTutorial1();
     
            // O procedimento paintInterface desenha o applet na tela
            void paintInterface(QPainter *painter,
                    const QStyleOptionGraphicsItem *option,
                    const QRect& contentsRect);
    	void init();
    
        private:
            Plasma::Svg m_svg;
            KIcon m_icon;
    };
     
    // Este é o comando que liga seu applet ao arquivo .desktop
    K_EXPORT_PLASMA_APPLET(tutorial1, PlasmaTutorial1)
    #endif
    

    QRectF boundingRect()

    A função boundingRect() diz ao Plasma o tamanho real do plasmoid. Isto é importante porque nós precisamos saber quanto espaço é tomado na tela.

    Tip
    Se você tem problemas com seu plasmoid deixando um rastro de pixels enquanto é arrastado, isso é, geralmente, causado por um boundingRect() incorreto.


    void paintInterface(QRectF contentsRect)

    Esta pode ser considerada a função principal, já que desenha o plasmoid na tela. Aqui você define como você quer que seu plasmoid fique. Você só deve desenhar nos limites definidos por contentsRect e evitar usar geometry(). Quando um plasmoid não tem um fundo padrão - quando, por exemplo, está desativado com uma chamada de setBackgroundHints() ou está no painel - geometry() e boundingRect() se comportam igualmente; no entanto, quando o fundo padrão está ativado (o caso usual), o applet vai ter uma margem onde não ele deveria ser desenhado.

    K_EXPORT_PLASMA_APPLET ( <name>, <class> )

    Esta é uma parte pequena, mas muito importante que liga o nome da classe ao nome do applet no arquivo .desktop. Se parecer que seu applet não foi carregado, deve haver uma diferença entre esta declaração e seu arquivo .desktop.

    Tip
    K_EXPORT_PLASMA_APPLET adiciona "plasma_applet_". Por favor, preste atenção a isto quando estiver configurando seu arquivo .desktop para evitar uma diferença de nome.


    O arquivo de trabalho de verdade

    Aqui está o corpo da função, novamente com vários comentários.

    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");
        // Isto vai nos dar o fundo padrão de applets, de graça!
        setBackgroundHints(DefaultBackground);
        resize(200, 200);
    }
     
    
    PlasmaTutorial1::~PlasmaTutorial1()
    {
        if (hasFailedToLaunch()) {
            // Pôr alguma limpeza aqui
        } else {
            // Salvar configurações
        }
    }
    
    void PlasmaTutorial1::init()
    {
     
        // Uma pequena demonstração da função setFailedToLaunch
        if (m_icon.isNull()) {
            setFailedToLaunch(true, "Nenhum mundo para dizer olá");
        }
    } 
     
     
    void PlasmaTutorial1::paintInterface(QPainter *p,
            const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
    {
        p->setRenderHint(QPainter::SmoothPixmapTransform);
        p->setRenderHint(QPainter::Antialiasing);
     
        // Agora nós desenhamos o applet, começando pelo svg
        m_svg.resize((int)contentsRect.width(), (int)contentsRect.height());
        m_svg.paint(p, (int)contentsRect.left(), (int)contentsRect.top());
     
        // Colocamos ícone e 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,
                    "Olá, plasmoid!");
        p->restore();
    }
     
    #include "plasma-tutorial1.moc"
    

    Plasma/Svg

    Como você pode ver no código de exemplo, estamos usando o objeto Plasma::Svg. Há algumas coisas importantes para notar aqui.

    Em primeiro lugar, estamos usando um path relativo (widgets/background), que faz com que Plasma::Svg use Plasma::Theme para localizar os dados SVG. Enquanto Plasma::Svg suporta carregar arquivos arbitrários quando é passado um path absoluto, ela usa paths relativos do tema sempre que possível e sempre que se aplica temas ao Plasma. Assim, plasmoids individuais parecem mais um grupo do que um conjunto de aplicações separadas. Você pode ver uma lista de imagens disponíveis na página de temas do Plasma.

    Em ambos os modos, Plasma::Svg pode ser usada para desenhar um subconjunto do arquivo SVG passando para ele um id de um elemento que aparece no documento SVG. Um bom exemplo: se você abrir o arquivo clock.svg que vem com o tema padrão, você verá que ele tem um fundo, 3 ponteiros (hora, minuto e segundos) e uma frente (o vidro). Graças à habilidade de pôr todos os elementos num arquivo, o arquivo SVG mostra um relógio. Isso é bem melhor para artistas do que editar 5 arquivos separados - que eles tem que imaginar que estão um encima do outro -, e muito melhor para a performace, já que apenas uma renderização SVG e uma leitura de arquivo bastam.

    setBackgroundHints(DefaultBackground)

    Como desenhar o fundo é uma função comum, há uma maneira rápida e fácil de fazê-lo. Adicionando setBackgroundHints(DefaultBackground) ao código, o fundo padrão do Plasma é desenhado ao fundo do seu plasmoid. Isso não só economiza tempo e código, como também cria uma apresentação mais consistente ao usuário.

    O método init()

    No construtor você apenas diz ao Plasma o fundo e o arquivo de configuração, se houver. Você também configura o tamanho inicial no construtor. Depois disso, o Plasma vai cuidar de qualquer redimensionamento, e você não vai mais precisar se preocupar sobre o tamanho. No método init() você inicializa tudo que for necessário, como ler os dados de configuração, por exemplo.

    hasFailedToLaunch()

    Se, por alguma razão, a inicialização do applet falhar (as bibliotecas não puderam ser carregadas, não foi encontrado o hardware necessário, etc.), esse método retorna verdadeiro. O uso dessa função dá uma chance de fazer a limpeza necessária ao seu aplicativo.

    setFailedToLaunch(bool, QString)

    Quando não é possível iniciar sua aplicação, essa função permite que você informe ao Plasma e dê um porquê opcional. Plasma vai então desenhar uma interface de erro padronizada para informar ao usuário sobre a situação e seu applet não será chamado para desenhar nada dali para frente. Se seu plasmoid ficar mais complexo e depender de múltiplos fatores, essa é a melhor maneira para fazer uma limpeza.

    dataUpdated

    Se você se conectasse a qualquer um dos data-engines do Plasma você teria que implementar uma função chamada dataUpdated no seu plasmoid. Ela é chamada se o data-engine lhe mandar dados - por exemplo: se seu plasmoid tivesse que recalcular o conteúdo.

    Determinar o tamanho e a geometria do applet: geometry() e contentsRect()

    Se você precisar saber, no código do seu applet, qual seus tamanho e geometria, chame contentsRect() e contentsRect().size(). Evite chamar geometry() e size(), pois eles não levam em conta o tamanho da margem, configurado pelo fundo padrão do applet. Além disso, evite usar números absolutos ao posicionar ítens no applet, como QPoint(0, 0) para indicar o ponto superior esquedo do applet. Em vez disso, use contentsRect().topLeft().

    Compilando tudo. CMakeLists.txt

    Finalmente, para pôr tudo junto é necessário compilar. Para dizer ao CMake o que precisa ir onde, aqui está o CMakeLists.txt.

    Para mais detalhes sobre o CMake, por favor leia Development/Tutorials/CMake_(pt_BR)

    # O projeto precisa de um nome, obviamente
    project(plasma-tutorial1)
    
    # Encontrar as bibliotecas necessárias
    find_package(KDE4 REQUIRED)
    include(KDE4Defaults)
    
    add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
    include_directories(
       ${CMAKE_SOURCE_DIR}
       ${CMAKE_BINARY_DIR}
       ${KDE4_INCLUDES}
       )
    
    # Adicionamos nosso código fonte aqui
    set(tutorial1_SRCS plasma-tutorial1.cpp)
    
    # Agora tenha certeza de que todos os arquivos estão no lugar certo
    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})
    

    Testando o Applet

    Se seu ambiente de desenvolvimento atual difere da instalação teste, você tem que rodar o CMake com -DCMAKE_INSTALL_PREFIX=$KDEDIR (sendo $KDEDIR o diretório onde o KDE se encontra). Então rode make. Se a compilação ocorreu com sucesso, o programa pode ser instalado com make install (como root). ou

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

    e rode kbuildsycoca4 (para que os programas KDE saibam dos novos arquivos desktop). Para testar seu applet, você pode usar o programa plasmoidviewer:

    plasmoidviewer applet_name
    

    Você pode, também, ver seu applet numa área de trabalho pequena usando o plasmoidviewer:

    plasmoidviewer -c desktop applet_name
    

    Sendo applet_name o calor especificado dentro do .desktop para a chave X-KDE-PluginInfo-Name.

    Ou então você pode reiniciar o Plasma, para que o applet seja mostrado no navegador de applets:

    kbuildsycoca4
    kquitapp plasma # no trunk (KDE4.3): kquitapp plasma-desktop
    plasma          # no trunk (KDE4.3): plasma-desktop
    

    Se isso não funcionar você terá que reiniciar sua sessão KDE fazendo logout e, então, login.