Skip to main content
تخط المحتوى

مفوضو النموذج في صفحات الإعدادات الخاصة بك

أنشئ صفحات إعدادات مخصصة أنيقة.

ملحقات كيريغامي هي مجموعة إضافية من المكونات البصرية التي تعمل بشكل جيد على الجوال والحاسوب المكتبي ومضمونة أن تكون عبر المنصات. تستخدم كيريغامي في الخلفية لإنشاء مكوناتها.

تعلمت كيفية إضافة صفحات حول وحول كيدي إلى تطبيقك. الآن ستتمكن من استخدام نفس مكوناتها الداخلية لإنشاء صفحات الإعدادات الخاصة بك.

ينبغي أن يبدو هيكل المشروع هكذا:

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

التغييرات المطلوبة

غيّر Main.qml لتضمين صفحة الإعدادات الجديدة:

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.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 تريد إنشاءه، يمكنك إنشاء FormHeader قبله مباشرة. يستخدم الرأس نصًا عريضًا ويظهر فوق بطاقة النموذج مباشرة.

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، ستكون قادرة على إظهار Item بعد النص، لكننا لن نستخدمها في برنامجنا.

نستخدم Kirigami.Icon هنا للبساطة، لكن يمكن أيضًا تنفيذ هذا باستخدام Avatar من إضافات كيريغامي الذي يجلب المعلومات من نموذج، كما فُعل في Neochat.

ينبغي أن يبدو شكله النهائي هكذا:

مفوّض زر النموذج

يشبه FormButtonDelegate بصريًا FormTextDelegate، لكنه قابل للنقر ويظهر سهمًا يشير إلى اليمين. استخدمناه سابقًا في مقدمة إضافات كيريغامي.

بينما كان لدى 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) هي مكونات شائعة الاستخدام جدًا في أي واجهة مستخدم. توفرها إضافات كيريغامي كـ FormRadioDelegate و FormCheckDelegate و FormSwitchDelegate.

خصائصها الرئيسية الوحيدة هي text و description. وهي مختلفة في الاستخدام لأنها جميعًا ترث AbstractButton، ولذا يُتوقع منك استخدام إشاراتها ومعالجاتها: checked و onChecked، toggled و onToggled، clicked و onClicked.

نريد إنشاء وظيفة حفظ آلي في تطبيقنا، ونريد إظهار إعداداتها فقط إذا فعّل المستخدم هذه الوظيفة. أنشئ قسمًا جديدًا باستخدام FormCard و FormHeader، ثم أضف FormSwitchDelegate و 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
    }
}

نربط رؤية كل زر اختيار بمفتاح، فتظهر فقط عندما يكون المفتاح مفعّلاً.

لاختبار خانة الاختيار لدينا، يمكننا إضافة 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 لعرض نص وهمي لمحاكاة ظهور أيقونة علبة النظام. إذا أردت حقًا، يمكنك بسهولة تنفيذ أيقونة علبة نظام باستخدام KStatusNotifierItem من كيدي أو SystemTrayIcon من كيوت.

حتى الآن يجب أن يبدو تطبيقنا هكذا:

FormComboBoxDelegate

يمكن إنشاء المكون ComboBox الشائع باستخدام FormComboBoxDelegate.

يحتوي مربع التحرير والسرد هذا على عدة خصائص مفيدة يمكننا استخدامها: editable، و displayText، و 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

صفحة الإعدادات لدينا تأخذ شكلها، لكن كل قسم بدأ يطول. يمكننا إضافة بضع نسخ من FormDelegateSeparator لجعل صفحتنا أكثر ترتيبًا:

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

بشكل عام، يمكنك استخدام الفواصل كلما رأيت تمييزات رئيسية بين المكونات، على الرغم من أن اختيار مكان وضعها يعود لك في النهاية. على سبيل المثال، في القسم العام، تختلف خانة الاختيار عن مكوناتها السابقة لأنها لا تبدأ بنص؛ في قسم الحفظ الآلي، يجمع الفاصل أزرار الاختيار معًا؛ وفي قسم الحسابات، إضافة فاصل بين آخر حساب والزر يوفر تركيزًا إضافيًا على الزر.

خصائص above و below واضحة بذاتها إلى حد ما عندما يتعلق الأمر باستخدامها: تمرر id المكونات أعلى وأسفل الفاصل. عند تعيينها، سيختفي الفاصل بسرعة كلما تم تمييز/تحويم العنصر الأعلى أو الأسفل. وهي مفيدة جدًا، على سبيل المثال، عندما تحتاج إلى توليد مكونات ديناميكيًا ولا يمكنك افتراض أي عنصر سيأتي مباشرة قبل أو بعد الفاصل تلقائيًا. سيكون هذا هو الحال في قسم الحسابات في تطبيقنا بمجرد تنفيذ منطق إضافة حسابات جديدة فعليًا، وفي هذه الحالة يمكننا دائمًا الحصول على آخر عنصر في النموذج للقيام بذلك.

لاحظ كيف لا يظهر الفاصل فوق إعداد أيقونة علبة النظام أثناء تحويمه.