Formulier gedelegeerden in uw instellingen pagina's
Kirigami-aanvullingen is een additionele set van visuele componenten die goed werken op een mobiel en bureaublad en gegarandeerd cross-platform zijn. Het gebruikt Kirigami onder de motorkap om zijn componenten aan te maken.
U hebt geleerd hoe de pagina's About en AboutKDE toe te voegen aan uw toepassing. Nu zult u in staat zijn om hun zelfde innerlijke componenten te gebruiken om uw instellingenpagina's aan te maken.
De projectstructuur zou er als volgt uit moeten zien:
addonsexample
├── CMakeLists.txt
├── main.cpp
├── Main.qml
├── MyAboutPage.qml
└── SettingsPage.qmlBenodigde wijzigingen
Wijzig Main.qml om onze nieuwe pagina Instellingen in te voegen:
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)
}
}
}
}
}We kunnen nu beginnen met de checkout van de componenten gebruikt om onze pagina Instellingenpage aan te maken: het formulier Card en zijn Gedelegeerden.
Formulier over gedelegeerden
FormCard en FormCardPage
FormCard.FormCard is de hoofdcomponent die we zullen gebruiken om alle zijn dochtercomponenten, de Gedelegeerden, te groeperen.
We gebruikten eerder een formulier-card in de Kirigami Addons introductie. Het hoofddoel hiervan is te dienen als een container voor andere componenten tijdens het volgen van een kleurverschil met de achtergrond, op een vergelijkbare manier met een Kirigami.Card.
Maak een nieuw bestand SettingsPage.qml:
import QtQuick
import org.kde.kirigamiaddons.formcard as FormCard
FormCard.FormCardPage {
FormCard.FormCard {
// Dit is waar alle gedelegeerden naartoe gaan!
}
FormCard.FormCard {
// Dit is waar alle gedelegeerden naartoe gaan!
}
}Omdat we een apart QML-bestand gaan maken voor onze pagina Instellingen en omdat we voor potentieel schuiven in onze pagina ons willen voorbereiden, gebruiken we een FormCard.FormCardPage, die Kirigami.ScrollablePage erft.
Het mooie van de pagina form-card is dat het komt met een interne indeling, dus is geen extra ColumnLayout nodig en onze gedelegeerden kunnen direct eraan worden toegevoegd.
Note
Het is mogelijk FormCard gedelegeerden direct te gebruiken met een Kirigami.ScrollablePage, maar in dat geval moet u uw eigen indelingen toevoegen.Formulierkop
Voor elke FormCard die u wilt aanmaken kunt u een FormHeader ervoor aanmaken. De kop gebruikt vette tekst en toont omhoog bovenaan de formcard.
import org.kde.kirigamiaddons.formcard as FormCard
FormCard.FormCardPage {
FormCard.FormHeader {
title: i18n("General")
}
FormCard.FormCard {
// Onze gedelegeerden gaan hier...
}
FormCard.FormHeader {
title: i18n("Accounts")
}
FormCard.FormCard {
// Onze gedelegeerden gaan hier...
}
}FormTextDelegate en FormSectionText
Laten we eenvoudig beginnen met platte tekst.
FormSectionText voegt eenvoudig een dunne gedelegeerde toe die een label bevat. FormTextDelegate heeft tekst en een grijze beschrijving.
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 ™️")
}
}
}We voegen enige dummy tekst toe voor de hypothetische detectie van het thema. Als we echt detectie van het kleurschema willen hebben, kan dat in de toekomst op dezelfde manier gedaan worden aan Neochat (code hier), gebruik makend van een C++ model met KColorSchemeManager.
In de sectie Online accounts zien we een extra eigenschap, leading. We kunnen een Item er aan toevoegen zodat het verschijnt voor de tekst. Zijn tegengestelde eigenschap, trailing, zou in staat zijn een Item achter de tekst te tonen, maar we zullen dat niet in ons programma gebruiken.
We gebruiken hier eenvoudig een Kirigami.Icon, maar dit zou ook geïmplementeerd kunnen worden met een Kirigami Addons Avatar die de informatie pakt uit een model, zoals gedaan is in Neochat.
Het zou er uiteindelijk als volgt uit moeten zien:

FormButtonDelegate
De FormButtonDelegate is visueel gelijk aan een FormTextDelegate, maar er is op te klikken en toont een pijl wijzend naar rechts. We gebruikten het eerder in de Kirigami Addons introductie.
Terwijl de FormTextDelegate de eigenschappen leading en trailing hadden om een item voor en na de hoofdinhoud te tonen, zo heeft de FormButtonDelegate slechts de eigenschap leading, omdat de rechterkant bezet is door de pijl.
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!")
}
}
}We gebruiken zijn eigenschap icon.name om een pluspictogram (+) te laten verschijnen na de ruimte waar de leading zou verschijnen en voor de hoofdinhoud. Dit is een algemeen patroon om aan te geven dat uw knop iets aan een lijst wil toevoegen.
Omdat dit voorbeeld een eenvoudig illustratief doel heeft, gaan we niet dieper in wat zou gedaan worden nadat op de knop is geklikt: het print eenvoudig "Geklikt!" op de terminal. We zouden een nieuwe pagina kunnen maken voor aanmaken van een account die een andere gebruiker toevoegt aan een model, daarna de pagina laat zien, gelijk aan wat we deden in Main.qml.

