التخطيطات، وعروض القوائم، والبطاقات
تخطيط المحتوى الخاص بك
الآن بعد أن فهمنا كيفية عمل الصفحات، حان الوقت لإضافة أشياء إليها. سنستعرض عددًا من مكونات وعناصر التخطيط المهمة التي ستكون مفيدة عند تصميم تطبيقنا.
بنهاية هذا القسم، سيكون لديك تطبيق ذو مظهر أنيق.
قوائم العرض
إن استخدمت يومًا ديسكفر أو نيو تشات أو إعدادات نظام بلازما، فستكون قد صادفت قائمة عرض. ببساطة، تتيح لك عرض البيانات في قائمة.
pageStack.initialPage: Kirigami.ScrollablePage {
// ...
Kirigami.CardsListView {
id: cardsView
model: kountdownModel
delegate: kountdownDelegate
}
}يبدو هذا غامضًا، لكن لا تقلق. لنبدأ من البداية.
نُضِف هذا المكون داخل صفحة قابلة للتمرير من كيريغامي من الدرس السابق.
نستخدم قائمة عرض بطاقات كيريغامي، وهي قائمة عرض تتيح لنا عرض البطاقات بسهولة في قائمة. لكن قوائم العرض صُممت لعرض بيانات مأخوذة من نموذج - لتعبئة نفسها آليًا من مجموعة بيانات نشير إليها. وهنا تأتي خاصية النموذج: في هذا المثال، تشير إلى kountdownModel.
النموذج
Kirigami.ApplicationWindow {
// ...
ListModel {
id: kountdownModel
// كل عنصر قائمة هو عنصر في القائمة، يحوي معلومات
ListElement {
name: "Dog birthday!!"
description: "Big doggo birthday blowout."
date: 100
}
}
// ...
}نُضِف kountdownModel داخل نافذة تطبيق كيريغامي من الدرس السابق.
يُعرّف النموذج طريقة بنية إدخال البيانات. سيتكون kountdownModel من عنصر واحد فقط حاليًا. بالنظر إلى عنصر القائمة أعلاه، نرى كيف بُنيت بيانات kountdownModel: يحوي اسمًا ووصفًا وتاريخًا. هذا ليس ثابتًا، وقد يكون لديك أنواع مختلفة من البيانات في نموذجك. الأولان مجرد سلاسل نصية، والثالث رقم نستخدمه كعنصر نائب.
ملاحظة
بما أن كيو إم إل مبني على جافا سكريبت، تتوفر العديد من ميزات هذه اللغة للاستخدام في ملفات كيو إم إل. لكن، يجب أن تُسبق متغيرات كيو إم إل بـproperty، إلا إذا كانت داخل كتلة كود جافا سكريبت. يمكنك قراءة المزيد عنها في هذه الصفحة.النماذج مفيدة أيضًا في كيفية تعديلها باستخدام عدة دوال. بعض الدوال المهمة هي:
- ListModel.append(yourobject: jsobject) يُضيف كائن جافا سكريبت
yourobjectإلى نموذج القائمة ويضعه بعد آخر عنصر في النموذج. ليحدث هذا بشكل صحيح، يجب توفير كائن جافا سكريبت بالخصائص الصحيحة وأنواع البيانات المقابلة. - ListModel.get(index: int) يُرجع كائن جافا سكريبت في موقع الفهرس الذي توفره.
- ListModel.remove(index: int, count: int) يُزيل كائن جافا سكريبت في موقع
indexالمقدم، وعددًا بعده بقدر ما تضعه فيcount(1 يشمل فقط كائن جافا سكريبت في الفهرس المقدم) - ListModel.set(index: int, yourobject: jsobject) يُغير العنصر في موقع
indexالمقدم بالقيم المقدمة فيyourobject. نفس قواعدappend().
المفوّضون
بينما يحوي kountdownModel البيانات التي ستُعرض، سيتولى kountdownDelegate كيفية عرض البيانات في قائمة العرض. لذلك نستخدم قائمة عرض بطاقات كيريغامي المصممة لعرض مفوّضين من نوع بطاقة، وسيُمثل هؤلاء المفوّضون بصريًا عبر بطاقة مجردة من كيريغامي.
يتلقى المفوّضون آليًا خصائص مثيلات عنصر القائمة التي حددناها في نموذجنا. لذلك يمكننا الإشارة إلى خصائص name و description و date كما لو كانت متغيرات تقليدية داخل مفوّضنا.
بناء بطاقة المفوّض
يمكن إضافة المكون الذي سيمثل مفوّضنا داخل نافذة تطبيق كيريغامي. سنتحقق بعد ذلك مما يفعله كل جزء من مكون المفوّض.
Kirigami.ApplicationWindow {
// ...
Component {
id: kountdownDelegate
Kirigami.AbstractCard {
contentItem: Item {
// يُعرّف العرض/الارتفاع الضمني العرض/الارتفاع الطبيعي لعنصر إذا لم يُحدد عرض أو
// ارتفاع. يُعرّف الإعداد أدناه الحجم المفضل للمكون بناءً على محتواه
implicitWidth: delegateLayout.implicitWidth
implicitHeight: delegateLayout.implicitHeight
GridLayout {
id: delegateLayout
anchors {
left: parent.left
top: parent.top
right: parent.right
}
rowSpacing: Kirigami.Units.largeSpacing
columnSpacing: Kirigami.Units.largeSpacing
columns: root.wideScreen ? 4 : 2
Kirigami.Heading {
level: 1
text: date
}
ColumnLayout {
Kirigami.Heading {
Layout.fillWidth: true
level: 2
text: name
}
Kirigami.Separator {
Layout.fillWidth: true
visible: description.length > 0
}
Controls.Label {
Layout.fillWidth: true
wrapMode: Text.WordWrap
text: description
visible: description.length > 0
}
}
Controls.Button {
Layout.alignment: Qt.AlignRight
Layout.columnSpan: 2
text: i18n("Edit")
// عند النقر: سيُفعل... قريبًا!
}
}
}
}
}
// ...
}العرض الضمني والارتفاع الضمني
الجزء الأول الذي سننظر إليه هو كيفية إدارة عرض وارتفاع مكوننا:
Kirigami.AbstractCard {
contentItem: Item {
implicitWidth: delegateLayout.implicitWidth
implicitHeight: delegateLayout.implicitHeight
GridLayout {
id: delegateLayout
// ...
}
}
}بالنظر إلى بطاقتنا المجردة من كيريغامي، أول الخصائص التي نضبطها هي العرض الضمني و الارتفاع الضمني. ضبطناها على delegateLayout.implicitWidth و delegateLayout.implicitHeight، أي العرض الضمني و الارتفاع الضمني لعنصر التخطيط الشبكي.
العروض والارتفاعات الضمنية هي خصائص متاحة في أي عنصر تعمل كتلميحات وتُضبط كإعداد مبدئي، أو كخيار احتياطي، إذا لم يُضبط عرض أو ارتفاع صريح لهذه المكونات. هذه القيم مبدئيًا 0x0، لذا من المهم جدًا تعريفها في مكونات العنصر الخام كما فعلنا أعلاه.
هنا ضبطنا implicitWidth و implicitHeight لـ بطاقتنا المجردة من كيريغامي على تلك الخاصة بـ التخطيط الشبكي أدناه لضمان عدم تجاوزها للبطاقة. بهذه الطريقة، تأخذ البطاقة المساحة اللازمة لمحتوياتها.
التخطيطات
التخطيط الشبكي داخل مكون العنصر الذي قدمناه لخاصية عنصر المحتوى. هذا هو العنصر الذي يحوي ما سيُعرض في بطاقتك.
نحتاج أيضًا لاختيار تخطيط لمكوناتنا حتى لا تتراكم فوق بعضها. هناك ثلاثة أنواع رئيسية يمكن الاختيار من بينها:
- ColumnLayout يُرتّب مكوّناتك عموديًا، في عمود واحد
- RowLayout يُرتّب مكوّناتك أفقيًا، في صف واحد
- GridLayout يُرتّب مكوّناتك في شبكة بتوليفة من اختيارك
مع ColumnLayout وRowLayout، كل ما علينا فعله هو كتابة مكوّناتنا داخل مكوّن التخطيط. كما ترى، اخترنا GridLayout، الذي يتطلب جهدًا يدويًا أكثر قليلًا.
GridLayout {
id: delegateLayout
anchors {
left: parent.left
top: parent.top
right: parent.right
}
rowSpacing: Kirigami.Units.largeSpacing
columnSpacing: Kirigami.Units.largeSpacing
columns: root.wideScreen ? 4 : 2
// ...
}أول ما تراه هو anchors لدينا. نظام التثبيت في QtQuick يُوفّر طريقة مفيدة لضمان وضع مكوّناتك في أجزاء معيّنة من المكوّن الأب. ثبّتنا GridLayout إلى اليسار والأعلى واليمين من البطاقة الأب، مما يضمن امتداد محتوانا عبر البطاقة بأكملها.
بعد ذلك نحدد التباعد بين الصفوف والأعمدة داخل شبكتنا، حتى لا تتزاحم مكوّناتنا. يُوفّر كيريجامي عددًا من الوحدات المحددة مسبقًا المفيدة لاستخدامها لهذا الغرض:
| وحدة كيريجامي | بكسل |
|---|---|
| smallSpacing | 4px |
| largeSpacing | 8px |
| gridUnit | 18px |
ملاحظة
مجموعة التصميم البصري لكيدي (VDG) لديها مزيد من المعلومات حول الوحدات المختلفة المُعرّفة داخل بلازما وكيريجامي في دليل الواجهة البشرية.كما قد تتذكر، root هو مُعرّف Kirigami.ApplicationWindow خاصتنا. يُوفّر الخاصية wideScreen، المُستخدمة لتحديد ما إذا كانت شاشة الجهاز الحالي عريضة (أي شاشة حاسوب أو هاتف في الوضع الأفقي). نستخدم شرطًا ثلاثيًا هنا لتغيير عدد الأعمدة في شبكتنا اعتمادًا على الشاشة التي نستخدمها: إذا كانت عريضة، ستحتوي الشبكة على 4 أعمدة، وإلا فستحتوي على 2.
المكوّنات الداخلية
قد نكتفي بإنشاء ثلاث وسوم داخل مكوّن المفوّض وننتهي، لكن ذلك لن يبدو جميلًا بشكل خاص. سنستفيد من بعض المكوّنات الأكثر ملاءمة:
GridLayout {
// ...
Kirigami.Heading {
Layout.fillHeight: true
level: 1
text: date
}
ColumnLayout {
Kirigami.Heading {
Layout.fillWidth: true
level: 2
text: name
}
Kirigami.Separator {
Layout.fillWidth: true
visible: description.length > 0
}
Controls.Label {
Layout.fillWidth: true
wrapMode: Text.WordWrap
text: description
visible: description.length > 0
}
}
Controls.Button {
Layout.alignment: Qt.AlignRight
Layout.columnSpan: 2
text: i18n("Edit")
}
}
كيف تبدو البطاقة المخصصة
- يسارًا، Kirigami.Heading: يستخدم
dateالخاص بـListElementكعنوان من المستوى 1. - وسطًا، ColumnLayout: يحتوي على Kirigami.Heading يعرض اسم المهمة؛ وKirigami.Separator، الذي يُوفّر الخط الأفقي؛ وControls.Label، الذي يعرض وصفًا اختياريًا للمهمة. المكوّنان الأخيران لهما خاصية visible، التي تتحقق مما إذا كان الوصف فارغًا أم لا وتعرض المكوّنين اعتمادًا على نتيجة
description.length > 0. - يمينًا، Controls.Button: زر سيفعل شيئًا... قريبًا!
تطبيقنا حتى الآن
Main.qml:
| |

إذن هذه هي بطاقتنا الأساسية!
بهذه الخطوات، وضعنا الآن الأساس لجميع الوظائف التي سنضيفها إلى تطبيقنا.