Aldonante dialogon
Farante nian apon utila
Ni havas fenestron, ni havas kartojn, kaj ni havas agojn. Tamen, ni ankoraŭ bezonas trovi ian manieron enigi nomon, priskribon kaj daton de nia elekto.
Unu maniero, kiel ni povus fari tion, estas kreante novan paĝon, kie ni metas la postulatajn enigelementojn. Tamen tuta paĝo dediĉita al liverado de nomo, priskribo kaj dato ŝajnas iom troa.
Anstataŭe, ni uzos dialogon.
Malfermante la dialogon
pageStack.initialPage: Kirigami.ScrollablePage {
// ...
actions: [
Kirigami.Action {
id: addAction
icon.name: "list-add"
text: i18nc("@action:button", "Add kountdown")
onTriggered: addDialog.open()
}
]
}
First we edit the action from the previous tutorial: just a Kirigami.Action that triggers the dialog's open() function.
Retronombrado-aldonado de dialogoj
The new component we add is a Kirigami.Dialog. Dialogs appear at the center of the window and can be used to provide extra information relevant to the current content. They can't be moved, but they adapt their own size to the window.
Kirigami.ApplicationWindow {
// ...
Kirigami.Dialog {
id: addDialog
title: i18nc("@title:window", "Add kountdown")
standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel
padding: Kirigami.Units.largeSpacing
preferredWidth: Kirigami.Units.gridUnit * 20
// Formaranĝoj helpas vicigi kaj strukturi aranĝon kun pluraj enigaĵoj
Kirigami.FormLayout {
// Tekstaj kampoj permesas vin enigi tekston en maldika tekstujo
Controls.TextField {
id: nameField
// Disponigas etikedon alfiksitan al la tekstokampo
Kirigami.FormData.label: i18nc("@label:textbox", "Name*:")
// Kion fari post kiam enigo estas akceptita (t.e. premita Enigu) En ĉi tiu kazo, ĝi
// movas la fokuson al la sekva kampo
onAccepted: descriptionField.forceActiveFocus()
}
Controls.TextField {
id: descriptionField
Kirigami.FormData.label: i18nc("@label:textbox", "Description:")
placeholderText: i18n("Optional")
// Denove, ĝi movas la fokuson al la sekva kampo
onAccepted: dateField.forceActiveFocus()
}
Controls.TextField {
id: dateField
Kirigami.FormData.label: i18nc("@label:textbox", "ISO Date*:")
// D signifas postulatan nombron inter 1-9, 9 signifas postulatan nombron inter 0-9
inputMask: "D999-99-99"
// Ĉi tie ni konfirmas la operacion same kiel klaki la OK butonon
onAccepted: addDialog.onAccepted()
}
Controls.Label {
text: "* = required fields"
}
}
// La dialoglogiko iras ĉi tie
}
// ...
}
Dialogoj defaŭlte havas header kaj [footer](https://doc.qt .io/qt-6/qml-qtquick-controls-dialog.html#footer-prop), ambaŭ hereditaj de Controls.Dialog.
The header by default includes a title and a close button that can be disabled with showCloseButton. The footer by default includes a close button, and it can be overridden with standardButtons.
We first set it to show an "Ok" button and a "Cancel" button, add some padding, and add a reasonable preferredWidth. The preferred width is the default expected size of the dialog, which can increase if needed. We can use standard Kirigami.Units that we will revisit later on.
Then we come to a Kirigami.FormLayout. Unlike a ColumnLayout, the layout of its child components is automatic and centered, with optional labels. As the name implies, it is used to create input forms.
Ĉi tiuj formularaj aranĝoj estas dezajnitaj por funkcii kun diversaj malsamaj enigspecoj, kvankam ni restas al simplaj Controls.Textfield enigaĵoj, kiuj donas al ni simplajn tekstskatolojn por skribi aferojn.
Ni kreis Textfield-elementojn kiuj funkcias kiel:
- Enigo por la nomo de nia retronombrado
- Enigo por la priskribo de nia retronombrado
- Enigo por la dato al kiu ni kalkulas malsupren, kiu devas esti provizita en formato
YYYY-MM-DD
Within each of these Controls.Textfield elements, we are setting a Kirigami.FormData.label property that lets us define labels for them. The form will present the correct labels to the left of each of these text input fields.
Fine, ni ankaŭ fiksas la onAccepted proprecon por ekigi la [forceActiveFocus()](https:/ /doc.qt.io/qt-6/qml-qtquick-item.html#forceActiveFocus-method) metodo de la sekva kampo; ĉi tio ŝanĝos la aktivan kampon post kiam la uzanto trafos la ENTER-klavon, plibonigante la uzeblecon de la formo.
Ni ankaŭ starigis proprecon nomitan inputMask sur la teksta kampo por nia dato. Agordi ĉi tion al D999-99-99
malhelpas uzantojn enigi ion, kio povus rompi la funkciecon de la aplikaĵo (kiel teksto), limigante ilin nur enigi ciferojn, kiujn ni tiam povas provi analizi en datan objekton.
Post kiam la uzantinterfaco por la dialogo estas farita, ni devas ŝanĝi kiel ĝi kondutas. Por tio ni bezonas tri aferojn:
- Montri la Ok-butonon nur kiam la postulataj kampoj estas plenigitaj
- Aldoni la enigajn informojn al la modelo
- Forigi la enigformularon
Kirigami.Dialog {
// ... Post kiam la Kirigami.Dialogo estas pravalorizita, ni volas krei propran ligadon por nur
// videbligi la Ok-butonon se la bezonataj tekstkampoj estas plenigitaj. Por tio ni uzas
// Kirigami.Dialog.standardButton(butono):
Component.onCompleted: {
const button = standardButton(Kirigami.Dialog.Ok);
// () => estas JavaScript-sago-funkcio
button.enabled = Qt.binding( () => requiredFieldsFilled() );
}
onAccepted: {
// La ligado estas kreita, sed ni ankoraŭ devas igi ĝin neklakebla krom se la kampoj estas
// plenigitaj
if (!addDialog.requiredFieldsFilled()) return;
appendDataToModel();
clearFieldsAndClose();
}
}
La unua afero, kiu devas esti farita, estas krei ligon inter la [enabled] de la OK butono (https://doc.qt.io/qt-6/qml-qtquick-controls-popup.html#enabled-prop) propreco kaj kontrolo ĉu la kampoj estas plenigitaj, kio ĉi-kaze devas esti farita per [Qt.binding()](https://doc.qt.io/qt-6/qtqml-syntax-propertybinding.html#creating- property-bindings-from-javascript) en JavaScript. Efektive, la linio:
button.enabled = Qt.binding( () => requiredFieldsFilled() );
estas simila al la QML-ligoj, kiujn ni vidis ĝis nun, kiel en la sekva pseŭdokodo:
enabled: requiredFieldsFilled()
La signala prizorganto, kiu ekigas la Ok-butonon, estas onAccepted. Ĝi restas malplena kaj sen fari ion se la postulataj kampoj estas plenigitaj; alie, ĝi aldonos la enigon al la modelo kaj malplenigos la dialogon por la venonta fojo, kiam ĝi estos malfermita.
Kirigami.Dialog {
// ... Ni kontrolas, ke la nomKampo ne estas malplena kaj ke la datKampo (kiu havas enigMaskon)
// estas tute plenigita
function requiredFieldsFilled() {
return (nameField.text !== "" && dateField.acceptableInput);
}
function appendDataToModel() {
kountdownModel.append({
name: nameField.text,
description: descriptionField.text,
date: new Date(dateField.text)
});
}
function clearFieldsAndClose() {
nameField.text = ""
descriptionField.text = ""
dateField.text = ""
addDialog.close();
}
}
Por nia postulata nomkampo, ĉio, kion ni devas fari, estas kontroli ĉu la kampoteksto estas malplena ĉeno. Por la data kampo, ĉar ĝi havas enigmaskon, ni devas uzi acceptableInput anstataŭe, kiu nur fariĝas vera post kiam la tuta kampo estas plenigita kaj enhavas nur akcepteblajn signojn.
Tiam, la append() metodo de nia lista modelo kountdownModel
aldonas JavaScript-objekton inkluzive de la proprecoj, kiujn ni disponigis.
Finfine, ni certigas forigi la tekstajn kampojn agordante iliajn text ecojn al malplena ĉeno, tiam close() ĝi.
Post kiam ni konservos niajn dosierojn kaj konstruos nian programon, ni povos aldoni niajn proprajn proprajn retronombradojn! Ni povas fari la lastan tuŝon por plibonigi la interfacon, nome forigi la falsan retronombradon, kiun ni havis en la antaŭaj lecionoj:
|
|
Secondly now that we have an actual date to play around with, we can calculate the time until said date:
|
|
And thirdly increase the window size so that we have more room for our new cards:
|
|
Multe pli bela.
Nia aplikaĵo ĝis nun
|
|