Nova Flow OS
KDE Developer Platform
KDE Developer Platform
  • KDE Developer Platform
    • Getting started
      • Building KDE software
        • KDE software
        • Where to find the development team
        • Learning more
        • Choose what to work on
        • Source code cross-referencing
        • Installing build dependencies
        • Set up a development environment
        • Building KDE software with kdesrc-build
        • Basic troubleshooting
        • Tips and tricks
        • IDE Configuration
          • Setting up an IDE for KDE development
          • Visual Studio Code
          • Qt Creator
          • Kate
          • KDevelop
          • CLion
          • Sublime Text
        • Building KDE software manually
        • Building KDE software with distrobox and podman
      • Kirigami
        • KDE is ours
        • Setting up and getting started
        • Explaining pages
        • Layouts, ListViews, and Cards
        • Adding actions
        • Adding a dialog
        • Using separate files
        • Next steps
        • Colors and themes in Kirigami
        • Typography
        • Actions based components
        • Page rows and page stacks
        • Scrollable pages and list views
        • Cards
        • Drawers
        • Chips
        • Dialog types
        • Controls and interactive elements
        • Form layouts
        • Inline messages
        • Action toolbars
        • Progress bars and indicators
        • List views
        • Understanding CMakeLists
        • Figuring out main.cpp
        • Connect logic to your QML user interface
        • Connect models to your QML user interface
        • About page
        • Introduction to Kirigami Addons
        • FormCard About pages
        • Form delegates in your settings pages
      • KXmlGui
        • Getting started with KXmlGui
        • Hello World!
        • Creating the main window
        • Using actions
        • Saving and loading
        • Command line interface
      • Python with Kirigami
        • Apps with QML and Python
        • Your first Python + Kirigami application
        • Creating a Python package
        • Creating a Flatpak
      • Common programming mistakes
      • Adding a new KDE project
    • Features
      • Icons
      • Configuration
        • The KConfig Framework
        • Introduction to KConfig
        • Using KConfig XT
        • KDE Frameworks 6 porting guide
        • Settings module (KCM) development
        • KConfigDialog
      • D-Bus
        • What is D-Bus practically useful for?
        • Introduction to D-Bus
        • Accessing D-Bus interfaces
        • Intermediate D-Bus
        • Creating D-Bus interfaces
        • Using custom types with D-Bus
        • D-Bus autostart services
      • Create your own mouse cursor theme
      • Session management
      • Archives
      • Desktop file
      • KAuth
        • Privilege Escalation
        • Using actions in your applications
      • KIdleTime
      • Akonadi: personal information management
        • Debugging Akonadi Resources
        • Using Akonadi in applications
      • Concurrent programming
      • Solid
      • Sonnet
    • Plasma themes and plugins
      • Getting started
      • Plasma Widget tutorial
        • How to create a plasmoid
        • Setup
        • Porting Plasmoids to KF6
        • Testing
        • QML
        • Plasma's QML API
        • Widget Properties
        • Configuration
        • Translations / i18n
        • Examples
        • C++ API
      • KWin Effects
      • Plasma Desktop scripting
        • Javascript Interaction With Plasma Shells
        • Templates
        • Examples
        • API documentation
        • Configuration keys
      • Plasma Style tutorial
        • Creating a Plasma Style quickstart
        • Understanding Plasma Styles
        • SVG elements and Inkscape
        • Background SVG format
        • System and accent colors
        • Theme elements reference
        • Porting themes to Plasma 5
        • Porting themes to Plasma 6
      • Aurorae window decorations
      • KWin scripting tutorial
        • Quick start
        • KWin scripting API
      • Wallpapers
      • Plasma comic
        • Tutorial
        • Testing and debugging
        • Examples
      • Create a custom Window Switcher
      • KRunner C++ Plugin
        • Basic Anatomy of a Runner
        • KRunner metadata format
    • Applications
      • Creating sensor faces
      • Dolphin
        • Creating Dolphin service menus
      • Kate
        • Kate plugin tutorial
      • KMines
        • Making a KMines theme
      • Writing tests
        • Appium automation testing
    • Packaging
      • Android
        • KDE on Android
        • Building applications for Android
        • Packaging and publishing applications for Android
        • Publishing on Google Play
          • Introduction
          • Packaging your app
          • Adding your app to Google Play
          • Publishing your app
          • Releasing new versions of old apps
        • Porting applications to Android
          • Basic porting
          • Making applications run well on Android
          • Metadata
      • Windows
        • Packaging and publishing applications for Windows
        • Publish your app in the Microsoft Store
          • Packaging your app for the Microsoft Store
          • Submitting your app to the Microsoft Store
      • Plasma Mobile
        • KDE on mobile devices
        • Porting a new device to Plasma Mobile
        • KDE Telephony stack
          • General Overview
          • Kernel layer
          • System daemons
            • General overview
            • Developing Telephony functionality
            • ModemManager Telephony functions
          • Session daemons
          • QML declarative plugin layer
          • KDE application layer
        • Execute applications
      • Distributing KDE software as Flatpak
        • Your first Flatpak
        • Extending your package
        • Nightly Flatpaks and Flathub
        • Testing your Flatpak
    • System administration
      • Shell scripting with KDE dialogs
      • Kiosk: Simple configuration management for large deployment
        • Abstract
        • Introduction to Kiosk
        • Kiosk keys
    • Contribute to the documentation
    • About
      • Readme
      • License
        • Creative Commons Attribution-ShareAlike 4.0 International
        • GNU General Public License 3.0 or later
