Skapa överlagringsblad

Att begripa överlagringsblad.

Göra vårt program användbart

Vi har ett fönster, vi har kort, och vi har åtgärder. Vi behöver ändå komma på något sätt att mata in ett namn, en beskrivning och ett datum vi väljer.

Ett sätt vi skulle kunna göra det är genom att skapa en nya sida där vi placerar inmatningselement. Dock verkar en hel sida tillägnad för att tillhandahålla namn, beskrivning och datum lite överdrivet.

Istället använder vi ett överlagringsblad.

Överlagringsblad som visas mitt i programmet som ett dialogfönster

Nedräkning: lägga till blad

Den nya komponenten vi lägger till är Kirigami.OverlaySheet . Överlagringsblad svävar över fönstrets innehåll och kan användas för en mängd olika syften, såsom att tillhandahålla extra information relevant för det aktuella innehållet. De liknar snygga meddelandefönster, utom att de inte kan flyttas.

Kirigami.OverlaySheet {
    id: addSheet
    header: Kirigami.Heading {
        text: i18nc("@title:window", "Add kountdown")
    }
    Kirigami.FormLayout {
        Controls.TextField {
            id: nameField
            Kirigami.FormData.label: i18nc("@label:textbox", "Name:")
            placeholderText: i18n("Event name (required)")
            onAccepted: descriptionField.forceActiveFocus()
        }
        Controls.TextField {
            id: descriptionField
            Kirigami.FormData.label: i18nc("@label:textbox", "Description:")
            placeholderText: i18n("Optional")
            onAccepted: dateField.forceActiveFocus()
        }
        Controls.TextField {
            id: dateField
            Kirigami.FormData.label: i18nc("@label:textbox", "Date:")
            placeholderText: i18n("YYYY-MM-DD")
            inputMask: "0000-00-00"
        }
        Controls.Button {
            id: doneButton
            Layout.fillWidth: true
            text: i18nc("@action:button", "Done")
            enabled: nameField.text.length > 0
            onClicked: {
                kountdownModel.append({
                    name: nameField.text,
                    description: descriptionField.text,
                    // Metoden parse() tolkar en sträng och returnerar antal millisekunder sedan 1:a
                    // januari, 1970, 00:00:00 UTC.
                    date: Date.parse(dateField.text)
                });
                nameField.text = ""
                descriptionField.text = ""
                dateField.text = ""
                addSheet.close();
            }
        }
    }
}

Vi kan ge överlagringsblad ett sidhuvud. De tilldelas med egenskapen header . Vi har gett vår en Kirigami.Heading som innehåller en relevant titel: 'Add Kountdown'.

Sedan kommer vi till en Kirigami.FormLayout . Den låter oss enkelt skapa mottagliga inmatningsformulär, som snyggt visar beteckningar för inmatning och själva inmatningen både på breda skärmar och smalare mobila enheter. Formulärlayouter är konstruerade för att arbeta med ett stort antal typer av inmatning, även om vi håller oss till enkla Controls.Textfield , som ger oss enkla textrutor att skriva in saker i.

Vi har skapat elementet Textfield som fungerar som:

  1. Indata för namnet på vår nedräkning
  2. Indata för beskrivningen av vår nedräkning
  3. Indata för datumet vi räknar ner till, som måste anges på formatet ÅÅÅÅ-MM-DD.

Inom vart och ett av de här Controls.Textfield elementen, använder vi egenskapen Kirigami.FormData.label som låter oss definiera beteckningar för dem. Formuläret visar rätt beteckning för vart och ett av textinmatningsfälten. Vi anger också platsmarkörer med egenskapen TextField.placeholderText, som försvinner så snart användaren börjar skriva i fältet. Slutligen tilldelar vi också egenskapen onAccepted för att utlösa metoden forceActiveFocus() för följande fält. Det byter aktivt fält när användaren väl trycker på returtangenten, vilket förbättrar vårt formulärs användbarhet.

