Development/Tutorials/Plasma4/QML/GettingStarted

    From KDE TechBase
    Revision as of 16:38, 22 August 2011 by Sreich (talk | contribs) (→‎Package Structure: fixen fixen)

    Abstract

    Writing a plasma applet in QML is very easy, in fact, with KDE 4.6 and Qt 4.7 it just works.

    QML Basics

    It is recommended that you have read through the Qt QML Tutorials, as there are quite a few and they are explained thoroughly. There is also a list of all standard QML elements.

    Essentially, most of the content is the same. The exceptions to be noted are how data is gathered...since we use Data Engines, it is a bit different. Text color and font should be made to use PlasmaCore.Theme.

    See the KDE Examples repository for more KDE-related helpful resources. Also of use (which use QML and Plasma) are: Plasma Mobile, Declarative Plasmoids (playground), for WIP ports of C++ originals

    Root Item

    The root item can be anything that inherits QGraphicsItem. For example, in this case it is QGraphicsWidget which is a plasmoid. It can also simply be an Item. I also noticed that PathView does not respond to mouse inputs automatically (so flicking doesn't work). Probably because events are being intercepted. So take note, it'll have to be e.g. an Item, for that case.

    Layouts

    Row and Column

    Anchors

    Anchor layouts offer a nice way of grouping UI elements nicely together. The idea is that you connect edges or corners of one element to the edge or corner of another widget. Some examples:

    import QtQuick 1.0
    import org.kde.plasma.core 0.1 as PlasmaCore
    
    
    Item {
        width: 200
        height: 300
    
    
        Text {
            id: first
            text: i18n("1st line")
            anchors { 
                top: parent.top;
                left: parent.left;
                right: parent.right;
            }
        }
        Text {
            id: second
            text: i18n("2nd line")
            anchors {
                top: first.bottom;
                left: parent.left;
                right: parent.right;
                bottom: parent.bottom;
            }
        }
    }
    

    Buttons

    Animations

    Package Structure

    You create a .desktop file and the .qml file. They have to be in the usual plasma package structure.

    plasmoid-qml/metadata.desktop plasmoid-qml/contents/ui/main.qml

    metadata.desktop

    [Desktop Entry]
    Name=Hello QML
    Comment=A hello world widget in QML
    Icon=chronometer
    
    X-Plasma-API=declarativeappletscript
    X-Plasma-MainScript=ui/main.qml
    X-Plasma-DefaultSize=200,100
    
    X-KDE-PluginInfo-Author=Frederik Gladhorn
    X-KDE-PluginInfo-Email=[email protected]
    X-KDE-PluginInfo-Website=http://plasma.kde.org/
    X-KDE-PluginInfo-Category=Examples
    X-KDE-PluginInfo-Name=org.kde.hello-qml
    X-KDE-PluginInfo-Version=0.0
    
    X-KDE-PluginInfo-Depends=
    X-KDE-PluginInfo-License=GPL
    X-KDE-PluginInfo-EnabledByDefault=true
    X-KDE-ServiceTypes=Plasma/Applet
    Type=Service
    

    The line below indicates the starting minimum size of the plasmoid. The applet will become no smaller than this:

    X-Plasma-DefaultSize=200,100
    

    main.qml

    import QtQuick 1.0
    
    Text {
        text: "Hello world!";
    }
    

    Installing

    You can install your plasmoid, though obviously this is just temporary. CMake, below, is recommended: plasmapkg --install plasmoid-qml

    Installation through CMake

    In your CMakeLists.txt:

    project(helloqml)
    
    install(DIRECTORY package/
            DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids/org.kde.plasma.applet.myapplet)
    
    install(FILES package/metadata.desktop DESTINATION ${SERVICES_INSTALL_DIR} RENAME plasma-applet-myapplet.desktop)
    

    Your directory structure should now be as follows:

    myproject/CMakeLists.txt
    myproject/package/
    myproject/package/metadata.desktop
    myproject/package/contents/
    myproject/package/contents/ui/
    myproject/package/contents/ui/helloworld.qml
    

    (if you have a configuration file (.ui file) to load the right-click 'plasmoid settings' menu, then your structure will also have myproject/package/contents/config/config.ui, or so)

    plasmoidviewer

    You can run it in plasmoidviewer as usual: plasmoidviewer plasmoid-qml

    qmlviewer

    It's possible to use Plasma specific imports in qml files loaded by qmlviewer:

    qmlviewer -I /usr/lib/kde4/imports/ plasmoid-qml/contents/qml/main.qml

    Where the -I is the path to the plasma plugin for qml. Try to look for the path of /usr/lib/kde4/imports/org/kde/plasma/graphicswidgets/libgraphicswidgetsbindingsplugin.so and use everything up to org of that path.

    Hovewer it's strongly discouraged to use qmlviewer to develop plasmoids, because some features won't be available there, like the following:

    • localization with i18n()
    • access to the global plasmoid object
    • device specific qml files imported with plasmapackage:// urls
    • bindings for qicons, KJobs, services and KConfig
    • retrieving data from a DataEngine

    Therefore, it is recommended to simply use plasmoidviewer

    Features only available in Plasma widgets

    In order to have a better integration with the KDE platform and to reach an higher degree of expressivity, the stock features of QML have been expanded with the following features, that strictly follow the Plasmoid JavaScript API:

    Minimum size

    if the root object of the plasmoid has the properties minimumWidth and minimumHeight, they will be used as the minimum size for the plasmoid. If they will change during the plasmoid execution, the plasmoid minimum size will be updated accordingly.

    import QtQuick 1.0
    
    Text {
        property int minimumWidth: paintedWidth
        property int minimumHeight: paintedHeight
        text: "Hello world!";
    }
    

    In the above example, the minimum size is binded to the paintedWidth/paintedHeight properties of the Text element, ensuring there will always be enough room for the whole text to be displayed.

    Plasmoid object

    Every QML plasmoid will have an object called plasmoid, that will give access to the configuration, the formfactor, immutability and so on. It offers the same api as the object with the same name in the Javascript API.

    For specific info on this, see Javascript API-Plasmoid Object

    Localization

    It's possible to localize strings with the usual i18n(), i18nc(), i18np() global functions

    Extra types

    Some extra types are available from withing JavaScript, namely

    • KConfigGroup: it's an object with its config keys readable and writable as properties
    • QIcon: can be constructed with QIcon("fdo name") such as QIcon("konqueror")
    • KJob
    • Plasma Service api

    Plasma specific imports

    To use some Plasma specific features and to take advantage of them in order for your applet to become a true Plasma applet, it is necessary to use some particular QML imports. See Plasma QML API.

    Extra Qt features

    org.kde.qtextraimports To use, do:

    import org.kde.qtextracomponents 0.1 as QtExtraComponents
    
    • QPixmapItem
    • QImageItem
    • QIconItem

    Plasma Widgets in QML

    To use standard plasma widgets (e.g. Plasma::LineEdit, etc.), you simply add an import line for them. All properties, signals and slots from ordinary Plasma widgets are available there. These widgets are provided as a transition tool, intended to be replaced by the Plasma version of QtComponents, which is currently in development by a gsoc.

    import QtQuick 1.0
    import org.kde.plasma.graphicswidgets 0.1 as PlasmaWidgets
    
    Item {
        width: 64
        height: 64
        PlasmaWidgets.IconWidget {
            id: icon
            Component.onCompleted: setIcon("flag-red")
            anchors.centerIn: parent
        }
    }