Powered by GitBook
On this page
  • Configuration Intro
  • contents/config/main.xml
  • contents/config/config.qml
  • contents/ui/configGeneral.qml
  • configPage.cfg_variableName
  • CheckBox - Boolean
  • SpinBox - Integer
  • SpinBox - Double/Real
  • TextField - String/Text
  • TextArea - Multi-Line String/Text
  • ColorButton - Color
  • FileDialog - Path
  • IconDialog - Icon
  • Assigning to plasmoid.configuration.varName
  • Configuration Examples
  • No-Apply Control Library
  1. KDE Developer Platform
  2. Plasma themes and plugins
  3. Plasma Widget tutorial

Configuration

Adding user configured settings to your widget

PreviousWidget PropertiesNextTranslations / i18n

Last updated 8 months ago

Configuration Intro

Every widget by default has a configure action when you right click the widget called MyWidget Settings.... By default it will contain a form to set a global shortcut to activate your widget.

contents/config/main.xml

main.xml is where you define the properties that will be serialized into ~/.config/plasma-org.kde.plasma.desktop-appletsrc. All properties will be accessible with plasmoid.configuration.variableName regardless of what group it's in.

  • Int for an Integer number

  • Double for a double precision floating point number (Real)

  • String for a string of characters to represent text

  • Color for a hexadecimal color. The color defaults to #000000 (black) if the default is left empty.

  • Path is a string that is specially treated as a file-path. In particular paths in the home directory are prefixed with $HOME when being stored in the configuration file.

  • StringList for a comma separated list of Strings


I personally don't recommend using Color if you want to default to a color from the color scheme (eg: PlasmaCore.ColorScope.textColor). I would instead suggest using a String that is empty by default. You can then use the following in the QML:

<entry name="labelColor" type="String">
    <default></default>
</entry>
PlasmaComponents.Label {
    color: plasmoid.configuration.labelColor || PlasmaCore.ColorScope.textColor
}

contents/config/main.xml

<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
    <kcfgfile name=""/>

    <group name="General">
        <entry name="variableName" type="Bool">
            <default>true</default>
        </entry>
        <entry name="integerExample" type="Int">
            <default>6</default>
        </entry>
        <entry name="floatingPointExample" type="Double">
            <default>3.1459</default>
        </entry>
        <entry name="textExample" type="String">
            <default>Hello World</default>
        </entry>
        <entry name="listExample" type="StringList">
            <default>First Item,Second Item,Third Item</default>
        </entry>
        <entry name="colorExample" type="Color">
            <default>#336699</default>
        </entry>
    </group>
    <group name="AnotherGroup">
        <entry name="secondGroupExample" type="Bool">
            <default>false</default>
        </entry>
    </group>
</kcfg>

contents/config/config.qml

config.qml is where we define the tabs in the configuration window.

We import the ConfigModel and ConfigCategory, and define the tab name, icon, and qml file that will be loaded. {{< /section-left >}} {{< section-right >}}

contents/config/config.qml

import QtQuick 2.0
import org.kde.plasma.configuration 2.0

ConfigModel {
    ConfigCategory {
        name: i18n("General")
        icon: "configure"
        source: "configGeneral.qml"
    }
    ConfigCategory {
        name: i18n("Another Tab")
        icon: "color-management"
        source: "configAnotherTab.qml"
    }
}

