Делегати форми на наших сторінках параметрів
Додатки Kirigami — це додатковий набір візуальних компонентів, які добре працюють на мобільних пристроях і комп'ютерах і гарантовано є багатоплатформовими. З лаштунками вони використовують Kirigami для створення своїх компонентів.
Ви навчилися додавати сторінки About та AboutKDE до вашої програми. Тепер ви зможете використовувати їхні внутрішні компоненти для створення сторінок налаштувань.
Структура проєкту має виглядати так:
addonsexample
├── CMakeLists.txt
├── main.cpp
├── Main.qml
├── MyAboutPage.qml
└── SettingsPage.qml
Потрібні зміни
Внесемо зміни до Main.qml
так, щоб включити до нього нашу нову сторінку Settings:
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)
}
}
}
}
}
Тепер ми можемо розпочати перевірку компонентів, які використовуються для створення сторінки налаштувань: картки форми та її делегатів.
Делегати форми
FormCard і FormCardPage
FormCard.FormCard є головним компонентом, яким ми користуватимемося для групування його дочірніх компонентів, делегатів.
Раніше ми скористалися карткою форми у вступі до додатків Kirigami. Її основним призначенням є робота контейнером для інших компонентів, маючи колір, який відрізняється від кольору тла, подібно до Kirigami.Card.
Створіть файл SettingsPage.qml
:
import QtQuick
import org.kde.kirigamiaddons.formcard as FormCard
FormCard.FormCardPage {
FormCard.FormCard {
// Ось куди ми впишемо усі делегати!
}
FormCard.FormCard {
// Ось куди ми впишемо усі делегати!
}
}
Оскільки ми створюємо окремий файл QML для нашої сторінки налаштувань і оскільки нам потрібно підготуватися до можливого гортання нашої сторінки, ми використовуємо FormCard.FormCardPage
, який успадковує Kirigami.ScrollablePage.
Приємна особливість сторінки картки форми полягає у тому, що вона має внутрішній макет, тому додатковий ColumnLayout не потрібен, і наших делегатів можна додавати безпосередньо до нього.
Зауваження
Можна використовувати делегати FormCard безпосередньо за допомогою Kirigami.ScrollablePage, але у цьому випадку вам доведеться додати ваші власні компонування.FormHeader
Для кожної FormCard, яку ви хочете створити, ви можете створити [FormHeader](https://api.kde.org /frameworks/kirigami-addons/html/classFormHeader.html) безпосередньо перед ним. У заголовку використовується напівжирний текст, який буде показано безпосередньо над карткою форми.
import org.kde.kirigamiaddons.formcard as FormCard
FormCard.FormCardPage {
FormCard.FormHeader {
title: i18n("General")
}
FormCard.FormCard {
// Тут будуть наші делегати…
}
FormCard.FormHeader {
title: i18n("Accounts")
}
FormCard.FormCard {
// Тут будуть наші делегати…
}
}
FormTextDelegate і FormSectionText
Розпочнімо із простого — звичайного тексту.
FormSectionText
просто додає тонкий делегат, що містить мітку. FormTextDelegate
містить текст і показаний сірим опис.
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 ™️")
}
}
}
Ми додаємо деякий фіктивний текст для виявлення гіпотетичної теми. Якби ми хотіли мати фактичне визначення схеми кольорів, у майбутньому це можна було б зробити подібно до Neochat (код тут), використовуючи модель C++ із KColorSchemeManager.
У розділі «Облікові записи в інтернеті» ми бачимо додаткову властивість leading
. Ми можемо додати до нього Item, щоб він з'являвся перед текстом. Його протилежна властивість, trailing
, надає можливість показувати елемент після тексту, але ми не будемо використовувати його у нашій програмі.
Ми використовуємо тут Kirigami.Icon для простоти, але це також можна реалізувати за допомогою Kirigami.Avatar, який збирає інформацію з моделі, як це робиться у Neochat тут.
Врешті, маємо отримати таке:
FormButtonDelegate
FormButtonDelegate візуально схожий на FormTextDelegate, але його можна натиснути, і на ньому показано стрілку, що вказує праворуч. Раніше ми використовували його у вступі до додатків Kirigami.
У той час як FormTextDelegate мав властивості leading
і trailing
для показу елемента до та після основного вмісту, FormButtonDelegate має лише властивість leading
, оскільки права сторона зайнята стрілкою.
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!")
}
}
}
Ми використовуємо його властивість icon.name
, щоб установити піктограму плюса (+), яка з'являється після місця, де з'являтиметься leading
, і перед основним вмістом. Це загальний шаблон, який вказує, що ваша кнопка додасть щось до списку.
Оскільки цей приклад наведено для простої ілюстрації, ми не заглиблюємось у те, що буде зроблено після натискання кнопки: він просто друкує "Clicked!" до терміналу. Ми можемо створити нову сторінку для створення облікового запису, яка додає іншого користувача до моделі, а потім розмістимо сторінку в полі зору, подібно до того, що ми зробили в Main.qml
.
FormRadioDelegate, FormCheckDelegate і FormSwitchDelegate
RadioButton, CheckBox і Switch є дуже поширеними компонентами для будь-якого інтерфейсу користувача. Додатки Kirigami надають їх як FormRadioDelegate, FormCheckDelegate і FormSwitchDelegate.
Їх єдиними основними властивостями є text
і description
. Вони відрізняються у використанні, тому що всі вони успадковують AbstractButton, і тому ви повинні використовувати його сигнали та обробники: checked і onChecked, toggled і onToggled, clicked і onClicked.
Ми хочемо створити деякі функції автозбереження у нашій програмі, і ми хочемо показувати її налаштування, лише якщо користувач увімкнув цю функцію. Створіть новий розділ за допомогою FormCard і [FormHeader](https://api.kde.org/frameworks/ kirigami-addons/html/classFormHeader.html), потім додайте FormSwitchDelegate і [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
}
}
Ми пов'яжемо видимість кожного пункту варіанта із перемикачем, тому їх буде показано, лише якщо увімкнено перемикач.
Найкращі підходи
Натисніть тут, щоб дізнатися більше
Якщо ви маєте досвід програмування в імперативних мовах, таких як C++, у вас може виникнути спокуса встановити властивість checked
перемикача, щоб змінити видимість пунктів варіантів на true
за допомогою призначення JavaScript, наприклад:
checked: {
radio1.visible = true;
radio2.visible = true;
radio3.visible = true;
}
Це не дуже ефективно для декларативної мови QML та її сигналів і слотів. Намагайтеся якомога більше використовувати прив'язки QML, як у випадку visible: autosave.checked
замість виразів JavaScript.
Див. цю сторінку, щоб дізнатися більше.
Щоб перевірити наш пункт варіанта, ми можемо додати новий FormCheckDelegate до нашого розділу «Загальне».
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!")
}
}
}
}
Тут ми використовуємо onToggled
обробник сигналів, щоб показати деякий фіктивний текст для імітації піктограми у лотку, що з'являється у системі. Якщо ви справді захочете, ви можете легко додати піктограму у лотку за допомогою SystemTrayIcon.
На цьому кроці вікно нашої програми має виглядати так:
FormComboBoxDelegate
Типовий компонент ComboBox можна створити за допомогою FormComboBoxDelegate.
Цей спадний список має декілька корисних властивостей, якими ми можемо скористатися: editable
, displayText
and displayMode
.
Налаштування editable: true
надає змогу користувачеві редагувати текст спадного списку, що корисно, якщо потрібно додати нові пункти до спадного списку:
Щоразу, коли вам потрібно показати додатковий текст перед кожним пунктом, ви можете використати щось подібне до displayText: "Profile: " + currentText
:
І найцікавішим, який ми будемо використовувати в нашому прикладі, є displayMode
. Він може мати три варіанти:
- FormComboBoxDelegate.ComboBox: стандартна мала панель зі списком пунктів.
- FormComboBoxDelegate.Dialog: діалогове вікно, у якому буде показано список пунктів посередині вікна, подібне до Kirigami.OverlaySheet.
- FormComboBoxDelegate.Page: нова сторінка, що містить список пунктів, які показано в окремому вікні.
Додайте таке між делегатами "Current Color Scheme" і "Show Tray Icon" у картці форми "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"]
}
З пунктом для позначки наша сторінка «Параметри» має виглядати так:
FormDelegateSeparator
Наша сторінка налаштувань набуває форми, але її розділи стають надто довгими. Ми можемо додати кілька FormDelegateSeparators, щоб зробити нашу сторінку більш охайною:
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!")
}
}
}
Як правило, ви можете використовувати роздільники щоразу, коли бачите великі відмінності між компонентами, хоча вибір місця їх розміщення залишається за вами. Наприклад, у розділі «Загальні» пункт варіанта відрізняється від попередніх компонентів тим, що він не починається з тексту; у розділі автозбереження роздільник об'єднує перемикачі; а в розділі «Облікові записи» додавання роздільника між останнім обліковим записом і кнопкою забезпечує додатковий акцент на кнопці.
Властивості above
і below
досить зрозумілі, коли йдеться про їхнє використання: ви передаєте id
компонентів над і під роздільником. Коли їх установлено, роздільник швидко зникатиме, при підсвічуванні або наведенні вказівника миші на пункт вище або нижче. Вони найбільш корисні, наприклад, коли вам потрібно генерувати компоненти динамічно, а ви не можете автоматично спрогнозувати, який елемент буде безпосередньо перед роздільником або після нього. Так було б у розділі «Облікові записи» нашої програми, де було реалізовано логіку додавання нових облікових записів, коли ми завжди могли б отримати останній елемент у моделі, щоб зробити це.
Зверніть увагу на те, що роздільник над налаштуванням піктограми у лотку не з'являється, якщо на нього навести вказівник.