Development/Tutorials/Plasma4/GettingStarted (uk)

    From KDE TechBase
     
    Proposed for Deletion
    This page has been proposed for deletion for the following reason:

    Page was created before the current translation system.

    Creating your first Plasmoid
    Tutorial Series   Plasma Tutorial
    Previous   C++, Qt, KDE4 development environment
    What's Next  
    Further Reading   CMake

    Передмова

    Дана інструкція потребує збірки kde 4.2. В даній статті ми створимо простий міні-додаток. Щоб зберегти простоту, ми створимо статичний міні-додаток із використанням наступних компонентів:

    • SVG малюнок
    • Іконка
    • Довільний простий текст

    Код міні-додатку

    Файл .desktop

    Кожен міні-додаток повинен містити файл .desktop, щоб вказати плазмі як і під яким іменем його запускати.

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

    Найважливішими є пункти X-KDE-Library та X-KDE-PluginInfo-Name, вони забезпечуються зв'язок між вашим класом та плазмою, без них нічого працювати не буде. Для X-KDE-PluginInfo-Category, див. PIG.

    Файл заголовка

    Це приклад файлу заголовка. Коментарі в коді додані для пояснення.

    plasma-tutorial1.h

    // Виключаємо повторне завантаження заголовків
    #ifndef Tutorial1_HEADER
    #define Tutorial1_HEADER
    
    #include <KIcon>
    // Необхідно включити заголовок Applet плазми 
    #include <Plasma/Applet>
    #include <Plasma/Svg>
     
    class QSizeF;
     
    // Визначаємо наш Applet плазми
    class PlasmaTutorial1 : public Plasma::Applet
    {
        Q_OBJECT
        public:
            // Конструктор та деструктор
            PlasmaTutorial1(QObject *parent, const QVariantList &args);
            ~PlasmaTutorial1();
     
            // paintInterface - процедура для промальовки Applet
            void paintInterface(QPainter *painter,
                    const QStyleOptionGraphicsItem *option,
                    const QRect& contentsRect);
    	void init();
    
        private:
            Plasma::Svg m_svg;
            KIcon m_icon;
    };
     
    // Ця команда зв'язує ваш Applet з .desktop файлом
    K_EXPORT_PLASMA_APPLET(tutorial1, PlasmaTutorial1)
    #endif
    

    Метод QRectF boundingRect()

    Функція boundingRect() повідомляє плазмі актуальні розміри міні-додатку. Це важливо, оскільки ми повинні знати, скільки місця займаємо на екрані.

    Tip
    Якщо виникають проблеми з неправильною промальовкою, то зазвичай це результат неправильної роботи функції boundingRect().


    Метод void paintInterface(QRectF contentsRect)

    Ця функціявважається головною, оскільки відповідає за промальовування плазмоїда на екрані. Тут ви можете визначити, як буде виглядати ваш додаток. Ви повинні проводити малювання в межах, визначених через contentsRect та уникати виходу за них за допомогою функції geometry(). Коли міні-додаток не має свого власного стандартного фону, наприклад він був відключений у функції setBackgroundHints() чи є панеллю, то geometry() та boundingRect() поводять себе так само, але, коли використовується стандартний фон(звичний випадок), аплет буде мати місця, де краще не малювати.

    Макрос K_EXPORT_PLASMA_APPLET ( <name>, <class> )

    Це маленька, але дуже важлива частина, що зв'язує ім'я вашого класу з іменем аплету, що визначене в файлі .desktop.

    Якщо ваш аплет не завантажується, то одною з причин може бути якраз невідповідність у цьому місці.

    Tip
    Макрос K_EXPORT_PLASMA_APPLET додає "plasma_applet_", будь ласка, враховуйте це, коли налаштовуєте ваш .desktop файл, щоб уникнути розбіжностей в іменах.


    Головний робочий файл

    Тут описано вміст функцій із коментарями.

    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");
        // встановлюємо стандартний фон
        setBackgroundHints(DefaultBackground);
        resize(200, 200);
    }
     
    
    PlasmaTutorial1::~PlasmaTutorial1()
    {
        if (hasFailedToLaunch()) {
            // Очистка
        } else {
            // Зберігаємо налаштування
        }
    }
    
    void PlasmaTutorial1::init()
    {
     
        // Невелика демонстрація виклику функції setFailedToLaunch
        if (m_icon.isNull()) {
            setFailedToLaunch(true, "Немає світу, котрому можна сказати привіт!");
        }
    } 
     
     
    void PlasmaTutorial1::paintInterface(QPainter *p,
            const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
    {
        p->setRenderHint(QPainter::SmoothPixmapTransform);
        p->setRenderHint(QPainter::Antialiasing);
     
        // Зараз ми намалюємо наш аплет, почнемо з нашого svg
        m_svg.resize((int)contentsRect.width(), (int)contentsRect.height());
        m_svg.paint(p, (int)contentsRect.left(), (int)contentsRect.top());
     
        // Помістимо іконку та текст на аплет.
        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,
                    "Привіт, Plasmoid!");
        p->restore();
    }
     
    #include "plasma-tutorial1.moc"
    

    Клас Plasma/Svg

    Як ви могли побачити із коду, ми використовували Plasma::Svg об'єкт, достатньо важливий, щоб відмітити його тут.

    Спершу ми виставляємо відносний шлях до файлу widgets/background для Plasma::Svg, котрий використовується в Plasma::Theme для знаходження SVG-даних. Поки Plasma::Svg не підтримує завантаження довільних файлів з абсолютними шляхами, використовуйте відносні шляхи із теми якомога частіше, оскільки це дозволяє окремим плазмоїдам виглядати одинаково, використовуючи визначений в даний момент стиль Plasma. Список доступних картинок можна знайти на Plasma Theme page.

    Н будь-якому режимі, Plasma::Svg може використовуватися для розбору вмісту SVG файлів, дістаючи із них елементи по ідентифікаторах, котрі містяться в SVG документі. Хороший приклад: якщо ви відкриєте файл clock.svg, то він буде відкритий з темою за замовчуванням, ви маєте побачити фон, 3 стрілки та задній фон(прозорість). Через можливість помістити всі елементи в один файл SVG, файл покаже годинник. Це набагато зручніше, ніж редагувати 5 різних файлів, коли вони повинні знаходитися один над одним, а також це покращує продуктивність при розборі SVG файла і зчитуванні його з диску.

    Метод setBackgroundHints(DefaultBackground)

    Оскільки малювання фону є загальною функцією, існує швидкий і простий спосіб промалювати його. При додаванні setBackgroundHints(DefaultBackground) до вашого коду, стандартний фон Plasma буде малюватися позаду вашого міні-додатку. Це не тільки економить ваш час і кількість коду, але й створює більш послідовне представлення для користувача.

    Метод init()

    В конструкторі ви повідомляєте плазмі тільки про фон додатку та конфігураційний файл, якщо такі є. Ви також можете виставляти розміри міні-додатку в конструкторі. Після цього плазма бере відповідальність за зміну розмірів на себе і ви можете не думати на рахунок цього. У методі init() ви можете ініціалізувати все, що захочете, наприклад зчитування інформації з конфігураційного файлу.

    Метод hasFailedToLaunch()

    Якщо в деяких випадках міні-додаток не може бути запущений (наприклад не завантажені деякі бібліотеки, відсутні драйвери для деякого обладнання і т.п.), то цей метод поверне значення true. Використання цього методу дасть вашому додатку можливість виконати деяку очистку перед завершенням.

    Метод setFailedToLaunch(bool, QString)

    Якщо ваш додаток не в стані запуститися, то, викликавши даний метод, ви зможете повідомити плазму як і чому це сталося. Після цього плазма намалює стандартний інтерфейс із повідомленням про помилку для користувача і ваш міні-додаток не буде виконувати те, для чого він був призначений. Якщо ваш міні-додаток складний та залежить від багатьох зовнішніх факторів, то це найкращий спосіб проведення очистки.

    Функція dataUpdated

    Якщо ви хочете обробляти будь-які дані від plasma's data-engines, вам необхідно реалізувати функцію dataUpdated у вашому міні-додатку. Остання викликається, якщо data-engine надсилає вам дані, тобто ваш міні-додаток повинен перерахувати свій вміст.

    Визначення форми та розміру аплета: функції geometry() та contentsRect()

    Якщо ви хочете дізнатися в коді аплету, який розмір та форму має аплет, викличте contentsRect() та contentsRect().size(). Уникайте викликів функцій geometry() та size(), тому що вони не враховують розмір поля фону, що встановлюється аплетам за замовчуванням. Також уникайте використання абсолютних значень для позиціонування аплета, наприклад таких як QPoint(0, 0) для показу верхньої лівої точки вашого аплету. Замість цього використовуйте contentsRect().topLeft().

    Побудова, файл CMakeLists.txt

    Нарешті, для зв'язування всього разом, вам необхідно це все збудувати. Для вказання cmake, що потрібно робити, вкажемо йому файл CMakeLists.txt.

    За деталями роботи CMake, будь ласка, звертайтесь до документації Development/Tutorials/CMake

    # Проекту звісно ж потрібне ім'я
    project(plasma-tutorial1)
    
    # Пошук необхідних бібліотек
    find_package(KDE4 REQUIRED)
    include(KDE4Defaults)
    
    add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
    include_directories(
       ${CMAKE_SOURCE_DIR}
       ${CMAKE_BINARY_DIR}
       ${KDE4_INCLUDES}
       )
    
    # Тут ми додаємо наш код
    set(tutorial1_SRCS plasma-tutorial1.cpp)
    
    # Переконайтеся, що всі шляхи до файлів правильні
    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})
    

    Тестування аплета

    Якщо ваше середовище розробки відрізняється від тестової установки, ви повинні запускати cmake з параметром -DCMAKE_INSTALL_PREFIX=/usr/lib/kde4/ (замініть вашою змінною $KDEDIR). Потім запустіть make. Якщо результат вдалий, то аплет може бути встановлений за допомогою команди sudo make install чи

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

    та запуском kbuildsycoca4 (так додатки KDE дізнаються про нові файли *.desktop) Для тестового запуску вашoго аплета ви можете використовувати програму plasmoidviewer виконавши:

    plasmoidviewer applet_name
    

    Де applet_name значення, вказане в .desktop для ключа X-KDE-PluginInfo-Name.

    Або ви можете перезапустити плазму, так що аплет буде відображений у вікні вибору аплетів:

    kbuildsycoca4
    kquitapp plasma
    plasma
    

    Якщо так не працює, вам необхідно перезапустити вашу KDE сесію здійснивши вихід із системи та увійшовши знову.