Dodajanje pogovornega okna
Izdelava naše aplikacije uporabne
Imamo okno, kartice in akcije. Vendar moramo še vedno najti način vnosa imena, opisa in datuma po naši izbiri.
To lahko storimo tako, da ustvarimo novo stran, kjer postavimo zahtevane vhodne elemente. Vendar pa se zdi cela stran, namenjena zagotavljanju imena, opisa in datuma, nekoliko pretirana.
Namesto tega bomo uporabili pogovorno okno.
Odpiranje pogovornega okna
pageStack.initialPage: Kirigami.ScrollablePage {
// ...
actions: [
Kirigami.Action {
id: addAction
icon.name: "list-add"
text: i18nc("@action:button", "Add kountdown")
onTriggered: addDialog.open()
}
]
}
Najprej uredimo dejanje iz prejšnje vadnice: samo Kirigami.Action, ki sproži funkcijo pogovornega okna open().
Pogovorna okna za dodajanje odštevanja
Nova komponenta, ki jo dodamo, je Kirigami.Dialog. Pogovorna okna se prikažejo na sredini okna in jih je mogoče uporabiti za zagotavljanje dodatnih informacij, ki so pomembne za trenutno vsebino. Ni jih mogoče premikati, ampak se po svoji velikosti prilagajajo oknu.
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
// Postavitve obrazcev pomagajo uskladiti in strukturirati postavitev z več vnosi
Kirigami.FormLayout {
// Textfields vam omogočajo vnos besedila v tanko besedilno polje
Controls.TextField {
id: nameField
// Zagotavlja oznako, pripeto besedilnemu polju
Kirigami.FormData.label: i18nc("@label:textbox", "Name*:")
// Kaj storiti, ko je vnos sprejet (tj. pritisnjen Enter) V tem primeru premakne
// fokus na naslednje polje
onAccepted: descriptionField.forceActiveFocus()
}
Controls.TextField {
id: descriptionField
Kirigami.FormData.label: i18nc("@label:textbox", "Description:")
placeholderText: i18n("Optional")
// Spet premakne fokus na naslednje polje
onAccepted: dateField.forceActiveFocus()
}
Controls.TextField {
id: dateField
Kirigami.FormData.label: i18nc("@label:textbox", "ISO Date*:")
// D pomeni zahtevano število med 1-9, 9 pomeni zahtevano število med 0-9
inputMask: "D999-99-99"
// Tukaj potrdimo operacijo tako kot s klikom na gumb V redu
onAccepted: addDialog.onAccepted()
}
Controls.Label {
text: "* = required fields"
}
}
// Logika dialoga gre sem
}
// ...
}
Pogovorna okna imajo privzeto glavo header in nogo [footer](https://doc.qt .io/qt-6/qml-qtquick-controls-dialog.html#footer-prop), oba podedovana iz Controls.Dialog.
Glava privzeto vključuje naslov title in gumb za zapiranje, ki ga je mogoče onemogočiti s [showCloseButton] (docs:kirigami2;Dialog::showCloseButton). Noga privzeto vključuje gumb za zapiranje in ga je mogoče preglasiti s standardButtons.
Najprej smo ga nastavili tako, da prikaže gumb »V redu« in gumb »Prekliči«, dodali nekaj oblazinjenja in dodali razumno širino preferredWidth. Želena širina je privzeta pričakovana velikost pogovornega okna, ki se lahko po potrebi poveča. Uporabimo lahko standardne Kirigami.Units, ki jih bomo ponovno pregledali pozneje.
Nato pridemo do Kirigami.FormLayout. Za razliko od ColumnLayout je postavitev njegovih podrejenih komponent samodejna in na sredini, z neobveznimi oznakami. Kot že ime pove, se uporablja za ustvarjanje vnosnih obrazcev.
Te postavitve obrazcev so zasnovane tako, da delujejo z različnimi vrstami vnosa, čeprav se držimo preprostih vnosov Controls.Textfield, ki nam dajejo preprosta besedilna polja, v katera lahko pišemo stvari.
Ustvarili smo elemente Textfield, ki delujejo kot:
- Vnos za ime našega odštevanja
- Vnos za opis našega odštevanja
- Vnos za datum, ki ga odštevamo proti vrednosti, ki jo je treba navesti v formatu 'YYYY-MM-DD'
Znotraj vsakega od teh elementov Controls.Textfield nastavimo lastnost Kirigami.FormData.label, ki nam omogoča definiranje oznak zanj. Obrazec bo prikazal pravilne oznake na levi strani vsakega od teh polj za vnos besedila.
Nazadnje nastavimo tudi lastnost onAccepted, da sproži [forceActiveFocus()](https:/ /doc.qt.io/qt-6/qml-qtquick-item.html#forceActiveFocus-method) metodo naslednjega polja; to bo preklopilo aktivno polje, ko uporabnik pritisne tipko ENTER, kar izboljša uporabnost obrazca.
Prav tako smo nastavili lastnost z imenom inputMask v besedilnem polju za naš datum. Če to nastavite na D999-99-99
, preprečite uporabnikom, da bi vnesli nekaj, kar bi lahko pokvarilo funkcionalnost aplikacije (kot je besedilo), in jih omejite na vnos samo številk, ki jih lahko nato poskusimo razčleniti v objekt datuma.
Ko je uporabniški vmesnik za pogovorno okno končan, moramo spremeniti njegovo obnašanje. Za to potrebujemo tri stvari:
- Pokaži gumb V redu samo, ko so izpolnjena zahtevana polja
- Dodajte vhodne informacije v model
- Počistite obrazec za vnos
Kirigami.Dialog {
// ... Ko je Kirigami.Dialog inicializiran, želimo ustvariti vezavo po meri, da bo gumb V redu
// viden le, če so izpolnjena zahtevana besedilna polja. Za to uporabljamo
// Kirigami.Dialog.standardButton(button):
Component.onCompleted: {
const button = standardButton(Kirigami.Dialog.Ok);
// () => je funkcija JavaScript puščice
button.enabled = Qt.binding( () => requiredFieldsFilled() );
}
onAccepted: {
// Vezava je ustvarjena, vendar moramo še vedno onemogočiti klikanje, razen če so polja
// izpolnjena
if (!addDialog.requiredFieldsFilled()) return;
appendDataToModel();
clearFieldsAndClose();
}
}
Prva stvar, ki jo je treba narediti, je ustvariti povezavo med lastnostjo enabled gumba OK in preverjanje, ali so polja izpolnjena, kar je v tem primeru treba narediti s [Qt.binding()]Qt.binding() v JavaScript. Dejansko je vrstica:
button.enabled = Qt.binding( () => requiredFieldsFilled() );
podobna vezavam QML, ki smo jih videli do sedaj, kot v naslednji psevdo kodi:
enabled: requiredFieldsFilled()
Upravljalnik signalov, ki sproži gumb V redu, je onAccepted. Če so zahtevana polja izpolnjena, ostane prazen in ne naredi ničesar; v nasprotnem primeru bo dodal vnos v model in počistil pogovorno okno za naslednje odprtje.
Kirigami.Dialog {
// ... Preverimo, da nameField ni prazno in da je dateField (ki ima inputMask) v celoti
// izpolnjeno
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();
}
}
Za naše zahtevano polje z imenom moramo le preveriti, ali je besedilo polja prazen niz. Ker ima polje z datumom vnosno masko, moramo namesto tega uporabiti acceptableInput, kar samo postane true, ko je celotno polje izpolnjeno in vsebuje samo sprejemljive znake.
Nato metoda append() našega modela seznama kountdownModel
doda objekt JavaScript, ki vključuje lastnosti, ki smo jih zagotovili.
Na koncu poskrbimo, da počistimo besedilna polja tako, da nastavimo njihove lastnosti text na prazen niz, nato ga zapremo s close().
Ko shranimo svoje datoteke in zgradimo svoj program, bomo lahko dodali lastna odštevanja po meri! Za izboljšanje vmesnika lahko naredimo še zadnji dotik, in sicer odstranimo navidezno odštevanje, ki smo ga imeli v prejšnjih lekcijah:
|
|
Drugič, zdaj, ko imamo dejanski datum, s katerim se lahko igramo, lahko izračunamo čas do omenjenega datuma:
|
|
In tretjič, povečamo velikost okna, da bomo imeli več prostora za naše nove kartice:
|
|
Veliko lepše.
Naša aplikacija do sedaj
Main.qml:
|
|