Form delegates in your settings pages
Create elegant custom settings pages.
Kirigami Addons is an additional set of visual components that work well on mobile and desktop and are guaranteed to be cross-platform. It uses Kirigami under the hood to create its components.
You have learned how to add About and AboutKDE pages to your application. Now you will be able to use their same inner components to create your settings pages.
The project structure should look like this:
Needed Changes
Add a new line to our resources.qrc
:
Ah ah ah
This file is not available.
And change main.qml
to include our new Settings page:
We can now start checking out the components used to create our Settings page: the Form Card and its Delegates.
Form Delegates
FormCard and FormCardPage
FormCard.FormCard is the main component we will be using to group all its child components, the Delegates.
We used a form card in the Kirigami Addons introduction before. Its main purpose is to serve as a container for other components while following a color different from the background, in a similar manner to a Kirigami.Card.
Create a new contents/ui/SettingsPage.qml
file:
Since we are making a separate QML file for our Settings page, and since we need to prepare for potential scrolling in our page, we use a FormCard.FormCardPage
, which inherits Kirigami.ScrollablePage.
The nice thing about the form card page is that it comes with an internal layout, so no additional ColumnLayout is needed and our delegates can be added directly to it.
Note It is possible to use FormCard delegates directly with a Kirigami.ScrollablePage, but in that case you will need to add your own layouts.
FormHeader
For every FormCard you want to create, you can create a FormHeader just before it. The header uses bold text and shows up right above the form card.
FormTextDelegate and FormSectionText
Let's start simple, with plain text.
FormSectionText
simply adds a thin delegate containing a label. FormTextDelegate
has text and a grayed out description.
We add some dummy text for the hypothetical theme detection. If we wanted to have actual color scheme detection, in the future it could be done similarly to Neochat (code here), making use of a C++ model with KColorSchemeManager.
In the Online Accounts section, we see an additional property, leading
. We can add an Item to it so that it appears before the text. Its opposite property, trailing
, would be able to show an Item after the text, but we won't use it in our program.
We use a Kirigami.Icon here for simplicity, but this could also be implemented using a Kirigami.Avatar that grabs the information from a model, as is done in Neochat here.
It should end up looking like this:
FormButtonDelegate
The FormButtonDelegate is visually similar to a FormTextDelegate, but it is clickable and shows an arrow pointing to the right. We used it in the Kirigami Addons introduction before.
While the FormTextDelegate had the leading
and trailing
properties to show an item before and after the main content, the FormButtonDelegate only has the leading
property, because the right side is occupied by the arrow.
We use its icon.name
property to set a plus (+) icon to appear after the space where the leading
would appear, and before the main content. This is a common pattern to indicate your button will add something to a list.
Since this example is for simple illustrative purposes, we don't delve deep into what would be done once the button is clicked: it just prints "Clicked!" to the terminal. We could make a new page for account creation that adds another user to a model, then push the page into view, similarly to what we did in main.qml
.
FormRadioDelegate, FormCheckDelegate and FormSwitchDelegate
The RadioButton, CheckBox and Switch are very commonly used components in any user interface. Kirigami Addons provides them as FormRadioDelegate, FormCheckDelegate and FormSwitchDelegate.
Their only main properties are text
and description
. They are different in usage because they all inherit AbstractButton, and so you are expected to use its signals and handlers: checked and onChecked, toggled and onToggled, clicked and onClicked.
We want to create some autosave functionality in our application, and we want to only show its settings if the user has enabled this functionality. Create a new section using a FormCard and a FormHeader, then add a FormSwitchDelegate and a FormRadioDelegate.
We bind the visibility of each radio button to a switch, so they only appear when the switch is enabled.
Best Practices
To test our checkbox, we can add a new FormCheckDelegate to our General section.
Here we use the onToggled
signal handler to show some dummy text to simulate a tray icon appearing in the system. If you really wanted to, you could easily implement a tray icon using SystemTrayIcon.
So far our application should look like this:
FormComboBoxDelegate
The common ComboBox component can be created using a FormComboBoxDelegate.
This combobox has several useful properties we can make use of: editable
, displayText
and displayMode
.
Setting editable: true
allows the user to edit the text of the combobox, which is useful in case adding new combobox options is needed:
Whenever you need to show additional text before each option, you can use something like displayText: "Profile: " + currentText
:
And the most interesting one, which we will be using in our example, is displayMode
. It can have three options:
FormComboBoxDelegate.ComboBox: the standard small box showing a list of options.
FormComboBoxDelegate.Dialog: a dialog showing a list of options in the middle of the window, like a Kirigami.OverlaySheet.
FormComboBoxDelegate.Page: a new page containing a list of options shown in a separate window.
Add the following between the "Current Color Scheme" and "Show Tray Icon" delegates in your "General" form card.
With the checkbox, our Settings page should look like this:
FormDelegateSeparator
Our Settings page is taking shape, but each section is starting to get long. We can add a few FormDelegateSeparators to make our page tidier:
Ah ah ah
This file is not available.
Generally, you may use separators whenever you see major distinctions between components, although the choice of where to place them is ultimately yours. For example, in the General section, the checkbox differs from its previous components as it doesn't start with text; in the Autosave section, the separator groups the radio buttons together; and in the Accounts section, adding a separator between the last account and the button provides some additional focus to the button.
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.
Notice how the separator above the tray icon setting does not appear while it is hovered.
Last updated