Plasma/DeveloperGuide: Difference between revisions
No edit summary |
No edit summary |
||
Line 125: | Line 125: | ||
==QML & QtQuick== | ==QML & QtQuick== | ||
[https://en.wikipedia.org/wiki/QML Wikipedia] has an excellent description | [https://en.wikipedia.org/wiki/QML Wikipedia] has an excellent description | ||
''QML (Qt Meta Language or Qt Modeling Language) is a user interface markup language. It is a JavaScript-based, declarative language for designing user interface–centric applications. It is part of Qt Quick, the UI creation kit | ''QML (Qt Meta Language or Qt Modeling Language) is a user interface markup language. It is a JavaScript-based, declarative language for designing user interface–centric applications. It is part of Qt Quick, the UI creation kit within the Qt framework. QML is used for desktop and mobile applications where touch input, fluid animations (60 FPS) and user experience are crucial. QML documents describe an object tree of elements. QML elements shipped with Qt are a sophisticated set of building blocks, graphical (e.g., rectangle, image) and behavioral (e.g., state, transition, animation). These elements can be combined to build components ranging in complexity from simple buttons and sliders, to complete internet-enabled programs.'' | ||
''QML elements can be augmented by standard JavaScript both inline and via included .js files. Elements can also be seamlessly integrated and extended by C++ components using the Qt framework.'' | ''QML elements can be augmented by standard JavaScript both inline and via included .js files. Elements can also be seamlessly integrated and extended by C++ components using the Qt framework.'' | ||
''QML is the language; its runtime is the Javascript V4 engine and Qt Quick is the scenegraph-based UI framework. | ''QML is the language; its runtime is the Javascript V4 engine and Qt Quick is the scenegraph-based UI framework.'' (slightly redacted for clarity purposes) | ||
Your QtQuick code "tree" describes an object-tree structure of visual items, such as images or text and non-visual items, such as data models or object collections. The visual structure is displayed in an OpenGL scenegraph. This allows us to manipulate and compose visual items in the UI directly on the graphics card. This leads to high-performance graphics on the one, and energy savings on the other hand. Graphics hardware is much more efficient for graphics manipulation than the central system processor. | |||
QtQuick code is loaded at runtime and just-in-time compiled into the javascript's engine's binary representation on application startup. | |||
QtQuick makes it very easy to create attractive user interfaces with smooth animations. QtQuick UIs support multitouch, mouse and keyboard inputs, allow handling of gestures. Most importantly, QtQuick is easy to write and change, and it is an intuitive language very well suited for creating modern UI with a gentle learning curve. | |||
On top of these fundamentals, you will want more high-level functionality. This is where "imports" enter the picture. | |||
==Imports== | ==Imports== | ||
QtQuick applications, such as your Plasma app, can be extended using imports. An import is a Qt plugin that is dynamically loaded at runtime. imports can consist of QML items (used as custom types once imported) or compiled libraries that export C++ functions and objects (often QObject based) to the QML runtime. Import plugins can contain QML files, a C++ plugins or both. | QtQuick applications, such as your Plasma app, can be extended using imports. An import is a Qt plugin that is dynamically loaded at runtime. imports can consist of QML items (used as custom types once imported) or compiled libraries that export C++ functions and objects (often QObject based) to the QML runtime. Import plugins can contain QML files, a C++ plugins or both. QML imports are also often referred to as ''components''. | ||
Imports | Imports allow you to use libraries from QML and javascript and to re-use or share code between different applications, for example across packages. QtQuick items 'understand' a useful number of Qt's standard types, such as QString, QAbstractItemModel, QColor, QDate, etc.. Builtin javascript types such as string, int, float are also supported. | ||
You can write an import yourself, though most of the time you will find yourself using already existing imports. | You can write an import yourself, though most of the time you will find yourself using already existing imports. | ||
Line 147: | Line 155: | ||
PlasmaComponents.Label { | PlasmaComponents.Label { | ||
text: "" | text: "Ultimate Plasma Hacking" | ||
/* ... */ | /* ... */ | ||
} | } | ||
It's recommended to always import QtQuick into the global namespace and to import other modules into their respective namespaces. This also improves code readability and makes it easier to debug since the code tells us where to look or where something actually comes from. It also avoids naming clashes. | It's recommended to always import QtQuick into the global namespace and to import other modules into their respective namespaces, such as in this case ''PlasmaComponents''. This also improves code readability and makes it easier to debug since the code tells us where to look or where something actually comes from. It also avoids naming clashes -- there may be other UI components | ||
Commonly useful imports are: | |||
===PlasmaCore=== | |||
import org.kde.plasma.components 2.0 as PlasmaComponents | |||
PlasmaCore provides lower-level functionality for your app: | |||
* '''units''' for DPI support, units.gridUnit is commonly used to describe sizes, gridUnits provide consistent sizing across the complete spectrum and has been tested to work between 100 and 500 DPI. | |||
* '''SvgItem''' and its friends allow to you load and use scalable SVG graphics in your UI. SvgItem and friends are backed by a rendering cache and offload as much as possible to the GPU. '''FrameSvgItem''' provides a correctly scaled and efficient mechanism to render and resize frame-like SVG graphics with correct sizing of corners. | |||
* '''ColorScope''' allows you to change the color scheme for a part of your application in a consistent way. | |||
KDE's can find a comprehensive list of [http://api.kde.org/frameworks-api/frameworks5-apidocs/plasma-framework/html/core.html PlasmaCore's API]. | |||
==Plasma Libraries== | ==Plasma Libraries== | ||
Revision as of 23:12, 25 August 2015
The Ultimate Guide to Plasma Development
Introduction
This guide explains the basic steps to build a fully integrated application. This guide is targeted at developers with basic knowledge of QML. It guides through the complete process of developing an application from scratch.
Plasma allows to write applications that work well on different form factors or devices. Plasma is built to adapt to different input methods (mouse, touch, keyboard, etc.) screen sizes and to be resolution-independent. Most of the information in this guide is applicable to all form factors. Topics that may differ for different form factors are indicated as such.
A well-architectured Plasma application will be able to offer different user interface per form factor. For desktops, a landscape layout with quite a lot of space for display and interaction can be used, while the same underlying components in a different, portrait-oriented layout can be used to present the user interface on a phone. A tablet user interface may use either, or combine the components in yet another fashion to make the best use of available screen real estate. In general, Plasma widgets such as buttons and other controls, work well on touch, mouse and with keyboard input, but can be switched at application start or runtime, transparently to the application using it.
In this guide, you will learn how to use all these features to create an application that works well on wide range of target devices.
Is this guide for you?
Plasma makes extensive use of QtQuick and QML to write the user interface and business logic of your application. Basic understanding of QtQuick is necessary, though Plasma is also a great environment to learn by doing it. This guide targets developers that are familiar with common programming paradigms, but do not have special knowledge of the Plasma APIs, libraries and mechanisms to solve certain problems.
Many things can be implemented without knowing or being able to write C++ code. Plasma provides high-level APIs to solve a great number of tasks and provide common functionality such as retrieving data, displaying information as well as widgets for common interaction patterns and themes and artwork to make your app beautiful and consistent.
In some cases, or in more complex apps, you may extend the functionality by writing a C++ plugin (or "import"). This allows to access custom functionality in your system, leverage an existing library, or move logic into a type-safe language that is easier to test (using unit tests, for example) or performs better.
Apps, Widgets and Plasmoids?
Plasma offers user interfaces for applications as well as workspaces (the environment you run your app in, the desktop, or phone user interface offering a launcher, task switcher, settings, for example).
The workspace can be extended using Plasma Widgets, or in more technical terms, plasmoids. A plasmoid is a package containing metadata, images, configuration defaults and the QML files that make up the UI. Most of Plasma Desktop's functionality is offered using plasmoids. The application launcher in the bottom-left corner is a plasmoid, the task manager in the panel which allows you to switch between running applications is a plasmoid, many of the widgets in the notification area on both, Plasma Mobile and Plasma Desktop are plasmoids. You can also put Plasmoids on your desktop, the analog clock widgets and the "post-it" notes plasmoids are popular examples.
Apps are loaded from packages as well. The main difference, aside from the layout probably being different, is that instead of loading the QML code inside a panel, or widget on the desktop, the application is loaded into its own window. (There are certain API features which may only make sense in the workspace, but those are usually implementation details that can be ignored where they don't make sense.)
An app or a plasmoid would typically load the main layout for the window, popup or widget from a QML file, and then use imports to load additional libraries or make APIs available from within the applications QML code.
An app in 5 easy steps
Creating a simple application in Plasma is very easy.
- Download an exampletemplate
- Adjust the package metadata
- Edit the QML code
- Install the plasmoid
- Run it to try it out
Download an example
You can create your own plasmoid from a simple example, shipped with the plasma-framework source code from git:
git clone git://anongit.kde.org/plasma-framework
Then copy a basic example, which is going to be your new plasmoid. Let's call it "myplasmoid":
cp -R plasma-framework/examples/developerguide/basic myplasmoid
==Adjust the plasmoid's metadata==
Open myplasmoid/metadata.desktop with your favorite text editor (mine is "Kate"):
kate myplasmoid/metadata.desktop
and change the Name and Comment fields. These will identify your Plasmoid in the widget chooser, be the default window name,
Name=My Plasmoid Comment=Plasma Hacker 101
You can also pick a nice icon here. Use for example the cuttlefish tool to pick a nice one.
Now change the line containing the X-KDE-PluginInfo-Name key to a different plugin id:
X-KDE-PluginInfo-Name=org.example.myplasmoid
The plugin name is used to identify the plugin on the system, make sure you pick a unique plugin name. It's advised to use a reverse domain name pattern. The plugin name will also be used in the installation path.
Edit the QML code
In order to change the template and write your own code, open its main QML file and hack away.
kate myplasmoid/contents/ui/main.qml
Play around with it a bit, try to change something, add a few new things, make yourself comfortable with it. For simple, first testing, you can also just skip this step for now, install as is to see if everything works in a clean environment and get back to actually changing the code later on.
Installing the plasmoid
To install a plasmoid, you can use the "kpackagetool5" program:
kpackagetool5 -i myplasmoid
This will install the plasmoid locally in your home directory, into ~/.local/share/kpackage/genericqml/org.example.myplasmoid on my system -- your installation path may vary. To update an already-installed package on your system, use
kpackagetool5 -u myplasmoid
to remove it, use
kpackagetool5 -r myplasmoid
Running it
You can now start your brand-new app using kpackagelauncherqml:
kpackagelauncherqml -a org.example.myplasmoid
And a window will show up with your application. You can now start hacking.
Requirements Analysis & Design
The first step to building an application is to analyze the problem that you want to solve and come up with a way how you can solve this problem. This allows you to make a list of required features for your application. A clear purpose and understanding of what want to achieve and how you want to get there helps you to make smart choices regarding features, their design and presentation. It can also avoid bloat and helps to set priorities for the app's development work.
In the design phase, you care about three things: interaction, visual and technical design. The interaction design is the workflow for the user. You can visualize this in a flowchart, for example. This flowchart should give you an idea of which steps or views you want to present to the user, and which options should be available in each of them.
In the visual design phase, you draw you user interfaces, views, screens and plan how things are laid out on screen. You can use pen and paper for it, but also tools like inkscape and the Plasma mockup toolkit. KDE's Human Interface Guidelines provide many useful tips how you can create intuitive user interfaces with a high level of consistency.
We encourage you to present your ideas, concepts and design and discuss it, for example in the KDE Forums or on the [FIXME Plasma Mailinglist] to refine your design further and get input from more points of view.
You can find more information about design workflows, tools and resources on this page.
Software Stack
The software stack consists of a number of components that are interesting for application development. This chapter gives an overview of the most important pieces to consider.
QML & QtQuick
Wikipedia has an excellent description
QML (Qt Meta Language or Qt Modeling Language) is a user interface markup language. It is a JavaScript-based, declarative language for designing user interface–centric applications. It is part of Qt Quick, the UI creation kit within the Qt framework. QML is used for desktop and mobile applications where touch input, fluid animations (60 FPS) and user experience are crucial. QML documents describe an object tree of elements. QML elements shipped with Qt are a sophisticated set of building blocks, graphical (e.g., rectangle, image) and behavioral (e.g., state, transition, animation). These elements can be combined to build components ranging in complexity from simple buttons and sliders, to complete internet-enabled programs. QML elements can be augmented by standard JavaScript both inline and via included .js files. Elements can also be seamlessly integrated and extended by C++ components using the Qt framework. QML is the language; its runtime is the Javascript V4 engine and Qt Quick is the scenegraph-based UI framework. (slightly redacted for clarity purposes)
Your QtQuick code "tree" describes an object-tree structure of visual items, such as images or text and non-visual items, such as data models or object collections. The visual structure is displayed in an OpenGL scenegraph. This allows us to manipulate and compose visual items in the UI directly on the graphics card. This leads to high-performance graphics on the one, and energy savings on the other hand. Graphics hardware is much more efficient for graphics manipulation than the central system processor.
QtQuick code is loaded at runtime and just-in-time compiled into the javascript's engine's binary representation on application startup.
QtQuick makes it very easy to create attractive user interfaces with smooth animations. QtQuick UIs support multitouch, mouse and keyboard inputs, allow handling of gestures. Most importantly, QtQuick is easy to write and change, and it is an intuitive language very well suited for creating modern UI with a gentle learning curve.
On top of these fundamentals, you will want more high-level functionality. This is where "imports" enter the picture.
Imports
QtQuick applications, such as your Plasma app, can be extended using imports. An import is a Qt plugin that is dynamically loaded at runtime. imports can consist of QML items (used as custom types once imported) or compiled libraries that export C++ functions and objects (often QObject based) to the QML runtime. Import plugins can contain QML files, a C++ plugins or both. QML imports are also often referred to as components.
Imports allow you to use libraries from QML and javascript and to re-use or share code between different applications, for example across packages. QtQuick items 'understand' a useful number of Qt's standard types, such as QString, QAbstractItemModel, QColor, QDate, etc.. Builtin javascript types such as string, int, float are also supported. You can write an import yourself, though most of the time you will find yourself using already existing imports.
In your app, you can import additional functionality like this:
import QtQuick 2.3 import org.kde.plasma.components 2.0 as PlasmaComponents
This imports QtQuick's standard items into the global namespace, that means you can now use types like Item {}. The second line imports the org.kde.plasma.components plugin into the PlasmaComponents QML namespace. This means you refer to its types like this:
PlasmaComponents.Label { text: "Ultimate Plasma Hacking" /* ... */ }
It's recommended to always import QtQuick into the global namespace and to import other modules into their respective namespaces, such as in this case PlasmaComponents. This also improves code readability and makes it easier to debug since the code tells us where to look or where something actually comes from. It also avoids naming clashes -- there may be other UI components
Commonly useful imports are:
PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
PlasmaCore provides lower-level functionality for your app:
- units for DPI support, units.gridUnit is commonly used to describe sizes, gridUnits provide consistent sizing across the complete spectrum and has been tested to work between 100 and 500 DPI.
- SvgItem and its friends allow to you load and use scalable SVG graphics in your UI. SvgItem and friends are backed by a rendering cache and offload as much as possible to the GPU. FrameSvgItem provides a correctly scaled and efficient mechanism to render and resize frame-like SVG graphics with correct sizing of corners.
- ColorScope allows you to change the color scheme for a part of your application in a consistent way.
KDE's can find a comprehensive list of PlasmaCore's API.
Plasma Libraries
- underlying frameworks - runtime environment - kpackage
Getting Started
Developing a Plasmoid
Creating the empty package
filesystem structure
metadata.desktop
- system integration (systray, alternatives, mimetypes, arguments, formfactors)
Choosing a Category
The following are acceptable known entries for plasmoids and applets. If your applet does not fall within one of the following categories, leave the category field empty (it will be automatically categorized under "Miscellaneous" for the time being) and contact the Plasma development team to have a suitable category added to the list (at which point you may then use that category).
- Accessibility tools that help those with special needs or disabilities use their computer
- Application Launchers application starters and file openers.
- Astronomy anything to do with the night sky or other celestial bodies.
- Date and Time clocks, calendars, scheduling, etc
- Development Tools tools and utilities to aid software developers
- Education teaching and educational aides
- Environment and Weather add-ons that display information regarding the weather or other environmentally related data
- Examples samples that are not meant for production systems
- File System anything that operates on files or the file system as it's primary purpose, such as file watchers or directory listings. Simply using a file as storage does not qualify the add-on for this category.
- Fun and Games for games and amusements
- Graphics for add-ons where displaying images, photos or graphical eye candy is the primary purpose
- Language add-ons whose primary purpose is language related, such as dictionaries and translators.
- Mapping geography and geographic data add-ons
- Multimedia music and video.
- Online Services add-ons that provide an interface to online services such as social networking or blogging sites. If there is another more appropriate category for the add-on given the topic (e.g. mapping if the applet's purpose is to show maps), even if the data is retrieved from the Internet prefer that other category over this one.
- System Information display and interaction with information about the computer such as network activity, hardware health, memory usage, etc
- Utilities Useful tools like calculators
- Windows and Tasks managers for application windows and/or tasks, such as taskbars
installation
- cmake - plasmapkg2
Starting the Code
main.qml stuffz
- Layouts - plasmoid object - fullRepresentation vs. popup
Plasma API
+ links to API documentation! - PlasmaCore - PlasmaComponents - PlasmaExtras - kdeclarative's useful stuff: kcmOpen? more useful imports
- general guidelines: units, iconSizes,
Development Environment Setup
Tools
- editor - commandline - plasmapkg2 - plasmoidviewer - plasmathemething - cuttlefish -
Display and Rendering
- theming - image display - dpi - ColorScope - Wayland vs. X11
Supporting Multiple Devices
- touch friendliness - layout considerations - formfactor support (X-KDE-FormFactors) - touch-specific overrides
Workspace Integration
- system tray - plasmoid status - dbus autoload
Translations
- i18n() & friends - making sure i18n is set up & how to x-test
Distribution
- plasmoid package - appstream metadata - kdeapps online installation - distros - upstreaming code