contents/ui/configGeneral.qml

configGeneral.qml is where we can place all the checkboxes and textboxes.

Please note that your should not use PlasmaComponents.* controls in the config window, as those are styled and colored for the panel. The normal QtQuick.Controls are styled using your application window style + colors.

Kirigami.FormLayout is used to layout the controls in the center of the page. The Kirigami.FormData.label attached property is used to place labels in front of the controls. Kirigami labels are optional, so you do not need to use them for CheckBoxes which have their own labels on the right.

contents/ui/configGeneral.qml

import QtQuick 2.0
import QtQuick.Controls 2.5 as QQC2
import org.kde.kirigami 2.4 as Kirigami

Kirigami.FormLayout {
    id: page
  
    property alias cfg_showLabel: showLabel.checked
    property alias cfg_showIcon: showIcon.checked
    property alias cfg_labelText: labelText.text

    QQC2.CheckBox {
        id: showLabel
        Kirigami.FormData.label: i18n("Section:")
        text: i18n("Show label")
    }
    QQC2.CheckBox {
        id: showIcon
        text: i18n("Show icon")
    }
    QQC2.TextField {
        id: labelText
        Kirigami.FormData.label: i18n("Label:")
        placeholderText: i18n("Placeholder")
    }
}

configPage.cfg_variableName

By default, all values are copied to the top level Item of the file prefixed with cfg_ like page.cfg_variableName. This is so the user can hit discard or apply the changes. You will need to define each cfg_ property so you can bind the value with a QML control.

contents/ui/configGeneral.qml

import QtQuick 2.0
import QtQuick.Controls 2.5 as QQC2
import org.kde.kirigami 2.4 as Kirigami

Kirigami.FormLayout {
    id: page
    property alias cfg_variableName: variableName.checked

    QQC2.CheckBox {
        id: variableName
        Kirigami.FormData.label: i18n("Icon:")
        text: i18n("Show")
    }
}

CheckBox - Boolean

contents/config/main.xml

<entry name="variableName" type="Bool">
    <default>true</default>
</entry>

contents/ui/configGeneral.qml

import QtQuick 2.0
import QtQuick.Controls 2.5 as QQC2
import org.kde.kirigami 2.4 as Kirigami

Kirigami.FormLayout {
    id: page
    property alias cfg_variableName: variableName.checked

    QQC2.CheckBox {
        id: variableName
    }
}

SpinBox - Integer

contents/config/main.xml

<entry name="variableName" type="Int">
    <default>6</default>
</entry>

contents/ui/configGeneral.qml

import QtQuick 2.0
import QtQuick.Controls 2.5 as QQC2
import org.kde.kirigami 2.4 as Kirigami

Kirigami.FormLayout {
    id: page
    property alias cfg_variableName: variableName.value

    QQC2.SpinBox {
        id: variableName
    }
}

SpinBox - Double/Real

contents/config/main.xml

<entry name="variableName" type="Double">
    <default>3.1459</default>
</entry>

contents/ui/configGeneral.qml

import QtQuick 2.0
import QtQuick.Controls 1.0 as QtControls1
import org.kde.kirigami 2.4 as Kirigami

Kirigami.FormLayout {
    id: page
    property alias cfg_variableName: variableName.value

    QtControls1.SpinBox {
        id: variableName
        decimals: 2
    }
}

TextField - String/Text

contents/config/main.xml

<entry name="variableName" type="String">
    <default>Hello World</default>
</entry>

contents/ui/configGeneral.qml

import QtQuick 2.0
import QtQuick.Controls 2.5 as QQC2
import org.kde.kirigami 2.4 as Kirigami

Kirigami.FormLayout {
    id: page
    property alias cfg_variableName: variableName.text

    QQC2.TextField {
        id: variableName
    }
}

TextArea - Multi-Line String/Text

contents/config/main.xml

<entry name="variableName" type="String">
    <default>Hello World</default>
</entry>

contents/ui/configGeneral.qml

import QtQuick 2.0
import QtQuick.Controls 2.5 as QQC2
import org.kde.kirigami 2.4 as Kirigami

Kirigami.FormLayout {
    id: page
    property alias cfg_variableName: variableName.text

    QQC2.TextArea {
        id: variableName
    }
}

ColorButton - Color

contents/config/main.xml

<entry name="variableName" type="Color">
    <default>#336699</default>
