Crear fulls superposats

Familiaritzeu-vos amb els fulls superposats.

Fer que la nostra aplicació sigui útil

Tenim una finestra, tenim targetes i tenim accions. No obstant això, encara necessitem trobar alguna forma d'introduir un nom, una descripció i una data de la nostra elecció.

Una manera en què podríem fer això és creant una pàgina nova on col·loquem els elements d'introducció requerits. No obstant això, una pàgina sencera dedicada a proporcionar un nom, una descripció i una data sembla una mica excessiu.

En el seu lloc, utilitzarem un full superposat.

Full superposat que apareix al mig de l'aplicació com una finestra de diàleg

Full que afegeix un compte enrere

El component nou que afegim és un Kirigami.OverlaySheet . Els fulls superposats se situen sobre el contingut de la finestra i es poden utilitzar per a diversos propòsits, com proporcionar informació addicional rellevant per al contingut actual. Són una espècie de finestres emergents elegants, excepte que no es poden moure.

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,
                    // El mètode parse() analitza una cadena i retorna el nombre de mil·lisegons des
                    // de l'1 de gener de 1970, 00:00:00 UTC.
                    date: Date.parse(dateField.text)
                });
                nameField.text = ""
                descriptionField.text = ""
                dateField.text = ""
                addSheet.close();
            }
        }
    }
}

Podem donar-los una capçalera. Aquesta s'estableix amb la propietat header . N'hem proporcionat una amb la Kirigami.Heading contenint un títol rellevant: «Add Kountdown».

Després arribem a una Kirigami.FormLayout . Ens permet crear formularis d'entrada receptius amb facilitat, els quals mostren amb claredat les etiquetes de les entrades i les entrades en si mateixes tant en pantalles apaïsades com en dispositius mòbils més estrets. Aquestes disposicions de formulari estan dissenyades per a treballar amb una varietat de diferents tipus d'entrada, encara que ens cenyim a entrades senzilles Controls.Textfield que ens brinden quadres de text senzills per a escriure-hi.

Hem creat elements Textfield que actuen com:

  1. Entrada per al nom del nostre compte enrere
  2. Entrada per a la descripció del nostre compte enrere
  3. Entrada per a la data cap a la qual estem comptant cap enrere, la qual s'ha de proporcionar en el format YYYY-MM-DD.

Dins de cadascun d'aquests elements Controls.Textfield , hem configurat una propietat Kirigami.FormData.label que ens permet definir-los etiquetes. El formulari presentarà les etiquetes correctes per a cadascuna d'aquestes entrades de text. També hem establert el text del marcador de posició dins dels camps amb la propietat TextField.placeholderText, que desapareixerà tan aviat com l'usuari comenci a escriure en el camp. Finalment, també hem establert la propietat onAccepted per a activar el mètode forceActiveFocus() del camp següent. Això commutarà el camp actiu una vegada l'usuari premi la tecla Retorn, millorant la usabilitat del nostre formulari.

També hem establert una propietat anomenada inputMask en el camp de text per a la nostra data. Establint això a "0000-00-00" evitarà que els usuaris introdueixin alguna cosa que pugui trencar la funcionalitat de l'aplicació (com ara text), restringint-lo a només la introducció de dígits, després podrem intentar analitzar-ho en un objecte de data.

Al final del nostre formulari, incloem un botó que afegeix el nostre compte enrere nou al model de llista. Hem establert la propietat enabled en una declaració condicional que comprova si el camp de nom està buit o no: si ho està, el botó estarà inhabilitat i viceversa. Quan s'activi el botó, s'activarà el mètode append del nostre model de llista kountdownModel, afegint un objecte de JavaScript que inclogui les propietats que hem proporcionat. També ens assegurarem d'esborrar els camps de text establint les seves propietats text a una cadena buida. Finalment cridarem a un mètode en el nostre full superposat, close() , que el tancarà.

Usar el nostre full

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

Els fulls superposats tenen dos mètodes, open() i close() , els quals controlen l'obertura i el tancament d'aquest component. En aquest cas, hem establert el full perquè s'obri quan activem la nostra acció. Una vegada que desem els nostres fitxers i creem el nostre programa, podrem afegir els nostres propis comptes enrere personalitzats!

La nostra aplicació fins ara

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

Captura de pantalla de l'aplicació amb quatre targetes d'exemple