Skip to main content
Passa al contenuto

Forma i delegati nelle pagine delle impostazioni

Crea eleganti pagine di impostazioni personalizzate.

Kirigami Addons è un insieme aggiuntivo di componenti visivi che funzionano bene su dispositivi mobili e desktop e sono garantiti multipiattaforma. Utilizza Kirigami sotto il cofano per creare i suoi componenti.

Hai imparato come aggiungere Pagine Informazioni e Informazioni su KDE alla tua applicazione. Ora sarai in grado di utilizzare gli stessi componenti interni per creare le tue pagine di impostazioni.

La struttura del progetto dovrebbe assomigliare a questa:

addonsexample
├── CMakeLists.txt
├── main.cpp 
├── Main.qml
├── MyAboutPage.qml
└── SettingsPage.qml

Modifiche necessarie

Modifica Main.qml per includere la nostra nuova pagina Impostazioni:

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)
                }
            }
        }
    }
}

Ora possiamo iniziare a verificare i componenti utilizzati per creare la nostra pagina Impostazioni: la scheda modulo e i suoi delegati.

Delegati modulo

FormCard e FormCardPage

FormCard.FormCard è il componente principale che useremo per raggruppare tutti i suoi componenti figli, i Delegati.

In precedenza abbiamo utilizzato una scheda modulo nell'Introduzione ai componenti aggiuntivi di Kirigami. Il suo scopo principale è quello di fungere da contenitore per altri componenti seguendo un colore diverso dallo sfondo, in modo simile a una Kirigami.Card.

Crea un nuovo file "SettingsPage.qml":

import QtQuick
import org.kde.kirigamiaddons.formcard as FormCard

FormCard.FormCardPage {
    FormCard.FormCard {
        // È qui che vanno tutti i nostri delegati!
    }

    FormCard.FormCard {
        // È qui che vanno tutti i nostri delegati!
    }
}

Poiché stiamo creando un file QML separato per la nostra pagina Impostazioni e poiché dobbiamo prepararci per un potenziale scorrimento nella nostra pagina, utilizziamo una FormCard.FormCardPage, che eredita Kirigami.ScrollablePage.

L'aspetto interessante della pagina della scheda modulo è che viene fornita con un layout interno, quindi non è necessario alcun ColumnLayout aggiuntivo e i nostri delegati possono essere aggiunti direttamente ad essa.

FormHeader

Per ogni FormCard che vuoi creare, puoi creare un FormHeader subito prima. L'intestazione utilizza testo in grassetto e viene visualizzata proprio sopra la scheda del modulo.

import org.kde.kirigamiaddons.formcard as FormCard

FormCard.FormCardPage {
    FormCard.FormHeader {
        title: i18n("General")
    }

    FormCard.FormCard {
        // I nostri delegati vanno qui...
    }

    FormCard.FormHeader {
        title: i18n("Accounts")
    }

    FormCard.FormCard {
        // I nostri delegati vanno qui...
    }
}

FormTextDelegate e FormSectionText

Iniziamo in modo semplice, con testo semplice.

FormSectionText aggiunge semplicemente un thin delegato contenente un'etichetta. FormTextDelegate contiene testo e una descrizione in grigio.

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 ™️")
        }
    }
}

Aggiungiamo del testo fittizio per l'ipotetico rilevamento del tema. Se volessimo avere un effettivo rilevamento dello schema di colori, in futuro potremmo farlo in modo simile a Neochat (codice qui), facendo uso di un modello C++ con KColorSchemeManager.

Nella sezione Account in linea, vediamo una proprietà aggiuntiva, leading. Possiamo aggiungere un Elemento in modo che appaia prima del testo. La sua proprietà opposta, trailing, sarebbe in grado di mostrare un oggetto dopo il testo, ma non lo useremo nel nostro programma.

Usiamo un Kirigami.Icon qui per semplicità, ma questo potrebbe anche essere implementato utilizzando un Kirigami Addons Avatar che prende le informazioni da un modello, come fatto in Neochat.

L'aspetto finale dovrebbe essere questo:

FormButtonDelegate

Il FormButtonDelegate è visivamente simile a FormTextDelegate, ma è selezionabile e mostra una freccia che punta a destra. L'abbiamo già utilizzato nell'Introduzione ai componenti aggiuntivi di Kirigami.

Mentre FormTextDelegate aveva le proprietà leading e trailing per mostrare un elemento prima e dopo il contenuto principale, il FormButtonDelegate ha solo la proprietà leading, perché il lato destro è occupato dalla freccia.

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!")
        }
    }
}

Usiamo la sua proprietà icon.name per impostare un'icona più (+) in modo che appaia dopo lo spazio in cui apparirà leading e prima del main content. Questo è uno schema comune per indicare che il tuo pulsante aggiungerà qualcosa a un elenco.

