Delegats de formularis a les pàgines de configuració
Els complements del Kirigami són un conjunt addicional de components visuals que funcionen bé en el mòbil i l'escriptori i es garanteix que són multiplataforma. Utilitzen el Kirigami per sota per a crear els seus components.
Heu après a afegir pàgines «Quant al» i «Quant al KDE» a l'aplicació. Ara podreu utilitzar els seus mateixos components interns per a crear les pàgines de configuració.
L'estructura del projecte s'hauria de veure així:
addonsexample
├── CMakeLists.txt
├── main.cpp
├── Main.qml
├── MyAboutPage.qml
└── SettingsPage.qml
Canvis necessaris
Canvieu el Main.qml
per a incloure la pàgina nova Settings:
import QtQuick
import QtQuick.Layouts
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
import org.kde.about 1.0
Kirigami.ApplicationWindow {
id: root
width: 600
height: 700
Component {
id: aboutkde
FormCard.AboutKDE {}
}
Component {
id: aboutpage
MyAboutPage {}
}
Component {
id: settingspage
SettingsPage {}
}
pageStack.initialPage: Kirigami.ScrollablePage {
ColumnLayout {
FormCard.FormCard {
FormCard.FormButtonDelegate {
id: aboutKDEButton
icon.name: "kde"
text: i18n("About KDE Page")
onClicked: root.pageStack.layers.push(aboutkde)
}
FormCard.FormButtonDelegate {
id: aboutPageButton
icon.name: "applications-utilities"
text: i18n("About Addons Example")
onClicked: root.pageStack.layers.push(aboutpage)
}
FormCard.FormButtonDelegate {
id: settingsButton
icon.name: "settings-configure"
text: i18n("Single Settings Page")
onClicked: root.pageStack.layers.push(settingspage)
}
}
}
}
}
Ara podem començar a consultar els components que s'utilitzen per a crear la pàgina de Configuració: la Targeta de Formulari i els seus Delegats.
Delegats de Formularis
FormCard i FormCardPage
FormCard.FormCard és el component principal que utilitzarem per a agrupar tots els seus components fills, els Delegats.
Hem utilitzat una targeta de formulari en la introducció dels complements del Kirigami abans. El seu propòsit principal és servir com a contenidor per a altres components alhora que segueix un color diferent del fons, de manera similar a un Kirigami.Card.
Crea un fitxer SettingsPage.qml
nou:
import QtQuick
import org.kde.kirigamiaddons.formcard as FormCard
FormCard.FormCardPage {
FormCard.FormCard {
// Aquí és on van tots els nostres delegats!
}
FormCard.FormCard {
// Aquí és on van tots els nostres delegats!
}
}
Com que estem creant un fitxer QML separat per a la nostra pàgina de Configuració, i com que necessitem preparar el desplaçament potencial a la nostra pàgina, utilitzem un FormCard.FormCardPage
, que hereta Kirigami.ScrollablePage.
El més agradable de la pàgina de la targeta de formulari és que ve amb una disposició interna, de manera que no es necessita cap ColumnLayout addicional i els nostres delegats poden afegir-se directament a ella.
Note
És possible utilitzar delegats de FormCard directament amb un Kirigami.ScrollablePage, però en aquest cas haureu d'afegir les vostres pròpies disposicions.FormHeader
Per a cada FormCard que vulgueu crear, podeu crear un FormHeader just abans. La capçalera utilitza text en negreta i es mostra just a sobre de la targeta de formulari.
import org.kde.kirigamiaddons.formcard as FormCard
FormCard.FormCardPage {
FormCard.FormHeader {
title: i18n("General")
}
FormCard.FormCard {
// Els nostres delegats van aquí...
}
FormCard.FormHeader {
title: i18n("Accounts")
}
FormCard.FormCard {
// Els nostres delegats van aquí...
}
}
FormTextDelegate i FormSectionText
Comencem de manera senzilla, amb text net.
FormSectionText
simplement afegeix un delegat prim que conté una etiqueta.FormTextDelegate
té text i una descripció en gris.
import QtQuick
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
FormCard.FormCardPage {
FormCard.FormHeader {
title: i18n("General")
}
FormCard.FormCard {
FormCard.FormTextDelegate {
text: i18n("Current Color Scheme")
description: "Breeze"
}
}
FormCard.FormHeader {
title: i18n("Accounts")
}
FormCard.FormCard {
FormCard.FormSectionText {
text: i18n("Online Account Settings")
}
FormCard.FormTextDelegate {
leading: Kirigami.Icon {source: "user"}
text: "John Doe"
description: i18n("The Maintainer ™️")
}
}
}
Afegim algun text fictici per a la hipotètica detecció del tema. Si volíem tenir una detecció real de l'esquema de color, en el futur es podria fer de manera similar al Neochat (codi aquí), fent ús d'un model de C++ amb el KColorSchemeManager.
A l'apartat Comptes Online, veiem un immoble addicional, leading
. Es pot afegir un element perquè aparegui abans del text. La seva propietat oposada, trailing
, podria mostrar un element després del text, però no l'utilitzarem en el programa.
Fem servir un Kirigami.Icon aquí per a la simplicitat, però això també es podria implementar utilitzant un Kirigami.Avatar que captura la informació d'un model, com es fa a Neochat aquí.
Hauria d'acabar veient-se així:
FormButtonDelegate
El FormButtonDelegate és visualment similar a un FormTextDelegate, però s'hi pot fer clic i mostra una fletxa que apunta cap a la dreta. L'hem utilitzat abans a la introducció dels complements del Kirigami.
Mentre que el FormTextDelegate tenia les propietats leading
i trailing
per a mostrar un element abans i després del contingut principal, el FormButtonDelegate només té la propietat leading
, perquè el costat dret està ocupat per la fletxa.
import QtQuick
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
FormCard.FormCardPage {
FormCard.FormHeader {
title: i18n("General")
}
FormCard.FormCard {
FormCard.FormTextDelegate {
text: i18n("Current Color Scheme")
description: "Breeze"
}
}
FormCard.FormHeader {
title: i18n("Accounts")
}
FormCard.FormCard {
FormCard.FormSectionText {
text: i18n("Online Account Settings")
}
FormCard.FormTextDelegate {
leading: Kirigami.Icon {source: "user"}
text: "John Doe"
description: i18n("The Maintainer ™️")
}
FormCard.FormButtonDelegate {
icon.name: "list-add"
text: i18n("Add a new account")
onClicked: console.info("Clicked!")
}
}
}
Utilitzem la seva propietat icon.name
per a establir una icona de més (+) que apareixerà després de l'espai on apareixerà el leading
, i abans del contingut principal. Aquest és un patró comú per a indicar que el botó afegirà alguna cosa a una llista.
Com que aquest exemple és per a propòsits il·lustratius senzills, no aprofundim en el que es faria una vegada que es clica el botó: només imprimeix «Clicked!» al terminal. Podríem crear una pàgina nova per a la creació de comptes que afegeixi un altre usuari a un model i després empenyi la pàgina a la vista, de manera similar al que vam fer a Main.qml
.
FormRadioDelegate, FormCheckDelegate i FormSwitchDelegate
El RadioButton, el CheckBox i el Switch són components molt utilitzats en qualsevol interfície d'usuari. Els complements del Kirigami els proporcionen com a FormRadioDelegate, FormCheckDelegate i FormSwitchDelegate.
Les seves úniques propietats principals són text
i description
. Són diferents en ús perquè tots hereten AbstractButton, i per tant s'espera que utilitzin els seus senyals i controladors: «checked» i «onChecked», «toggled» i «onToggled», «clicked» i «onClicked».
Volem crear alguna funcionalitat de desament automàtic a la nostra aplicació, i només volem mostrar la seva configuració si l'usuari ha habilitat aquesta funcionalitat. Creeu una secció nova utilitzant un FormCard i un FormHeader i un FormRadioDelegate.
FormCard.FormHeader {
title: i18n("Autosave")
}
FormCard.FormCard {
FormCard.FormSwitchDelegate {
id: autosave
text: i18n("Enabled")
}
FormCard.FormRadioDelegate {
text: i18n("After every change")
visible: autosave.checked
}
FormCard.FormRadioDelegate {
text: i18n("Every 10 minutes")
visible: autosave.checked
}
FormCard.FormRadioDelegate {
text: i18n("Every 30 minutes")
visible: autosave.checked
}
}
Vinculem la visibilitat de cada botó d'opció a un commutador, de manera que només apareixeran quan el commutador estigui habilitat.
Millors pràctiques
Feu clic aquí per a llegir-ne més
Si teniu algun coneixement de programació en llenguatges imperatius com C++, és possible que tingueu la temptació d'establir la propietat checked
del commutador per a activar la visibilitat dels botons d'opció a true
amb una assignació de JavaScript com:
checked: {
radio1.visible = true;
radio2.visible = true;
radio3.visible = true;
}
Això no és molt eficient per al llenguatge declaratiu del QML i els seus senyals i ranures. Intenteu utilitzar les vinculacions del QML com en el cas de visible: autosave.checked
tant com sigui possible en lloc d'expressions JavaScript.
Vegeu aquesta pàgina per als detalls.
Per a provar la nostra casella de selecció, podem afegir un FormCheckDelegate nou a la nostra secció General.
FormCard.FormHeader {
title: i18n("General")
}
FormCard.FormCard {
FormCard.FormTextDelegate {
text: i18n("Current Color Scheme")
description: "Breeze"
}
FormCard.FormCheckDelegate {
text: i18n("Show Tray Icon")
onToggled: {
if (checkState) {
console.info("A tray icon appears on your system!")
} else {
console.info("The tray icon disappears!")
}
}
}
}
Aquí utilitzem el manipulador de senyals onToggled
per a mostrar algun text fictici per a simular una icona de safata que apareix en el sistema. Si realment voleu, podeu implementar fàcilment una icona de la safata utilitzant SystemTrayIcon.
Finalment, la nostra aplicació s'hauria de veure així:
FormComboBoxDelegate
El component ComboBox comú es pot crear utilitzant un FormComboBoxDelegate.
Aquest quadre combinat té diverses propietats útils que podem fer servir: editable
, displayText
i displayMode
.
Establir editable: true
permet a l'usuari editar el text del quadre combinat, el qual és útil en cas que es necessitin opcions noves del quadre combinat:
Sempre que necessiteu mostrar text addicional abans de cada opció, podeu utilitzar alguna cosa com displayText: "Profile: " + currentText
:
I el més interessant, que utilitzarem en el nostre exemple, és displayMode
. Pot tenir tres opcions:
- FormComboBoxDelegate.ComboBox: el quadre petit estàndard que mostra una llista d'opcions.
- FormComboBoxDelegate.Dialog: un diàleg que mostra una llista d'opcions al mig de la finestra, com un Kirigami.OverlaySheet.
- FormComboBoxDelegate.Page: una pàgina nova que conté una llista d'opcions mostrades en una finestra separada.
Afegiu el següent entre els delegats de «Current Color Scheme» i «Show Tray Icon» a la targeta del formulari «General».
FormCard.FormComboBoxDelegate {
text: i18n("Default Profile")
description: i18n("The profile to be loaded by default.")
displayMode: FormCard.FormComboBoxDelegate.ComboBox
currentIndex: 0
editable: false
model: ["Work", "Personal"]
}
Amb la casella de selecció, la pàgina Configuració s'hauria de veure així:
FormDelegateSeparator
La nostra pàgina de configuració està prenent forma, però cada secció està començant a fer-se llarga. Podem afegir alguns FormDelegateSeparators per a fer que la nostra pàgina sigui més ordenada:
import QtQuick 2.15
import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
FormCard.FormCardPage {
id: root
title: i18nc("@title", "Settings")
FormCard.FormHeader {
title: i18nc("@title:group", "General")
}
FormCard.FormCard {
FormCard.FormTextDelegate {
text: i18nc("@info", "Current Color Scheme")
description: "Breeze"
}
FormCard.FormComboBoxDelegate {
id: combobox
text: i18nc("@label:listbox", "Default Profile")
description: i18nc("@info:whatsthis", "The profile to be loaded by default.")
displayMode: FormCard.FormComboBoxDelegate.ComboBox
currentIndex: 0
editable: false
model: ["Work", "Personal"]
}
FormCard.FormDelegateSeparator {
above: combobox
below: checkbox
}
FormCard.FormCheckDelegate {
id: checkbox
text: i18nc("@option:check", "Show Tray Icon")
onToggled: {
if (checkState) {
console.info("A tray icon appears on your system!")
} else {
console.info("The tray icon disappears!")
}
}
}
}
FormCard.FormHeader {
title: i18nc("@title:group", "Autosave")
}
FormCard.FormCard {
FormCard.FormSwitchDelegate {
id: autosave
text: i18nc("@option:check", "Enabled")
}
FormCard.FormDelegateSeparator {
above: autosave
below: firstradio
visible: autosave.checked
}
FormCard.FormRadioDelegate {
id: firstradio
text: i18nc("@option:radio", "After every change")
visible: autosave.checked
}
FormCard.FormRadioDelegate {
text: i18nc("@option:radio", "Every 10 minutes")
visible: autosave.checked
}
FormCard.FormRadioDelegate {
text: i18nc("@option:radio", "Every 30 minutes")
visible: autosave.checked
}
}
FormCard.FormHeader {
title: i18nc("@title:group", "Accounts")
}
FormCard.FormCard {
FormCard.FormSectionText {
text: i18nc("@info:whatsthis", "Online Account Settings")
}
FormCard.FormTextDelegate {
id: lastaccount
leading: Kirigami.Icon {source: "user"}
text: "John Doe"
description: i18nc("@info:credit", "The Maintainer ™️")
}
FormCard.FormDelegateSeparator {
above: lastaccount
below: addaccount
}
FormCard.FormButtonDelegate {
id: addaccount
icon.name: "list-add"
text: i18nc("@action:button", "Add a new account")
onClicked: console.info("Clicked!")
}
}
}
Generalment, podeu utilitzar separadors sempre que veieu distincions importants entre components, encara que l'elecció d'on col·locar-los és en última instància vostra. Per exemple, a la secció General, la casella de selecció difereix dels seus components anteriors, ja que no comença per text; a la secció Desament automàtic, el separador agrupa els botons d'opció; i a la secció Comptes, afegir un separador entre l'últim compte i el botó proporciona algun focus addicional al botó.
Les propietats above
i below
són bastant autoexplicatives pel que fa al seu ús: es passa el id
dels components per sobre i per sota del separador. Quan s'estableixin, el separador desapareixerà ràpidament cada vegada que es ressalti o es passi per sobre de l'element anterior o inferior. Són més útils, per exemple, quan necessiteu generar components dinàmicament i no podeu assumir automàticament quin element vindrà immediatament abans o després del separador. Aquest seria el cas a la secció de Comptes de la nostra aplicació una vegada que s'hagi implementat realment la lògica d'afegir comptes nous, i en aquest cas sempre podríem agafar l'últim element del model per a fer-ho.
Observeu com el separador que hi ha a sobre de la configuració de la icona de la safata no apareixerà mentre es passa per sobre.