Plasma's QML API
Intro
KDE Frameworks ships with a number of useful extensions to Qt’s QML. The API documentation is a good start if you need to know what a specific property does. If you want to browse any of the sources easier, it’s also available on GitLab.
PlasmaComponents Controls
QML ships with various controls, like CheckBox , RadioButton , ComboBox (dropdown menu), SpinBox , Slider , TextField , TextArea , Button , ToolButton . Plasma extends these controls to style them using the SVGs from the Plasma Theme. It also assigns a number of default settings like setting the text color to follow the panel’s color scheme.
PlasmaComponents 3 is a QML library that extends the Qt Quick Controls 2 components with defaults adapted to fit into Plasma widgets. Because PlasmaComponents 3 inherits from Qt Quick Controls 2, they have the same API, so the Qt documentation can be followed. For Plasma’s specific behaviour changes, you can read the QML source code for each control in:
plasma-framework
/src/declarativeimports/plasmacomponents3/
You may see leftover imports to PlasmaComponents 2 in some widgets. It uses the older Qt Quick Controls 1 components which are deprecated. The source code for the older controls can also be found in the plasma-frameworks
repo:
plasma-framework
/src/declarativeimports/plasmacomponents/qml/
Label
Labels are used for displaying text to the user. Plasma’s Label are assigned a number of defaults. One thing is it sets the text color to follow the panel’s color scheme.
For the specifics, you can read the Label.qml
source code.
// main.qml
import QtQuick 2.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
PlasmaComponents3.Label {
text: i18n("Hello World")
}
CheckBox - Toggle
For a simple toggle, QML ships with CheckBox . For Plasma’s specific changes, you can read the QML source code at:
// main.qml
import QtQuick 2.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
PlasmaComponents3.CheckBox {
text: i18n("Hello World")
checked: true
}
RadioButton - Multiple Choice
For mutiple choices, QML ships with RadioButton . For Plasma’s specific changes, you can read the QML source code at:
Note the KDE Human Interface Guidelines suggest using a ComboBox (dropdown menu) when your list is greater than 5 options.
// main.qml
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
ColumnLayout {
PlasmaComponents3.RadioButton {
text: i18n("Top")
checked: true
autoExclusive: true
}
PlasmaComponents3.RadioButton {
text: i18n("Bottom")
autoExclusive: true
}
}
ComboBox - Multiple Choice
For mutiple choices, QML also ships with ComboBox (dropdown menu). For Plasma’s specific changes, you can read the QML source code at:
Note that ComboBox.valueRole
and ComboBox.currentValue
was introduced in Qt 5.14. Ubuntu 20.04 only has Qt 5.12 so you will need to use the following properties until Ubuntu 22.04. Make sure to not define a currentValue
property or it will break when your users upgrade to Qt 5.14.
PlasmaComponents3.ComboBox {
textRole: "text"
property string _valueRole: "value"
readonly property var _currentValue: _valueRole && currentIndex >= 0 ? model[currentIndex][_valueRole] : null
}
// main.qml
import QtQuick 2.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
PlasmaComponents3.ComboBox {
textRole: "text"
valueRole: "value"
model: [
{ value: "a", text: i18n("A") },
{ value: "b", text: i18n("B") },
{ value: "c", text: i18n("C") },
]
}
Slider - Numbers
To control Integer or Real numbers, QML ships with Spinbox and Slider . For Plasma’s specific changes, you can read the QML source code at:
See the KDE Human Interface Guidelines to determine wither to use a Slider or a SpinBox.
// main.qml
import QtQuick 2.4
import QtQuick.Layouts 1.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
RowLayout {
PlasmaComponents3.Slider {
id: slider
Layout.fillWidth: true
from: 0
to: 100
value: 50
stepSize: 5
}
PlasmaComponents3.Label {
id: sliderValueLabel
function formatText(value) {
return i18n("%1%", value)
}
text: formatText(slider.value)
TextMetrics {
id: textMetrics
font.family: sliderValueLabel.font.family
font.pointSize: sliderValueLabel.font.pointSize
text: sliderValueLabel.formatText(slider.to)
}
Layout.minimumWidth: textMetrics.width
}
}
SpinBox - Numbers
To control Integer or Real numbers, QML ships with SpinBox and Slider . For Plasma’s specific changes, you can read the QML source code at:
See the KDE Human Interface Guidelines to determine wither to use a SpinBox or a Slider.
// main.qml
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
RowLayout {
PlasmaComponents3.Label {
text: i18n("Label:")
Layout.alignment: Qt.AlignRight
}
PlasmaComponents3.SpinBox {
from: 0
to: 100
value: 25
stepSize: 1
}
}
TextField, TextArea - Input
To enter text, QML ships with TextField and TextArea . For Plasma’s specific changes, you can read the QML source code for each:
See the KDE Human Interface Guidelines to determine wither to use a TextField (HIG calls it a Line Edit) or a TextArea.
// main.qml
import QtQuick 2.0
import QtQuick.Layouts 1.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
RowLayout {
PlasmaComponents3.Label {
Layout.alignment: Qt.AlignRight
text: i18n("Name:")
}
PlasmaComponents3.TextField {
placeholderText: i18n("Name")
}
}
import QtQuick 2.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
PlasmaComponents3.TextArea {
text: "Lorem ipsum\ndolor sit amet,\nconsectetur adipisicing elit"
}
Button, ToolButton
For buttons, QML ships with Button and the flat ToolButton version. For Plasma’s specific changes, you can read the QML source code for each:
// main.qml
import QtQuick 2.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
PlasmaComponents3.Button {
icon.name: "view-refresh"
text: i18n("Refresh")
}
// main.qml
import QtQuick 2.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
PlasmaComponents3.ToolButton {
icon.name: "view-refresh-symbolic"
text: i18n("Refresh")
}
ScrollView
To add a scrollbar to manage overflow, QML ships with ScrollView . For Plasma’s specific changes, you can read the QML source code at:
// main.qml
import QtQuick 2.0
import org.kde.plasma.components 3.0 as PlasmaComponents3
PlasmaComponents3.ScrollView {
id: scrollView
ListView {
model: 100
delegate: PlasmaComponents3.CheckBox {
text: i18n("CheckBox #%1", index+1)
}
}
}
PlasmaExtras
To be consistent with elsewhere in Plasma, Plasma ships with a couple of special components. These components have their own API and are particulary helpful when creating a Plama Widget.
You will need to import PlasmaExtras
to use them.
Heading, Paragraph
To be consistent with elsewhere in Plasma, Plasma ships with a couple different Label/Text
types with preset default sizes. The first one is
Heading
for subsections of texts and the second one is
Paragraph
.
Both wraps by default with Layout.fillWidth: true
.
// main.qml
import QtQuick 2.0
import QtQuick.Layouts 1.0
import org.kde.plasma.extras 2.0 as PlasmaExtras
ColumnLayout {
spacing: 0
Repeater {
model: 5
PlasmaExtras.Heading {
Layout.fillWidth: true
level: index + 1
text: i18n("Header level %1", level)
}
}
PlasmaExtras.Paragraph {
Layout.fillWidth: true
text: i18n("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sit amet turpis eros, in luctus lectus. Curabitur pulvinar ligula at leo pellentesque non faucibus mauris elementum. Pellentesque convallis porttitor sodales. Maecenas risus erat, viverra blandit vestibulum eu, suscipit in est. Praesent quis mattis eros. Sed ante ante, adipiscing non gravida sed, ultrices ultrices urna. Etiam congue mattis convallis. Maecenas sollicitudin mauris at lorem aliquam in venenatis erat convallis. Fusce eleifend scelerisque porttitor. Praesent metus sapien, hendrerit ac congue eget, feugiat id enim. Morbi venenatis gravida felis, vitae varius nunc dictum a. Etiam accumsan, velit ac tempor convallis, leo nibh consequat purus, sit amet fringilla nisi mi et libero.")
}
}
Plasmoid property group
As discussed in the main.qml
setup widget section, when you import org.kde.plasma.plasmoid 2.0
, the main Item
in your widget will have the Plasmoid
(with a capital) property group similar to when you import QtQuick.Layouts 1.0
. This Plasmoid
property group has properties from
AppletInterface
which inherits a few properties from PlasmaQuick::AppletQuickItem
.
Plasmoid.compactRepresentation
The compact representation uses DefaultCompactRepresentation.qml
by default. To summarize, it:
- Draws the
plasmoid.icon
using aPlasmaCore.IconItem
- Defines a
MouseArea
to toggle theexpanded
property which displays the full representation.
Plasmoid.fullRepresentation
If there’s enough room (more than Plasmoid.switchHeight
) then the widget’s full representation can be drawn directly in the panel or on the desktop. If you want to force this behaviour you can set Plasmoid.preferredRepresentation
.
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
If there isn’t enough room, then the widget will display Plasmoid.compactRepresentation
instead, and the full representation will be visible when plasmoid.expanded
is true
.
In a plasma widget, the full representation will be shown in a
PlasmaCore.Dialog
which you cannot access directly. You can manipulate the dialog with:
- Set
Layout.preferredWidth
andLayout.preferredHeight
in your full representationItem
to change to dialog size. - Set
Plasmoid.hideOnWindowDeactivate
to prevent the dialog from closing. You can use this to have a configurable “pin” like the digital clock widget does.
The dialog’s source code can be found in CompactApplet.qml
to see the exact behavior.
// main.qml
import QtQuick 2.0
import QtQuick.Layouts 1.0
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.plasmoid 2.0
Item {
// Always display the compact view.
// Never show the full popup view even if there is space for it.
Plasmoid.preferredRepresentation: Plasmoid.compactRepresentation
Plasmoid.fullRepresentation: Item {
Layout.minimumWidth: label.implicitWidth
Layout.minimumHeight: label.implicitHeight
Layout.preferredWidth: 640 * PlasmaCore.Units.devicePixelRatio
Layout.preferredHeight: 480 * PlasmaCore.Units.devicePixelRatio
PlasmaComponents.Label {
id: label
anchors.fill: parent
text: "Hello World!"
horizontalAlignment: Text.AlignHCenter
}
}
}
Plasmoid.icon
As discussed in the metadata.desktop
setup widget section, by default the plasmoid icon is populated with Icon=
in metadata.desktop
.
To set a dynamic or user configurable icon, you will need to assign an icon name to Plasmoid.icon
.
You can search for icon names in the /usr/share/icon
folder. You can also look for an icon name by right clicking your app launcher widget then editing the icon in its settings. It uses a searchable interface and lists them by category. Plasma’s SDK also has the Cuttlefish app (screenshot) which you can install with sudo apt install plasma-sdk
.
Also checkout the configurable panel icon example
// main.qml
import QtQuick 2.0
import org.kde.plasma.plasmoid 2.0
Item {
id: widget
property bool hasUnread: true
Plasmoid.icon: hasUnread ? "mail-unread" : "mail-message"
Timer {
interval: 1000
repeat: true
running: true
onTriggered: widget.hasUnread = !widget.hasUnread
}
}