Formulärdelegater på inställningssidorna
Kirigami Addons är en ytterligare uppsättning visuella komponenter som fungerar bra på mobiler och skrivbordsdatorer och är garanterade att fungera på flera plattformar. De använder Kirigami i bakgrunden för att skapa sina komponenter.
Du har lärt dig hur man lägger till About- och AboutKDE-sidor i programmet. Nu kan du använda samma inre komponenter för att skapa inställningssidor.
Projektstrukturen ska se ut så här:
addonsexample
├── CMakeLists.txt
├── main.cpp
├── Main.qml
├── MyAboutPage.qml
└── SettingsPage.qml
Nödvändiga ändringar
Ändra Main.qml
för att inkludera vår nya inställningssida:
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)
}
}
}
}
}
Vi kan nu börja titta på komponenterna som används för att skapa vår inställningssida: formulärkortet och dess delegater.
Formulärdelegater
FormCard och FormCardPage
FormCard.FormCard är huvudkomponenten vi använder för att gruppera alla dess underordnade komponenter, delegaterna.
Vi använde ett formulärkort tidigare i Kirigami Addons introduktion. Dess huvudsakliga syfte är att fungera som en behållare för andra komponenter samtidigt som det följer en färg som skiljer sig från bakgrunden, på ett liknande sätt som ett Kirigami.Card.
Skapa en ny fil, SettingsPage.qml
:
import QtQuick
import org.kde.kirigamiaddons.formcard as FormCard
FormCard.FormCardPage {
FormCard.FormCard {
// Det är här alla våra delegater ska finnas.
}
FormCard.FormCard {
// Det är här alla våra delegater ska finnas.
}
}
Eftersom vi gör en separat QML-fil för vår inställningssida, och eftersom vi behöver förbereda oss för eventuell panorering av vår sida, använder vi FormCard.FormCardPage
, som ärver Kirigami.ScrollablePage.
Det fina med formulärkortsidan är att en intern layout ingår, så ingen ytterligare ColumnLayout behövs och våra delegater kan läggas till direkt.
Note
Det är möjligt att använda FormCard delegater direkt med en Kirigami.ScrollablePage, men i detta fall måste en egen layout läggas till.FormHeader
För varje FormCard som ska skapas, kan man skapa en FormHeader precis innan den. Huvudet använder text med fetstil och visas precis ovanför formulärkortet.
import org.kde.kirigamiaddons.formcard as FormCard
FormCard.FormCardPage {
FormCard.FormHeader {
title: i18n("General")
}
FormCard.FormCard {
// Våra delegater ska finnas här...
}
FormCard.FormHeader {
title: i18n("Accounts")
}
FormCard.FormCard {
// Våra delegater ska finnas här...
}
}
FormTextDelegate och FormSectionText
Låt oss börja enkelt, med vanlig text.
FormSectionText
lägger helt enkelt till en enkel delegat som innehåller en beteckning. FormTextDelegate
har text och en nedtonad beskrivning.
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 ™️")
}
}
}
Vi lägger till lite text som platsmarkering för den hypotetiska temadetekteringen. Om vi ville ha verklig färgschemadetektering skulle det i framtiden kunna göras på samma sätt som i Neochat (code here), med användning av en C++ modell med KColorSchemeManager.
I sektionen Online Accounts ser vi en ytterligare egenskap, leading
. Vi kan lägga till ett Item i den så att den visas före texten. Dess omvända egenskap, trailing
, skulle kunna visa ett objekt efter texten, men vi använder inte den i programmet.
Vi använder en Kirigami.Icon här för enkelhetens skull, med det skulle också kunna implementeras genom att använda Kirigami.Avatar som hämtar information från en modell, vilket görs här i Neochat.
Slutligen ska det se ut så här:
FormButtonDelegate
FormButtonDelegate liknar FormTextDelegate visuellt, men är klickbar och visar en pil som pekar åt höger. Vi använde den tidigare i Kirigami Addons introduktion.
Medan FormTextDelegate har egenskaperna leading
och trailing
för att visa ett objekt före eller efter huvudinnehållet, har FormButtonDelegate bara egenskapen leading
, eftersom den högra sidan är upptagen av pilen.
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!")
}
}
}
Vi använder dess egenskap icon.name
för att ange en plusikon (+) som ska visas efter utrymmet där leading
skulle visas, och före huvudinnehållet. Det är ett vanligt mönster för att indikera att knappen lägger till något i en lista.
Eftersom exemplet är för enkla illustrativa syften, går vi inte djupt in på vad som skulle göras när man väl klickar på knappen: den skriver bara ut "Clicked!" på terminalen. Vi kan göra en ny sida för att skapa ett konto som lägger till en annan användare till en modell, och sedan visar sidan, på samma sätt som vi gjorde i Main.qml
.
FormRadioDelegate, FormCheckDelegate och FormSwitchDelegate
RadioButton, CheckBox och Switch är mycket vanliga komponenter i alla användargränssnitt. Kirigami Addons tillhandahåller dem som FormRadioDelegate, FormCheckDelegate och FormSwitchDelegate.
Deras enda huvudegenskaper är text
och description
. De är olika vid användning eftersom de alla ärver AbstractButton, och därför förväntas man använda dess signaler och hanterare: checked och onChecked, toggled och onToggled, clicked och onClicked.
Vi vill skapa en del funktioner för att spara automatiskt i vårt program, och vi vill bara visa dess inställningar om användaren har aktiverat funktionaliteten. Skapa en ny sektion med ett FormCard och en [FormHeader](https://api.kde.org/frameworks/ kirigami-addons/html/classFormHeader.html), lägg sedan till en FormSwitchDelegate och en [FormRadioDelegate](https:// api.kde.org/frameworks/kirigami-addons/html/classFormRadioDelegate.html).
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
}
}
Vi kopplar synligheten för varje alternativknapp till en omkopplare, så de bara visas när omkopplaren är aktiverad.
Bästa metoder
Klicka här för att läsa mer
Om du har viss programmeringsbakgrund med imperativa språk som C++, kan du bli frestad att använda omkopplarens egenskap checked
för att ändra synlighet för alternativknapparna till "true" med en tilldelning i JavaScript som:
checked: {
radio1.visible = true;
radio2.visible = true;
radio3.visible = true;
}
Det är inte särskilt effektivt med QML:s deklarativa språk och dess signaler och slots. Försök att använda QML-bindningar som i fallet med visible: autosave.checked
så mycket som möjligt istället för uttryck i JavaScript.
Se den här sidan för detaljinformation.
För att prova vår kryssruta, kan vi lägga till en ny FormCheckDelegate i sektionen 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!")
}
}
}
}
Här använder vi signalhanteraren onToggled
för att visa lite text som platsmarkering för att simulera att en brickikon visas i systemet. Om du verkligen vill, skulle du enkelt kunna implementera en brickikon med användning av SystemTrayIcon.
Hittills ska programmet se ut så här:
FormComboBoxDelegate
Den vanliga komponenten ComboBox kan skapas med hjälp av en FormComboBoxDelegate.
Kombinationsrutan har flera användbara egenskaper som vi kan använda: editable
, displayText
och displayMode
.
Att ställa in editable: true
låter användaren redigera text i kombinationsrutan, vilket är användbart om tillägg av nya alternativ i kombinationsrutan behövs:
När du behöver visa ytterligare text före varje alternativ kan du använda något som liknar displayText: "Profile: " + currentText
:
Och det mest intressanta, som vi kommer att använda i vårt exempel, är displayMode
. Det kan ha tre alternativ:
- FormComboBoxDelegate.ComboBox: Den lilla standardrutan som visar en lista med alternativ.
- FormComboBoxDelegate.Dialog: En dialogruta som visar en lista med alternativ i mitten av fönstret, som ett Kirigami.OverlaySheet.
- FormComboBoxDelegate.Page: En ny sida som innehåller en lista med alternativ som visas i ett separat fönster.
Lägg till följande mellan delegaterna "Current Color Scheme" och "Show Tray Icon" på formulärkortet "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"]
}
Med kryssrutan ska inställningssidan se ut så här:
FormDelegateSeparator
Vår inställningssida tar form, men varje sektion börjar bli lång. Vi kan lägga till några FormDelegateSeparators för att göra vår sida snyggare:
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!")
}
}
}
I allmänhet kan avskiljare användas när det finns stora skillnader mellan komponenter, även om valet av var du ska placera dem i slutändan är fritt. Till exempel, i sektionen General, skiljer sig kryssrutan från de tidigare komponenterna eftersom den inte börjar med text, i sektionen Autosave grupperar avskiljaren alternativknapparna, och i sektionen Accounts, ger tillägg av en avskiljare mellan det sista kontot och knappen lite extra fokus på knappen.
Egenskaperna above
och below
är ganska självförklarande när det gäller deras användning: man skickar "id" för komponenterna ovanför och under avskiljaren. När de är inställda försvinner avskiljaren snabbt när objektet ovan eller under markeras eller musen hålls över det. De är mest användbara, när komponenter behöver genereras dynamiskt och det inte går att automatiskt anta vilket objekt som kommer omedelbart före eller efter avskiljaren. Det vore fallet i sektionen Accounts i vårt program när logiken för att lägga till nya konton faktiskt implementeras, då vi alltid skulle kunna ta det sista objektet i modellen för att göra det.
Lägg märke till hur avskiljaren ovanför brickikonens inställning inte visas när musen hålls över den.