Skip to main content
Ir para o conteúdo

Formulário delegados em suas páginas de configurações

Crie páginas de configurações personalizadas e elegantes.

Os Addons do Kirigami é um conjunto adicional de componentes visuais que funcionam bem em dispositivos móveis e desktops, com garantia de compatibilidade entre plataformas. Ele utiliza Kirigami internamente para criar seus componentes.

Você aprendeu como adicionar as páginas Sobre e Sobre o KDE ao seu aplicativo. Agora você poderá usar os mesmos componentes internos para criar suas páginas de configurações.

A estrutura do projeto deve ser semelhante a esta:

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

Alterações necessárias

Altere Main.qml para incluir nossa nova página de configurações:

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

Agora podemos começar a verificar os componentes usados ​​para criar nossa página de Configurações: o Cartão de Formulário e seus Delegados.

Formulários delegados

FormCard e FormCardPage

[FormCard.FormCard](https://api.kde.org/frameworks/kirigami-addons /html/classFormCard.html) é o componente principal que usaremos para agrupar todos os seus componentes filhos, os Delegados.

Usamos um cartão de formulário na introdução aos Addons do Kirigami anteriormente. Seu principal objetivo é servir como um contêiner para outros componentes, seguindo uma cor diferente do fundo, de forma semelhante a um Kirigami.Card.

Crie um novo arquivo SettingsPage.qml:

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

FormCard.FormCardPage {
    FormCard.FormCard {
        // É aqui que todos os nossos delegados vão!
    }

    FormCard.FormCard {
        // É aqui que todos os nossos delegados vão!
    }
}

Como estamos criando um arquivo QML separado para nossa página de Configurações e como precisamos nos preparar para uma possível rolagem em nossa página, usamos um FormCard.FormCardPage, que herda Kirigami.ScrollablePage.

O interessante da página do cartão de formulário é que ela vem com um layout interno, portanto, nenhum ColumnLayout adicional é necessário e nossos delegados podem ser adicionados diretamente a ela.

FormHeader

Para cada [FormCard](https://api.kde.org/frameworks/kirigami-addons /html/classFormCard.html) que você deseja criar, você pode criar um [FormHeader](https://api.kde.org/frameworks/kirigami-addons /html/classFormHeader.html) logo antes dele. O cabeçalho usa texto em negrito e aparece logo acima do cartão de formulário.

import org.kde.kirigamiaddons.formcard as FormCard

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

    FormCard.FormCard {
        // Nossos delegados vão aqui...
    }

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

    FormCard.FormCard {
        // Nossos delegados vão aqui...
    }
}

FormTextDelegate e FormSectionText

Vamos começar de forma simples, com texto simples.

FormSectionText simplesmente adiciona um delegado fino contendo um rótulo. FormTextDelegate tem texto e uma descrição em cinza.

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

Adicionamos um texto fictício para a detecção hipotética do tema. Se quiséssemos ter uma detecção real do esquema de cores, no futuro isso poderia ser feito de forma semelhante ao Neochat (código aqui), utilizando um modelo C++ com KColorSchemeManager.

Na seção Contas Online, vemos uma propriedade adicional, leading. Podemos adicionar um Item a ela para que apareça antes do texto. Sua propriedade oposta, trailing, seria capaz de mostrar um Item após o texto, mas não a usaremos em nosso programa.

Usamos um Kirigami.Icon aqui para simplificar, mas isso também pode ser implementado usando um Kirigami.Avatar que obtém as informações de um modelo, como é feito no Neochat aqui.

Deve ficar assim:

FormButtonDelegate

O [FormButtonDelegate](https://api.kde.org/frameworks/kirigami-addons /html/classFormButtonDelegate.html) é visualmente semelhante a um FormTextDelegate, mas é clicável e exibe uma seta apontando para a direita. Já o usamos na introdução aos Addons do Kirigami anteriormente.

Enquanto o FormTextDelegate tinha as propriedades leading e trailing para mostrar um item antes e depois do conteúdo principal, o FormButtonDelegate possui apenas a propriedade leading, porque o lado direito é ocupado pela seta.

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

Usamos a propriedade icon.name para definir um ícone de mais (+) que aparecerá após o espaço onde o leading apareceria e antes do conteúdo principal. Este é um padrão comum para indicar que seu botão adicionará algo a uma lista.

Como este exemplo é apenas para fins ilustrativos, não nos aprofundamos no que seria feito quando o botão fosse clicado: ele apenas imprime "Clicado!" no terminal. Poderíamos criar uma nova página para criação de conta que adicionasse outro usuário a um modelo e, em seguida, colocasse a página na visualização, semelhantemente ao que fizemos em Main.qml.

FormRadioDelegate, FormCheckDelegate e FormSwitchDelegate

O RadioButton, o CheckBox e o Switch são componentes muito utilizados em qualquer interface de usuário. Os Addons do Kirigami os fornece como [FormRadioDelegate](https://api.kde.org/frameworks/kirigami-addons /html/classFormRadioDelegate.html), [FormCheckDelegate](https://api.kde.org/frameworks/kirigami-addons /html/classFormCheckDelegate.html) e [FormSwitchDelegate](https://api.kde.org/frameworks/kirigami-addons /html/classFormSwitchDelegate.html).

Suas únicas propriedades principais são text e description. Elas são diferentes no uso porque todas herdam AbstractButton, e portanto, espera-se que você use seus sinais e manipuladores: checked e onChecked, toggled e onToggled, clicked e onClicked.

Queremos criar uma funcionalidade de salvamento automático em nosso aplicativo e queremos mostrar suas configurações apenas se o usuário tiver habilitado essa funcionalidade. Crie uma nova seção usando um [FormCard](https://api.kde.org/frameworks/kirigami-addons /html/classFormCard.html) e um [FormHeader](https://api.kde.org/frameworks/kirigami-addons /html/classFormHeader.html), depois adicione um [FormSwitchDelegate](https://api.kde.org/frameworks/kirigami-addons /html/classFormSwitchDelegate.html) e um [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
    }
}

Nós vinculamos a visibilidade de cada botão de opção a um botão de opção, para que eles só apareçam quando o botão estiver habilitado.

Para testar nossa caixa de seleção, podemos adicionar um novo [FormCheckDelegate](https://api.kde.org/frameworks/kirigami-addons /html/classFormCheckDelegate.html) à nossa seção Geral.

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

Aqui, usamos o manipulador de sinais onToggled para exibir um texto fictício que simula um ícone de bandeja aparecendo no sistema. Se você realmente quisesse, poderia facilmente implementar um ícone de bandeja usando SystemTrayIcon.

Até agora, nossa aplicação deve ficar assim:

FormComboBoxDelegate

O componente ComboBox comum pode ser criado usando um [FormComboBoxDelegate](https://api.kde.org/frameworks/kirigami-addons /html/classFormComboBoxDelegate.html).

Este combobox tem várias propriedades úteis que podemos utilizar: editable, displayText e displayMode.

Definir editable: true permite que o usuário edite o texto do combobox, o que é útil caso seja necessário adicionar novas opções ao combobox:

Sempre que precisar mostrar texto adicional antes de cada opção, você pode usar algo como displayText: "Perfil: " + currentText:

E o mais interessante, que usaremos em nosso exemplo, é o displayMode. Ele pode ter três opções:

  • FormComboBoxDelegate.ComboBox: a pequena caixa padrão mostrando uma lista de opções.
  • FormComboBoxDelegate.Dialog: uma caixa de diálogo que mostra uma lista de opções no meio da janela, como uma Kirigami.OverlaySheet.
  • FormComboBoxDelegate.Page: uma nova página contendo uma lista de opções exibidas em uma janela separada.

Adicione o seguinte entre os delegados "Esquema de cores atual" e "Mostrar ícone da bandeja" no seu cartão de formulário "Geral".

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

Com a caixa de seleção, nossa página Configurações deve ficar assim:

FormDelegateSeparator

Nossa página de Configurações está tomando forma, mas cada seção está começando a ficar longa. Podemos adicionar alguns FormDelegateSeparators para deixar nossa página mais organizada:

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

Geralmente, você pode usar separadores sempre que notar grandes distinções entre componentes, embora a escolha de onde colocá-los seja, em última análise, sua. Por exemplo, na seção Geral, a caixa de seleção difere de seus componentes anteriores, pois não começa com texto; na seção Salvamento automático, o separador agrupa os botões de opção; e na seção Contas, adicionar um separador entre a última conta e o botão fornece algum foco adicional ao botão.

As propriedades above e below são bastante autoexplicativas quando se trata de seu uso: você passa o id dos componentes acima e abaixo do separador. Quando elas são definidas, o separador desaparece rapidamente sempre que o item acima ou abaixo é destacado/passado pelo mouse. Elas são mais úteis, por exemplo, quando você precisa gerar componentes dinamicamente e não pode presumir automaticamente qual item virá imediatamente antes ou depois do separador. Esse seria o caso na seção Contas da nossa aplicação uma vez que a lógica para adicionar novas contas fosse implementada, nesse caso sempre poderíamos pegar o último item do modelo para fazer isso.

Observe como o separador acima da configuração do ícone da bandeja não aparece enquanto o mouse passa por ele.