Pages
Developer Documentation
On this page

Adding actions

Recap

So far we built a simple application that shows cards, but the user can't add new cards yet.

This step looks at Kirigami actions, which add interactivity to the application in a consistent, fast and accessible way.

Actions

A Kirigami.Action is a user interface action. Actions give applications easy-to-reach commands for their essential functions.

If you have used Kirigami applications, you have used Kirigami actions, for example the buttons with icons to the right of a page's title. Actions can be shown in several ways and can do all kinds of things.

Adding countdowns

A countdown application isn't much use if you can't add countdowns. Let's create an action for that.

pageStack.initialPage: Kirigami.ScrollablePage {
    // Other page properties...
    actions: [
        Kirigami.Action {
            id: addAction
            icon.name: "list-add-symbolic"
            text: i18nc("@action:button", "Add kountdown")
            onTriggered: kountdownModel.append({
                name: "Kirigami Action added card!",
                description: "Congratulations, your Kirigami Action works!",
                date: 1000
            })
        }
    ]
    // ...
}

We put the Kirigami.Action in our main page from the previous steps. We could add more actions to the page if we wanted (and even nest actions in actions!).

The brackets [] work like JavaScript arrays: they hold one or more things, separated by commas:

// General JavaScript array of components:
variable: [ component1, component2 ]
// Passing an array of Kirigami actions to QML:
actions: [ Kirigami.Action {}, Kirigami.Action {} ]

id and text are familiar from the previous steps. More interesting is the icon property, inherited from Qt Quick Controls' Action (Kirigami.Action derives from it): an object with several properties for the action's icon. To use an icon from the icon theme, just set its name, icon.name.

Finding icons: SonicDE's Icon Explorer (iconexplorer, in sonic-theme-sdk) shows all the icons you can use: how they look in the installed icon themes, at different sizes, and more. Most icon names follow the freedesktop.org Icon Naming Specification, which lists the names available on every desktop. SonicDE's Silver icon theme has both icons used here.

The onTriggered signal handler is the most important part: it is what the action does when used. Here it calls kountdownModel.append() of the kountdownModel from the previous step, which adds an element to our list model. We give it an object (in curly braces {}) with the properties of a countdown (name, description and the placeholder date).

Each time you click the "Add kountdown" button at the top right, a new card is added.

Global drawer

Next, a Kirigami.GlobalDrawer. It appears as a hamburger menu. By default it opens a sidebar, which is especially useful on mobile, where the user can swipe it in from the side of the screen. Global drawers are good for navigation and actions that concern the whole application. We create a simple one with a "Quit" button:

Kirigami.ApplicationWindow {
    id: root
    // Other window properties...
    globalDrawer: Kirigami.GlobalDrawer {
        isMenu: true
        actions: [
            Kirigami.Action {
                text: i18n("Quit")
                icon.name: "application-exit-symbolic"
                shortcut: StandardKey.Quit
                onTriggered: Qt.quit()
            }
        ]
    }
    // ...
}

The global drawer goes in the application window. The main property is GlobalDrawer.actions, a list of Kirigami.Actions. This action has a fitting icon and calls Qt.quit() when triggered, which closes the application.

Since our global drawer is simple for now, we set GlobalDrawer.isMenu to true. It is then shown as a normal application menu, which takes less space than the default drawer pane.

Tip: Actions based components explains Kirigami actions and their uses in more detail.

Actions are contextual

Where you put Kirigami actions matters. Actions added to a Kirigami.Page, Kirigami.ScrollablePage or another page type appear on the right of the page header on the desktop. In mobile mode they appear in a toolbar at the bottom of the page.

Actions added to a Kirigami.GlobalDrawer appear in the drawer or menu.

Other components that show actions in their own way:

And other Kirigami components.

Our application so far

Main.qml:

import QtQuick
import QtQuick.Layouts
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami

Kirigami.ApplicationWindow {
    id: root

    width: 400
    height: 300

    title: i18nc("@title:window", "Day Kountdown")

    // Global drawer element with app-wide actions
    globalDrawer: Kirigami.GlobalDrawer {
        // Makes drawer a small menu rather than sliding pane
        isMenu: true
        actions: [
            Kirigami.Action {
                text: i18n("Quit")
                icon.name: "application-exit-symbolic"
                shortcut: StandardKey.Quit
                onTriggered: Qt.quit()
            }
        ]
    }

    ListModel {
        id: kountdownModel
        ListElement {
            name: "Dog birthday!!"
            description: "Big doggo birthday blowout."
            date: 100
        }
    }

    Component {
        id: kountdownDelegate
        Kirigami.AbstractCard {
            contentItem: Item {
                implicitWidth: delegateLayout.implicitWidth
                implicitHeight: delegateLayout.implicitHeight
                GridLayout {
                    id: delegateLayout
                    anchors {
                        left: parent.left
                        top: parent.top
                        right: parent.right
                    }
                    rowSpacing: Kirigami.Units.largeSpacing
                    columnSpacing: Kirigami.Units.largeSpacing
                    columns: root.wideScreen ? 4 : 2

                    Kirigami.Heading {
                        Layout.fillHeight: true
                        level: 1
                        text: date
                    }

                    ColumnLayout {
                        Kirigami.Heading {
                            Layout.fillWidth: true
                            level: 2
                            text: name
                        }
                        Kirigami.Separator {
                            Layout.fillWidth: true
                            visible: description.length > 0
                        }
                        Controls.Label {
                            Layout.fillWidth: true
                            wrapMode: Text.WordWrap
                            text: description
                            visible: description.length > 0
                        }
                    }
                    Controls.Button {
                        Layout.alignment: Qt.AlignRight
                        Layout.columnSpan: 2
                        text: i18n("Edit")
                    }
                }
            }
        }
    }

    pageStack.initialPage: Kirigami.ScrollablePage {
        title: i18nc("@title", "Kountdown")

        // Kirigami.Action encapsulates a UI action. Inherits from Controls.Action
        actions: [
            Kirigami.Action {
                id: addAction
                // Name of icon associated with the action
                icon.name: "list-add-symbolic"
                // Action text, i18n function returns translated string
                text: i18nc("@action:button", "Add kountdown")
                // What to do when triggering the action
                onTriggered: kountdownModel.append({
                    name: "Kirigami Action added card!",
                    description: "Congratulations, your Kirigami Action works!",
                    date: 1000
                })
            }
        ]

        Kirigami.CardsListView {
            id: cardsView
            model: kountdownModel
            delegate: kountdownDelegate
        }
    }
}

Adapted for SonicDE from develop.kde.org/docs/getting-started/kirigami/introduction-actions/ by Alessio Mattiazzi, Antti Savolainen, Carl Schwan, Claudio Cambra, Justin Kourie, Justin Zobel, Mikhail Zolotukhin, Nicolas Fella, Phu Nguyen, Swapnil Tripathi, Thiago Sueto, licensed under CC BY-SA 4.0.

Edit this page on GitHub

We use cookies to personalize content and to analyze our traffic. Please decide if you are willing to accept cookies from our website.