Vi har också ställt in en egenskap som kallas inputMask i textfältet för vårt datum. Att ställa in den till `"0000-00-00" förhindrar oss från att mata in någonting som kan förstöra programmets funktion (såsom text), och begränsar dem att bara mata in siffror som vi sedan kan försöka tolka som ett datumobjekt.

I slutet på vårt formulär inkluderar vi en [Button](docs:qtquickcontrols;QtQuick.Controls.Button som lägger till vår nya nedräknare i listmodellen. Vi har ställt in egenskapen enabled till en villkorssats som kontrollerar om namnfältet är tomt eller inte: om det är det, är knappen inaktiverad, och vice versa. När knappen utlöses, utlöser den metoden append i vår kountdownModel listmodell, vilket lägger till ett Javascript-objekt som inkluderar egenskaperna vi har tillhandahållit. Vi säkerställer också att textfälten rensas genom att ställa in deras text egenskaper till en tom sträng. Slutligen anropar vi en metod i vårt överlagringsblad, close() , som stänger det.

Använda vårt blad

actions.main: Kirigami.Action {
    id: addAction
    icon.name: "list-add"
    text: i18nc("@action:button", "Add kountdown")
    onTriggered: addSheet.open()
}

Överlagringsblad har två metoder, open() och close() , som styr öppning och stängning av komponenten. I detta fall har vi ställt in bladet att öppnas när vi utlöser vår åtgärd. När vi väl har sparat våra filer och byggt programmet, kommer vi att kunna lägga till våra egna anpassade nedräknare.

Vårt program så långt

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import QtQuick 2.15
import QtQuick.Controls 2.15 as Controls
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami

Kirigami.ApplicationWindow {
    id: root

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

    globalDrawer: Kirigami.GlobalDrawer {
        isMenu: true
        actions: [
            Kirigami.Action {
                text: i18n("Quit")
                icon.name: "gtk-quit"
                shortcut: StandardKey.Quit
                onTriggered: Qt.quit()
            }
        ]
    }

    ListModel {
        id: kountdownModel
    }

    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: i18n("%1 days", Math.round((date-Date.now())/86400000))
                    }

                    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")
                    }
                }
            }
        }
    }

    // Overlay sheets appear over a part of the window
    Kirigami.OverlaySheet {
        id: addSheet
        header: Kirigami.Heading {
            text: i18nc("@title:window", "Add kountdown")
        }
        // Form layouts help align and structure a layout with several inputs
        Kirigami.FormLayout {
            // Textfields let you input text in a thin textbox
            Controls.TextField {
                id: nameField
                // Provides label attached to the textfield
                Kirigami.FormData.label: i18nc("@label:textbox", "Name:")
                // Placeholder text is visible before you enter anything
                placeholderText: i18n("Event name (required)")
                // What to do after input is accepted (i.e. pressed enter)
                // In this case, it moves the focus to the next field
                onAccepted: descriptionField.forceActiveFocus()
            }
            Controls.TextField {
                id: descriptionField
                Kirigami.FormData.label: i18nc("@label:textbox", "Description:")
                placeholderText: i18n("Optional")
                onAccepted: dateField.forceActiveFocus()
            }
            Controls.TextField {
                id: dateField
                Kirigami.FormData.label: i18nc("@label:textbox", "Date:")
                placeholderText: i18n("YYYY-MM-DD")
                inputMask: "0000-00-00"
            }
            Controls.Button {
                id: doneButton
                Layout.fillWidth: true
                text: i18nc("@action:button", "Done")
                // Button is only enabled if the user has entered something into the nameField
                enabled: nameField.text.length > 0
                onClicked: {
                    // Add a listelement to the kountdownModel ListModel
                    kountdownModel.append({
                        name: nameField.text,
                        description: descriptionField.text,
                        date: Date.parse(dateField.text)
                    });
                    nameField.text = ""
                    descriptionField.text = ""
                    dateField.text = ""
                    addSheet.close();
                }
            }
        }
    }

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

        // Kirigami.Action encapsulates a UI action. Inherits from Controls.Action
        actions.main: Kirigami.Action {
            id: addAction
            // Name of icon associated with the action
            icon.name: "list-add"
            // Action text, i18n function returns translated string
            text: i18nc("@action:button", "Add kountdown")
            // What to do when triggering the action
            onTriggered: addSheet.open()
        }

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

Skärmbild av programmet med fyra exempelkort