</entry>

I personally don't recommend using the Color data type in main.xml if you want the default color to be a color from the color scheme (eg: PlasmaCore.ColorScope.textColor). I would instead suggest using a String that is empty by default. You can then use the following:

<entry name="labelColor" type="String">
    <default></default>
</entry>
PlasmaComponents.Label {
    color: plasmoid.configuration.labelColor || PlasmaCore.ColorScope.textColor
}

contents/ui/configGeneral.qml

import QtQuick 2.0
import org.kde.kirigami 2.4 as Kirigami
import org.kde.kquickcontrols 2.0 as KQControls

Kirigami.FormLayout {
    id: page
    property alias cfg_variableName: variableName.color

    KQControls.ColorButton {
        id: variableName
        showAlphaChannel: true
    }
}

FileDialog - Path

Note that we place the Kirigami.FormData.label in the RowLayout as it is the direct child of Kirigami.FormLayout.

contents/config/main.xml

<entry name="variableName" type="Path">
    <default>/usr/share/sounds/freedesktop/stereo/message.oga</default>
</entry>

contents/ui/configGeneral.qml

import QtQuick 2.0
import QtQuick.Controls 2.5 as QQC2
import QtQuick.Dialogs 1.0 as QQD
import QtQuick.Layouts 1.0
import org.kde.kirigami 2.4 as Kirigami

Kirigami.FormLayout {
    id: page
    property alias cfg_variableName: variableName.text

    RowLayout {
        Kirigami.FormData.label: i18n("Sound File:")

        QQC2.TextField {
            id: variableName
            placeholderText: i18n("No file selected.")
        }
        QQC2.Button {
            text: i18n("Browse")
            icon.name: "folder-symbolic"
            onClicked: fileDialogLoader.active = true

            Loader {
                id: fileDialogLoader
                active: false

                sourceComponent: QQD.FileDialog {
                    id: fileDialog
                    folder: shortcuts.music
                    nameFilters: [
                        i18n("Sound files (%1)", "*.wav *.mp3 *.oga *.ogg"),
                        i18n("All files (%1)", "*"),
                    ]
                    onAccepted: {
                        variableName.text = fileUrl
                        fileDialogLoader.active = false
                    }
                    onRejected: {
                        fileDialogLoader.active = false
                    }
                    Component.onCompleted: open()
                }
            }
        }
    }
}

IconDialog - Icon

Assigning to plasmoid.configuration.varName

You can also assign directly to plasmoid.configuration.variableName if necessary in the configuration window or anywhere else in your widget. If you do this in the configuration page, you will skip the "apply" process and the property will be applied right away. I leave this up to the reader whether this is a pro or con.

contents/ui/configGeneral.qml

import QtQuick 2.0
import QtQuick.Controls 2.5 as QQC2
import QtQuick.Layouts 1.0
import org.kde.kirigami 2.4 as Kirigami

Kirigami.FormLayout {
    id: page

    QQC2.CheckBox {
        id: variableName
        checked: plasmoid.configuration.variableName
        onCheckedChanged: plasmoid.configuration.variableName = checked
    }
}

Configuration Examples

To learn by example, we can look at a couple widgets:

  • Application Launcher

  • Task Manager

No-Apply Control Library

Zren has written a few files that apply the above pattern of skipping "Apply" and updating right after you change the value.