FormRadioDelegate, FormCheckDelegate en FormSwitchDelegate
De RadioButton, CheckBox en Switch zijn erg gebruikelijke componenten in elke gebruikersinterface. Kirigami Addons levert ze als FormRadioDelegate, FormCheckDelegate en FormSwitchDelegate.
Hun enige hoofdeigenschappen zijn tekst en beschrijving. Ze zijn anders in gebruik omdat ze allemaal AbstractButtonerven en dus van u wordt verwacht hun signalen en hendels te gebruiken: geactiveerd en niet-geactiveerd, omgeschakeld en niet-omgeschakeld, geklikt en niet-geklikt.
We willen enige auto-opslag functionaliteit in uw toepassing aanmaken en we willen alleen zijn instellingen tonen als de gebruiker deze functionaliteit heeft ingeschakeld. Maak een nieuwe sectie aan met een FormCard en een FormHeader, voeg daarna een FormSwitchDelegate toe en een 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
}
}We verbinden de zichtbaarheid van elk keuzerondje aan een schakelaar, ze verschijnen dus alleen wanneer de schakelaar is ingeschakeld.
Beste praktijk
Klik hier om meer te lezen
Als u enige achtergrond hebt in programmeren in imperatieve talen zoals C++, dan zou u verleid kunnen worden om de eigenschap geactiveerd aan de schakelaar te hangen om de zichtbaarheid van het keuzerondje op true te zetten met een JavaScript toekenning zoals:
checked: {
radio1.visible = true;
radio2.visible = true;
radio3.visible = true;
}Dit is niet erg efficiënt voor de declaratie taal QML en zijn signalen en slots. Probeer de binding aan QML zo veel mogelijk te gebruiken zoals in het geval van visible: autosave.checked in plaats van JavaScript expressies.
Zie deze pagina voor details.

Om ons keuzevakje te testen kunnen we een nieuwe FormCheckDelegate toevoegen aan onze sectie Algemeen.
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!")
}
}
}
}Hier gebruiken we de signaalbehandelaar genaamd onToggled om enige dummy tekst te tonen om een pictogram in het systeemvak te simuleren die in het systeem verschijnt. Als u dat echt wilt, zou u gemakkelijk een pictogram in het systeemvak kunnen implementeren met KDE's KStatusNotifierItem of Qt's SystemTrayIcon.
Tot zover zal onze toepassing er uitzien zoals deze:

FormComboBoxDelegate
The common ComboBox component can be created using a FormComboBoxDelegate.
Deze keuzelijst heeft verschillende nuttige eigenschappen waar we gebruik van kunnen a maken: bewerkbaar, displayText en displayMode.
Instellen van editable: true biedt de gebruiker het bewerken van de tekst van het keuzevak, wat nuttig is in geval dat toevoegen van nieuwe opties in het keuzevak nodig is:

Wanneer u het tonen van extra tekst voor elke optie nodig hebt, kunt u zoiets als displayText: "Profile: " + currentText gebruiken:

And the most interesting one, which we will be using in our example, is displayMode. It can have three options:
- FormComboBoxDelegate.ComboBox: het standaard kleine vak die een lijst met opties toont.

- FormComboBoxDelegate.Dialog: a dialog showing a list of options in the middle of the window, like a Kirigami.OverlaySheet.

- FormComboBoxDelegate.Page: een nieuwe pagina die een lijst met opties bevat in een apart venster.

Voeg het volgende toe tussen het "Huidige kleurenschema" en "Pictogram in systeemvak tonen" gedelegeerden in uw formulierkaart "Algemeen".
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"]
}Met het keuzevakje zou de pagina Instellingen er uitzien zoals deze:

FormDelegateSeparator
Our Settings page is taking shape, but each section is starting to get long. We can add a few FormDelegateSeparator instances to make our page tidier:
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!")
}
}
}
In het algemeen kunt u scheidingen gebruiken wanneer u belangrijk onderscheid ziet tussen componenten, hoewel de keuze waar deze te plaatsen uiteindelijk aan u is. Bijvoorbeeld, in de sectie General, verschilt het keuzevakje van zijn vorige componenten omdat het niet met tekst begint; in de sectie Autosave, groepeert de scheiding de keuzerondjes; en in sectie Accounts, levert een scheiding tussen het laatste account en de knop toevoegen enige extra focus op de knop.
The above and below properties are rather self-explanatory when it comes to their use: you pass the id of the components above and below the separator. When they are set, the separator will swiftly disappear whenever the above or below item is highlighted/hovered. They are most useful, for instance, when you need to generate components dynamically and you can't automatically assume which item will come immediately before or after the separator. That would be the case in the Accounts section of our application once the logic to add new accounts were actually implemented, in which case we could always grab the last item in the model to do so.

Merk op hoe de scheider boven de instelling van het pictogram in het systeemvak niet verschijnt bij er boven zweven.