Poiché questo esempio è per semplici scopi illustrativi, non approfondiamo cosa si farebbe una volta cliccato il pulsante: viene semplicemente stampato "Clicked!" to the terminal. Potremmo potremmo creare una nuova pagina per la creazione di un account che aggiunga un altro utente a un modello, quindi rendere visibile la pagina, in modo simile a quello che abbiamo fatto in Main.qml.

FormRadioDelegate, FormCheckDelegate e FormSwitchDelegate

RadioButton, CheckBox e Switch sono componenti molto comunemente utilizzati in qualsiasi interfaccia utente. I componenti aggiuntivi di Kirigami li forniscono come FormRadioDelegate, FormCheckDelegate e FormSwitchDelegate.

Le loro uniche proprietà principali sono "testo" e "descrizione". Sono diversi nell'utilizzo perché ereditano tutti AbstractButton e quindi ci si aspetta che tu usi i suoi segnali e gestori: check e onChecked, toggled e onToggled, clicked e onClicked.

Vogliamo creare alcune funzionalità di salvataggio automatico nella nostra applicazione e vogliamo mostrare le sue impostazioni solo se l'utente ha abilitato questa funzionalità. Crea una nuova sezione utilizzando una FormCard e una FormHeader, quindi aggiungi una FormSwitchDelegate e 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
    }
}

Associamo la visibilità di ciascun pulsante di opzione a un interruttore, in modo che vengano visualizzati solo quando l'interruttore è abilitato.

Per testare la nostra casella di controllo, possiamo aggiungere un nuovo FormCheckDelegate alla nostra sezione Generale.

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!")
            }
        }
    }
}

Qui utilizziamo il gestore del segnale chiamato onToggled per mostrare del testo fittizio per simulare un'icona nella barra delle applicazioni che appare nel sistema. Se lo desideri davvero, puoi facilmente implementare un'icona nel vassoio utilizzando KStatusNotifierItem di KDE o SystemTrayIcon.

Alla fine la nostra applicazione dovrebbe assomigliare a questa:

FormComboBoxDelegate

Il componente ComboBox comune può essere creato utilizzando un FormComboBoxDelegate.

Questa casella combinata ha diverse proprietà utili che possiamo utilizzare: editable, displayText e displayMode.

L'impostazione "editable: true" consente all'utente di modificare il testo della casella combinata, il che è utile nel caso in cui sia necessaria l'aggiunta di nuove opzioni della casella combinata:

Ogni volta che devi mostrare del testo aggiuntivo prima di ciascuna opzione, puoi usare qualcosa come displayText: "Profile: " + currentText:

E quello più interessante, che useremo nel nostro esempio, è displayMode. Può avere tre opzioni:

  • FormComboBoxDelegate.ComboBox: il piccolo riquadro standard che mostra un elenco di opzioni.
  • FormComboBoxDelegate.Dialog: una finestra di dialogo che mostra un elenco di opzioni al centro della finestra, come un Kirigami.OverlaySheet.
  • FormComboBoxDelegate.Page: una nuova pagina contenente un elenco di opzioni mostrate in una finestra separata.

Aggiungi quanto segue tra i delegati "Schema colori corrente" e "Mostra icona nella barra delle applicazioni" nella scheda del modulo "Generale".

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"]
}

Con la casella di controllo, la nostra pagina Impostazioni dovrebbe assomigliare a questa:

FormDelegateSeparator

La nostra pagina Impostazioni sta prendendo forma, ma ogni sezione inizia a diventare lunga. Possiamo aggiungere alcune istanze di FormDelegateSeparator per rendere la nostra pagina più ordinata:

import QtQuick
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard 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 generale, è possibile utilizzare i separatori ogni volta che si notano distinzioni importanti tra i componenti, anche se la scelta di dove posizionarli spetta in definitiva a voi. Ad esempio, nella sezione Generale, la casella di controllo differisce dai suoi componenti precedenti poiché non inizia con il testo; nella sezione Salvataggio automatico, il separatore raggruppa i pulsanti radio; e nella sezione Account, l'aggiunta di un separatore tra l'ultimo account e il pulsante fornisce ulteriore attenzione al pulsante.

Le proprietà sopra e sotto sono piuttosto autoesplicative per quanto riguarda il loro utilizzo: si passa il "id" dei componenti sopra e sotto il separatore. Una volta impostati, il separatore scomparirà rapidamente ogni volta che l'elemento sopra o sotto viene evidenziato/passato sopra. Sono particolarmente utili, ad esempio, quando è necessario generare componenti in modo dinamico e non è possibile assumere automaticamente quale elemento verrà immediatamente prima o dopo il separatore. Questo sarebbe il caso nella sezione Account della nostra applicazione una volta implementata la logica per aggiungere nuovi account, nel qual caso potremmo sempre prendere l'ultimo elemento nel modello per farlo.

Nota come il separatore sopra l'impostazione dell'icona nella barra delle applicazioni non viene visualizzato mentre ci si passa sopra.