cd ~/Code/plasmoid-helloworld/package/contents/ui
mkdir -p ./libconfig
cd ./libconfig
wget https://github.com/Zren/plasma-applet-lib/archive/master.zip
unzip -j master.zip plasma-applet-lib-master/package/contents/ui/libconfig/*
rm master.zip

contents/ui/libconfig/CheckBox.qml

import QtQuick 2.0
import QtQuick.Controls 2.0 as QQC2

QQC2.CheckBox {
    id: configCheckBox

    property string configKey: ''
    checked: plasmoid.configuration[configKey]
    onClicked: plasmoid.configuration[configKey] = !plasmoid.configuration[configKey]
}

contents/ui/configGeneral.qml

import QtQuick 2.0
import org.kde.kirigami 2.4 as Kirigami
import "./libconfig" as LibConfig

Kirigami.FormLayout {
    id: page

    LibConfig.CheckBox {
        Kirigami.FormData.label: i18n("CheckBox:")
        configKey: 'showVariable'
    }

    LibConfig.ColorField {
        Kirigami.FormData.label: i18n("ColorField:")
        configKey: 'labelColor'
        defaultColor: PlasmaCore.ColorScope.textColor
    }

    LibConfig.ComboBox {
        Kirigami.FormData.label: i18n("ComboBox:")
        configKey: "variableName"
        model: [
            { value: "a", text: i18n("A") },
            { value: "b", text: i18n("B") },
            { value: "c", text: i18n("C") },
        ]
    }
}

has a variety of data types:

I've listed the more common use cases. More can be found in .

Note that you can use a property to a control's property like checkBox.checked or textField.text.

A is used for boolean on/off values.

A is used for numbers.

If you want decimal places, a is a little easier to use than the QtQuick.Controls 2.0 version. QtQuickControls1 has a SpinBox.decimals to easily switch from an Integer decimals: 0 to decimals: 3 to represent a Real number (the Double data type).

If you want decimal places, a is a little easier to use than the QtQuick.Controls 2.0 version. QtControls1 has a SpinBox.decimals property to easily switch from an Integer decimals: 0 to decimals: 3 to represent a Real number (the Double config data type).

If you really want to use QtQuick.Controls 2.0, look at Zren's for an example on implementing the decimals property.

A is used for a single line of text. It can be used as a base for many other data types as well. You will also want to look at the base for more properties.

A is used for paragraphs of text. You will also want to look at the base for more properties.

KDE Frameworks has which provides a preview of the selected color and will open QtQuick's for selecting a color.

Unfortunately KDE Framework's ColorButton doesn't easily support this pattern as it stores the value in a QML color property which will read the empty string and cast it as the default color #000000 (black). I worked around this issue in the [No-Apply Control Library]({{< ref "#no-apply-control-library" >}})'s . I used a TextField to store the value as a string, and displayed the default color scheme color as placeholderText.

When we need to store a filepath in the config, we should use the Path or PathList config type. It will substitute /home/user/... with $HOME/.... To properly layout the file selector, we need a RowLayout with a TextField and Button which opens a . We can specify the default folder the dialog opens to with FileDialog's (eg: shortcuts.pictures).

makes it easy to search and preview icons.

See the [configurable icon example]({{< ref "examples.md#configurable-icon" >}}) for an example of based on the Application Launcher's (aka kickoff) .

for on/off booleans values.

for use with a String or Color config data type. If you use use a String data type, you can treat an empty string as a certain color theme color. Eg:

is useful for creating enums using the String config data type. KConfig comes with a enum datatype as well, but you have to either use hardcoded integers (with comments), or in your QML code and keep it in sync. String comparison is less efficient but is easier to program with.

inherits ComboBox.qml and is populated with all available fonts.

based on the Application Launcher icon selector.

takes a similar model as ComboBox.qml but will display the options as .

for Integer or Real numbers.

for use with an Int config data type. It has your typical 4 buttons for left/center/right/justify alignment. It serializes the Text.AlignHCenter enum.

is used to toggle bold, italic, underline, and embeds the text alignment. For use with 3 Bool config keys and 1 Int config key (used for the embedded TextAlign.qml).

for a string with multiple lines of text.

overloads TextArea.qml's valueToText(value) and textToValue(text) functions to treat a new line as the separator for the StringList type.

for a single line of text.

KConfig
KConfigXT's documentation
alias
CheckBox
SpinBox
QtQuick.Controls 1.0 SpinBox
QtQuick.Controls 1.0 SpinBox
libconfig/SpinBox.qml
TextField
TextInput
TextArea
TextEdit
ColorButton
ColorDialog
libconfig/ColorField.qml
FileDialog
shortcuts property
KQuickAddons.IconDialog
KQuickAddons.IconDialog
icon selector code
contents/config/main.xml
contents/config/config.qml
contents/ui/ConfigGeneral.qml
contents/config/main.xml
contents/config/config.qml
contents/ui/ConfigAppearance.qml
contents/ui/ConfigBehavior.qml
https://github.com/Zren/plasma-applet-lib/tree/master/package/contents/ui/libconfig
libconfig/CheckBox.qml
libconfig/ColorField.qml
libconfig/ComboBox.qml
declare the enum
FontFamily.qml
libconfig/IconField.qml
libconfig/RadioButtonGroup.qml
RadioButton
libconfig/SpinBox.qml
libconfig/TextAlign.qml
TextFormat.qml
libconfig/TextArea.qml
TextAreaStringList.qml
libconfig/TextField.qml