KDE Frameworks provides a cross-platform notification API, and with a proposed change still in review this would also become directly usable from QML.

Basic Notifications

Getting started with notifications in QML would then be quite similar to how this also works in C++:

  • Create a KNotificiation instance.
  • Customize it to your needs via its properties (labels, icons, actions, priorities, etc).
  • Connect to its signals to react to the user interacting with the notification, by triggering its inline actions or by closing it.
  • Eventually call its sendEvent() method to show or re-show the notification.
import QtQuick 2.15
import org.kde.notification 1.0

... {
    Notification {
        id: myNotification
        componentName: "plasma_workspace"
        eventId: "notification"
        title: "Attention!"
        text: "Something important happened."
        iconName: "kde"
        actions: [ "Action 1", "Action 2" ]
        flags: Notification.Persistent
        urgency: Notification.HighUrgency
        onClosed: console.log("Notification closed.")
        onDefaultActivated: console.log("Default action activated.")
        onAction1Activated: console.log("Action 1 activated.")
        onAction2Activated: console.log("Action 2 activated.")
    }

    Button {
        onClicked: myNotification.sendEvent()
    }
}

Inline Reply Notifications

Inline reply notifications are also available. There’s a small difference to C++ in that the reply action doesn’t need to be explicitly managed but is created on demand behind the scenes.

import QtQuick 2.15
import org.kde.notification 1.0

... {
    Notification {
        id: myReplyNotification
        componentName: "plasma_workspace"
        eventId: "notification"
        title: "Chat message from Dr Konqui"
        text: "How are you?"
        replyAction {
            label: "Reply"
            placeholderText: "Reply to Dr Konqui..."
            submitButtonText: "Send Reply"
            submitButtonIconName: "mail-reply-all"
            onReplied: console.log(text)
        }
    }
}

Memory Management

If you are already familiar with KNotification’s C++ API you might notice that the use shown above shouldn’t actually be possible due to KNotification objects being auto-deleted after being closed.

Or you might have a use-case that requires an arbitrary amount of dynamically created notifications rather than a fixed set of reusable instances. In that case the above examples might seem too restrictive.

The answer to both is the new configurable auto-delete behavior of KNotification. When used from C++ it’s on by default for compatibility (but can also be switched off now), in QML it’s off by default and can be switched on when needed as shown in the following example.

import QtQuick 2.15
import org.kde.notification 1.0

... {
    Component {
        id: notificationComponent
        Notification {
            componentName: "plasma_workspace"
            eventId: "notification"
            text: "Temporary notification we can create new instances of."
            autoDelete: true
        }
    }

    Button {
        property int count: 0
        onClicked: {
            var notification = notificationComponent.createObject(parent);
            notification.title = "New Notification " + count;
            n.sendEvent();
            ++count;
        }
    }
}

There’s a more complete and actually runnable pure-QML example here.

KDE Frameworks 6

One of the goals for KDE Frameworks 6 is to have QML bindings directly integrated with the corresponding frameworks themselves. Doing this during the lifetime of 5 allows us to identify issues in the C++ API that we can then adjust in 6 to minimize the need for wrapper or glue code. This reduces maintenance cost and improves usability by making both APIs more similar.

Help with this is very welcome, check the KF6 workboard and consider joining the #kde-devel channel on Matrix, the weekly KF6 meeting (Monday 15:00 UTC) and the kde-frameworks-devel mailing list to discuss the details!