<hr>
<h1 dir=“rtl” lang=“ar” align=“right”>الشروع في برمجة َQML:</h1>
<hr>

<p dir=“rtl” lang=“ar” align=“right”>
مرحبا بكم في عالم QML ، لغة واجهة المستخدم التعريفي. في هذا دليل الشروع في العمل ، فإننا سنضع محرر نص بسيط التطبيق باستخدام QML. بعد قراءة هذا الدليل ، يجب أن تكون على استعداد لتطوير التطبيقات الخاصة بك باستخدام QML وكيو تي سي + +.
</p>

<hr>
<h1 dir=“rtl” lang=“ar” align=“right”> QML لبناء واجهات المستخدم </h1>
<hr>
<p dir=“rtl” lang=“ar” align=“right”>
التطبيق الذي نقوم ببناءه هو محرر نصوص بسيطة من شأنها أن تحميل وحفظها وأداء بعض التلاعب بالنص. هذا الدليل سوف يتكون من جزأين. وسيكون الجزء الأول يشمل تصميم تخطيط تطبيق والسلوكيات باستخدام لغة التعريفي في QML. بالنسبة للجزء الثاني ، ستنفذ تحميل الملف حفظ باستخدام كيو تي سي + +. باستخدام Qt’s Meta-Object System ، يمكننا استخدام وظائف سي + + كخصائص تستطيع عناصر QML استخدامها. استخدام QML وكيو تي سي + + ، يمكننا فصل بكفاءة منطق الواجهة عن منطق التطبيق.
</p>

no

<p dir=“rtl” lang=“ar” align=“right”> لتشغيل الشيفرة/البرنامج المثال على ال QML ، نادرا وفر أداة qmlviewer المضمنة مع ملف QML كوسيطة. جزء سي + + من هذا البرنامج التعليمي ويفترض أن القارئ يمتلك المعرفة الأساسية للإجراءات تجميع كيو تي. </p>

<p dir=“rtl” lang=“ar” align=“right”>
البرنامج التعليمي فصول :
1.تعريف زر وقائمة.
2.تنفيذ شريط قائمة
3.بناء محرر النص
4.تنسيق نص محرر
5.تسويع ال QML باستخدام كيو تي سي + +
</p>

<hr>
<h1 dir=“rtl” lang=“ar” align=“right”> تحديد زر والقائمة على </h1>
<hr>

<hr>
<h1 dir=“rtl” lang=“ar” align=“right”> مكون أساسي — زر </h1>
<hr>

<p dir=“rtl” lang=“ar” align=“right”>
نبدأ جهودنا لتحرير النص من خلال بناء زر واحدة. وظيفيا ، زر الماوس لديه منطقة حساسة وتسمية. أزرار تنفيذ إجراءات عندما يضغط المستخدم على زر. في QML ، العنصر الأساسي البصري هو عنصر المستطيل. العنصر المستطيل له خصائص للتحكم في مظهر العنصر ومكانه.
</p>

  1.   import Qt 4.7
  2.  
  3.   Rectangle{
  4.     id:simplebutton
  5.          
  6.     color: "grey"
  7.     width: 400; height: 400
  8.  
  9.     Text {
  10.         id: buttonLabel
  11.         text: "button label"
  12.         anchors.centerIn:parent
  13.     }
  14.   }

<p dir=“rtl” lang=“ar” align=“right”>
أولا ، import QtQuick 1.0 يسمح لأداة qmlviewer لاستيراد عناصر QML التي سوف نستخدمها في وقت لاحق. يجب أن يظهر هذا الخط في كل ملف QML. لاحظ ان فيرجن/رقم وحدات Qt مضمنة في جملة الاستيراد .
</p>

<p dir=“rtl” lang=“ar” align=“right”>
هذا المستطيل بسيط لديه معرف فريد ، simplebutton ، التي ترتبط مع معرف الخاصية. لا بد لخصائص عنصر المستطيل ان ترتبط بقيم من خلال سرد الخاصية ، متبوعا بنقطتين ، ثم القيمة. في عينة البرنامج، اللون الرمادي تم ربطه مع خاصية لون المستطيل، وبالمثل ، فإننا قد ربطنا العرض والارتفاع للمستطيل.
</P>

<p dir=“rtl” lang=“ar” align=“right”>
عنصر النص هو حقل نص غير قابل للتحرير. نحن نسمي هذا عنصر النص هذا ب buttonLabel. لضبط محتوى سلسلة الاحرف من حقل النص ، نقوم بربط قيمة إلى خاصية النص. والتسمية محتواه داخل المستطيل ومن أجل مركزته في الوسط نقوم بتعيين المراسي “anchors” ل عنصر النص إلى في أصله ، وهو ما يسمى simplebutton. المراسي قد تربط الى مراسي أخرى ، مما يسمح للتخطيط ان يصبح بسيطا.

</P>
<p dir=“rtl” lang=“ar” align=“right”>
وسنعمل على حفظ هذا الرمز باسم SimpleButton.qml. وتشغيل qmlviewer مع الملف كوسيطة لعرض المستطيل الرمادي مع تسمية ل النص.
</P>

no

<p dir=“rtl” lang=“ar” align=“right”>
لتنفيذ وظائف النقر على زر ، يمكننا استخدام نظام معالجة الحدث الموجود QML. معالجة الحدث في QML مشابهة جدا لإشارة َQt وفتحة الآلية. عندما تنبعث الاشارات فإن فتحة متصلة أو دالة معينة تنفذ آليا.
</P>

  1. Rectangle{
  2.      id:simplebutton
  3.      ...
  4.  
  5.      MouseArea{
  6.          id: buttonMouseArea
  7.  
  8.          anchors.fill: parent //anchor all sides of the mouse area to the rectangle's anchors
  9.                  //onClicked handles valid mouse button clicks
  10.          onClicked: console.log(buttonLabel.text + " clicked" )
  11.      }
  12. }

<p dir=“rtl” lang=“ar” align=“right”>
نحن تشمل عنصرا MouseArea في simplebutton الموجود هنا. عناصر MouseArea تصف المنطقة التفاعلية حيث يتم الكشف عن حركات الماوس. للزر الموجود لدينا، ونحن نربط/ MouseArea كله إلى الأصل ، وهو simplebutton. بناء الجملة anchors.fill هي طريقة معينة للوصول إلى خاصية معينة تسمى ملء “fill” داخل مجموعة من الخصائص ودعا المراسي “anchors”. QML يستخدم مرساة تخطيطات “anchor based layouts” إلى حيث يمكن ربط العناصر إلى عنصر آخر ، لإنشاء تخطيطات قوية.
</P>

<p dir=“rtl” lang=“ar” align=“right”>
وMouseArea لديها عدة معالجات اشارات التي تنادى/تنفذ خلال حركات الماوس داخل حدود MouseArea المحددة. واحد من هذه الحركات هو onClicked وينفذ كلما تم النقر على زر الماوس بشكل مقبول ، النقرة اليسرى على الماوس وضعت لتكون النقرة الافتراضية. يمكننا ربط الإجراءات/وظائف إلى معالج onClicked. في مثالنا ، ()console.log ينتج/يخرج النص كلما تم النقر على منطقة الماوس. والدالة () console.logهو أداة مفيدة لأغراض التصحيح وإخراج للنص.
</P>

<p dir=“rtl” lang=“ar” align=“right”>
الكود الموجود في SimpleButton.qml هو كافي لعرض زر على الشاشة وإخراج نص كلما يتم النقر فوقه مع ماوس.
</p>

  1. Rectangle {
  2.      id:Button
  3.      ...
  4.  
  5.      property color buttonColor: "lightblue"
  6.      property color onHoverColor: "gold"
  7.      property color borderColor: "white"
  8.  
  9.      signal buttonClick()
  10.      onButtonClick: {
  11.          console.log(buttonLabel.text + " clicked" )
  12.      }
  13.  
  14.      MouseArea{
  15.          onClicked: buttonClick()
  16.          hoverEnabled: true
  17.          onEntered: parent.border.color = onHoverColor
  18.          onExited:  parent.border.color = borderColor
  19.      }
  20.  
  21.      //determines the color of the button by using the conditional operator
  22.      color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor
  23. }

<p dir=“rtl” lang=“ar” align=“right”>
زر التشغيل الكامل موجود Button.qml. مقتطفات البرمجية في هذه المقالة قد تم حذف بعض الكود منها، مثلت عملية هذا الحف بواسطة اشكال إما لأنها قدمت في وقت سابق من الأقسام السابقة أو غير ذات صلة لمناقشة القانون الحالي.
</p>

<p dir=“rtl” lang=“ar” align=“right”>
يتم تعريف الخصائص المخصصة باستخدام جملة “اسم نوع الخاصية”. في الكود ، الخاصية buttonColor ، من نوع لون “color”، تم تعريفها ان ربطها الى قيمة “lightblue”. يستخدم buttonColor في وقت لاحق في عملية مشروطة لتحديد لون الأزرار والتعبئة. علما بأن تعيين قيمة الخاصية ممكن باستخدام يساوي = اشارة المساواة ، بالإضافة إلى ربط قيمة باستخدام “:” الخصائص المخصصة السماح للعناصر الداخلية لتكون يمكن الوصول إليها/معالجتها من خارج نطاق مستطيل. وهناك أنواع QML الأساسية مثل “int” أو العدد الطبيعي ، سلسلة “string” ، الحقيقي”real” ، فضلا عن نوع يسمى متغير “variant”.
</p>

<p dir=“rtl” lang=“ar” align=“right”>
بواسطة ربط معالجات إشارة onEntered وonExited للألوان ، فإن حدود الزر سوف تتحول إلى الأصفر بدوره عند مرور الماوس فوق الزر ويعود اللون عند إنهاء الفأر منطقة الماوس.
</p>

<p dir=“rtl” lang=“ar” align=“right”>
()buttonClick تم ألاعلان عنه في Button.qml عن طريق وضع كلمة signal أمام اسم الإشارة. كل الإشارات لديها معالجاتها التي تنشأ وتخلق تلقائيا ،حيث تبدأ اسمائها ب on. ونتيجة لذلك، onButtonClick هو معالج ل buttonClick. يتم تعيين onButtonClick لإجراء لتنفيذ/دالة. في مثالنا –مثال الزر- ، فإن معالج الماوس المسمى ب onClicked سيستدعى/سينفذ onButtonClick ، الذي يعرض النص. وتمكن onButtonClick الكائنات خارج المنطقة للوصول إلى الزر الماوس بسهولة. على سبيل المثال ، العناصر قد يكون لديها أكثر من MouseArea واحدة تم الاعلان عنها وإشارة buttonClick يمكن أن تميز بين عدة معالجات لإشارة MouseArea بشكل أفضل.
</p>
<p dir=“rtl” lang=“ar” align=“right”>
لدينا الآن المعرفة الأساسية لتنفيذ البنود الواردة في QML التي يمكن التعامل مع حركات الماوس الأساسية. ولقد خلقنا تسمية النص داخل مستطيل ، وغيرنا خصائصه ، وبرمجنا/كتبنا الكود للسلوكيات التي تستجيب لحركات الماوس. إن فكرة انشاء عناصر داخل عناصر هي فكرة مكررة داخل تطبيق محرر النصوص.</P>
<p dir=“rtl” lang=“ar” align=“right”>
هذا الزر غير مفيدة ما لم يستخدم كمكون لأداء إجراء/دالة. في الجزء التالي، سنقوم قريبا إنشاء قائمة تحتوي على العديد من هذه الأزرار.
</p>

no

<h1> إنشاء صفحة القائمة</h1>

<p dir=“rtl” lang=“ar” align=“right”>
حتى هذه المرحلة ، غطينا كيفية إنشاء عناصر وتعيين السلوكيات داخل ملف QML واحد. في هذا القسم ، سوف تغطي كيفية استيراد عناصر QML وكيفية إعادة استخدام بعض المكونات التي أنشئت لبناء المكونات الأخرى.
<p>

<p dir=“rtl” lang=“ar” align=“right”>
القوائم تعرض محتويات قائمة ، كل عنصر/بند لديها القدرة على تنفيذ إجراء. في QML ، يمكننا إنشاء قائمة في عدة طرق. أولا ، سوف نقوم بإنشاء قائمة تحتوي على أزرار التي سوف تؤدي في نهاية المطاف إجراءات مختلفة. رمز القائمة في FileMenu.qml.
</p>

  1.  import Qt 4.7                      \\import the main Qt QML module
  2.  import "folderName"            \\import the contents of the folder
  3.  import "script.js" as Script    \\import a Javascript file and name it as Script

<p dir=“rtl” lang=“ar” align=“right”>
الجملة المبينة أعلاه توضح كيفية استخدام الكلمة “import”. هذا مطلوب لاستخدام ملفات جافا سكريبت ، أو ملفات QML التي لا تقع ضمن نفس المجلد. لأن Button.qml في نفس المجلد ك FileMenu.qml ، نحن لسنا بحاجة لاستيراد”import” ملف Button.qml لاستخدامه. يمكننا خلق عنصر ال “زر” مباشرة باعلان Button{} ، على غرار Rectangle{} الذي يقوم بالاعلان عن المستطيل.
</P>

  1.  In FileMenu.qml:
  2.  
  3.      Row{
  4.          anchors.centerIn: parent
  5.          spacing: parent.width/6
  6.  
  7.          Button{
  8.              id: loadButton
  9.              buttonColor: "lightgrey"
  10.              label: "Load"
  11.          }
  12.          Button{
  13.              buttonColor: "grey"
  14.              id: saveButton
  15.              label: "Save"
  16.          }
  17.          Button{
  18.              id: exitButton
  19.              label: "Exit"
  20.              buttonColor: "darkgrey"
  21.  
  22.              onButtonClick: Qt.quit()
  23.          }
  24.      }

<p dir=“rtl” lang=“ar” align=“right”>
في FileMenu.qml، نعلن عن ثلاثة عناصرمن نوع زر”Button”. يتم الإعلان عنها داخل عنصر الصف “Row” ، والتي من شأنها تحديد مواضع عناصرها الاطفال – أي العناصر الموجودة والمحتواه داخل هذا العنصر- . الإعلان عن زر موجود في Button.qml ، وهو مشابه ل Button.qml الذي كنا قد استخدمناه في المقطع السابق. روابط جديدة للخصائص يمكن الاعلان عنها داخل الازرار التي انشئت حديثا ، وعلى نحو فعال تستنسخ مجموعة الخصائص الموجودة داخل Button.qml. الزر المسمى ب exitButton يستخدم لإنهاء وإغلاق النافذة عندما يتم النقر فوقه. علما بأن معالج اشارة onButtonClick في Button.qmlسوف يستدعى بالاضافة الى onButtonClick في exitButton.
</P>

no

<p dir=“rtl” lang=“ar” align=“right”>
إن إعلان ال صف “Row” تم عمله في مستطيل ، مما خلق وعاء مستطيل لصف الأزرار. هذا المستطيل الاضافي يخلق طريقة غير مباشرة لتنظيم صف من الأزرار داخل القائمة.
</p>
<p dir=“rtl” lang=“ar” align=“right”> كما إعلان قائمة التحرير مشابهة جدا في هذه المرحلة. القائمة لديها أزرار التي يدورها لديها التسميات : نسخ ولصق،وتحديد الكل.
</p>

no

<p dir=“rtl” lang=“ar” align=“right”>
مسلحين بمعرفتنا باستيراد “import”وتخصيص مكونات مصنوعة من قبل ، ونحن الآن قد تجمع بين صفحات القائمة هذه لإنشاء شريط القوائم ، التي تتكون من أزرار لاختيار القائمة ، وننظر في كيفية بناء البيانات باستخدام QML.
</P>

<h1align=“right”> تنفيذ وبرمجة شريط قوائم</h1>
<p dir=“rtl” lang=“ar” align=“right”>
تطبيق محرر النص الذي نقوم ببناءه سوف يحتاج إلى وسيلة لعرض القوائم باستخدام شريط القوائم. شريط القوائم سوف يقوم بتبديل القوائم المختلفة ، ويمكن للمستخدم اختيار القائمة التي لعرض.تبديل القائمة يعني أن القوائم بحاجة الى مزيد من التركين والتنظيم أكثر من مجرد من عرضها في صف واحد. QML تستخدم نماذج وومناظر/واجهات لهيكلة البيانات وعرض البيانات المنظمة.
</P>

<h1 align=“right”>استخدام النماذج البيانات الواجهات</h1>
<p dir=“rtl” lang=“ar” align=“right”>
QML لديه واجهات بيانات مختلفة التي تعرض نماذج بيانات. شريط القائمة لدينا سوف يعرض القوائم في قائمة ، مع مقدمة تعرض صف من أسماء القوائم. وأعلنت قائمة من القوائم داخل VisualItemModel. العنصر VisualItemModel يحتوي على عناصر لديها واجهات”views” مسبقا مثل عناصر ال مستطيل عناصر واجهة المستخدم المستوردة. أنواع نماذج أخرى مثل العنصر ListModel بحاجة الى مندوب لعرض البيانات الخاصة بهم.
</P>
<p dir=“rtl” lang=“ar” align=“right”>
نعلن بندين بصريين في menuListModel ، وFileMenu وEditMenu. نقوم بتخصيص القائمتين ونعرضهم باستخدام ListView. الملف MenuBar.qml يحتوي على إعلانات QML ويتم تعريف قائمة تحرير بسيطة في EditMenu.qml.
</P>

  1.      VisualItemModel{
  2.          id: menuListModel
  3.          FileMenu{
  4.              width: menuListView.width
  5.              height: menuBar.height
  6.              color: fileColor
  7.          }
  8.          EditMenu{
  9.              color: editColor
  10.              width:  menuListView.width
  11.              height: menuBar.height
  12.          }
  13.      }

<p dir=“rtl” lang=“ar” align=“right”>
سيعرض العنصر ListView نموذج وفقا لمندوب” delegate”. يمكن للمندوب ان يعلن عن عناصر نموذج لتعرض في عنصر صف “Row” أو تعرض العناصر في شبكة. menuListModel الموجود لدينا لديه عناصر مرئية ، ولذلك ، نحن لسنا بحاجة الى اعلان مندوب
</P>

  1.      ListView{
  2.          id: menuListView
  3.  
  4.          //Anchors are set to react to window anchors
  5.          anchors.fill:parent
  6.          anchors.bottom: parent.bottom
  7.          width:parent.width
  8.          height: parent.height
  9.  
  10.          //the model contains the data
  11.          model: menuListModel
  12.  
  13.          //control the movement of the menu switching
  14.          snapMode: ListView.SnapOneItem
  15.          orientation: ListView.Horizontal
  16.          boundsBehavior: Flickable.StopAtBounds
  17.          flickDeceleration: 5000
  18.          highlightFollowsCurrentItem: true
  19.          highlightMoveDuration:240
  20.          highlightRangeMode: ListView.StrictlyEnforceRange
  21.      }

<p dir=“rtl” lang=“ar” align=“right”>
بالاضافة، يرث ListView من Flickable ، جاعلا من القائمة تستجيب لعملية سحب الماوس واللفتات الأخرى. الجزء الأخير من الكود أعلاه يضبط خصائص Flickable لخلق الحركة المطلوبة لواجهتنا. على وجه الخصوص ، الخاصية highlightMoveDuration تغير مدة الانتقال لل “flick”. قيمة أعلى ل highlightMoveDuration سوفي تؤدي إلى تبديل ابطأ في القائمة.
</P>
<p dir=“rtl” lang=“ar” align=“right”>
تحافظ ListView على عناصر النموذج من خلال فهرس حيث يمكن معالجة اي عنصر من عناصر هذا النموذج والوصول إليها من خلال هذا الفهرس بشكل مرتب حسب وقت انشاء ذهه العناصر. تغيير ال currentIndex يغير بفعالية يغير العنصر المميز في ListView. رأس شريط القوائم لدينا يمثل هذا التأثير. هناك اثنين من الأزرار في صف واحد ، كلاهما يغير القائمة الحالية عند النقر عليهما. يغير ال fileButton القائمة الحالية إلى قائمة الملف عند النقر عليها ، الفهرس يكون قيمته 0 لأن FileMenu تم إعلان عنه في menuListModel. وبالمثل ، فإن editButton سوف تغير القائمة الحالية لEditMenu عند النقر عليها.
</p>
<p dir=“rtl” lang=“ar” align=“right”>
المستطيل labelList له قيمة “z” وهي ال 1 ، والتي تدل بأنه يتم عرضها امام شريط القائمة، العناصر ذات قيم أعلى من “z” تعرض أمام العناصر ذات قيم أدنى من “z”. القيمة الافتراضية هي ل “z” هي 0.

  1.      Rectangle{
  2.          id: labelList
  3.          ...
  4.          z: 1
  5.          Row{
  6.              anchors.centerIn: parent
  7.              spacing:40
  8.              Button{
  9.                  label: "File"
  10.                  id: fileButton
  11.                  ...
  12.                  onButtonClick: menuListView.currentIndex = 0
  13.              }
  14.              Button{
  15.                  id: editButton
  16.                  label: "Edit"
  17.                  ...
  18.                  onButtonClick:    menuListView.currentIndex = 1
  19.              }
  20.          }
  21.      }

<p dir=“rtl” lang=“ar” align=“right”>
يمكن شريط القوائم الذي انشئناه للوصول إلى القوائم أو من خلال النقر على أسماء القوائم في الأعلى. تبديل شاشات القائمة يبدو بديهيا ومستجيبا.
</p>
no

<p dir=“rtl” lang=“ar” align=“right”>
بناء محرر النص
اعلان ناحية النص
محرر النص لدينا ليس محرر النص اذا لم تحتوي على مساحة نص قابل للتحرير. عنصر ال TextEdit يسمح للإعلان منطقة نص متعدد الخطوط قابلة للتحرير. TextEdit مختلفة عن عنصر Text ، والتي لا تسمح للمستخدم لتحرير النص مباشرة.
</P>

  1.      TextEdit{
  2.          id: textEditor
  3.          anchors.fill:parent
  4.          width:parent.width; height:parent.height
  5.          color:"midnightblue"
  6.          focus: true
  7.  
  8.          wrapMode: TextEdit.Wrap
  9.  
  10.          onCursorRectangleChanged: flickArea.ensureVisible(cursorRectangle)
  11.      }

<p dir=“rtl” lang=“ar” align=“right”>
المحرر لديه مجموعة خاصية لون الخط. منطقة TextEdit مجودة داخل منطقة flickable التي سوف تنتقل بالنص إذا كان المؤشر النص خارج منطقة مرئية. الدالة ()ensureVisible سوف تفحص ما اذا كان مستطيل المؤشر المستطيل خارج حدود واضحة وتحرك ناحية النص وفقا لذلك. QML يستخدم الجافا سكريبت ل كتابة “سكريبتاتها“، وكما ذكر سابقا ، يمكن استيراد ملفات جافا سكريبت واستخدامها ضمن ملف QML.
</p>

  1.      function ensureVisible(r){
  2.          if (contentX >= r.x)
  3.              contentX = r.x;
  4.          else if (contentX+width <= r.x+r.width)
  5.              contentX = r.x+r.width-width;
  6.          if (contentY >= r.y)
  7.              contentY = r.y;
  8.          else if (contentY+height <= r.y+r.height)
  9.              contentY = r.y+r.height-height;
  10.      }

<h1 align=“right”> الجمع بين مكونات لمحرر النص</h1>
<p dir=“rtl” lang=“ar” align=“right”>
ونحن الآن على استعداد لإنشاء تخطيط باستخدام محرر نصنا QML. محرر النصوص من عنصرين ، شريط القوائم وأنشأنا منطقة النص. QML يسمح لنا لإعادة استخدام المكونات ، مما يجعل الكود لدينا أكثر بساطة ، عن طريق استيراد مكوناتها وتخصيصها عند الضرورة. منا محرر النص يقسم النافذة إلى قسمين ؛ ثلث الشاشة قد تم تكريسه لشريط القوائم وثلثي يعرض شاشة منطقة النص. يتم عرض شريط القائمة أمام أية عناصر أخرى.
</P>

  1.      Rectangle{
  2.  
  3.          id: screen
  4.          width: 1000; height: 1000
  5.  
  6.          //the screen is partitioned into the MenuBar and TextArea. 1/3 of the screen is assigned to the MenuBar
  7.          property int partition: height/3
  8.  
  9.          MenuBar{
  10.              id:menuBar
  11.              height: partition
  12.              width:parent.width
  13.              z: 1
  14.          }
  15.  
  16.          TextArea{
  17.              id:textArea
  18.              anchors.bottom:parent.bottom
  19.              y: partition
  20.              color: "white"
  21.              height: partition*2
  22.              width:parent.width
  23.          }
  24.      }

<p dir=“rtl” lang=“ar” align=“right”>
عن طريق استيراد مكونات قابلة للاستخدام ، لدينا كود TextEditor يبدو أبسط من ذلك بكثير. يمكننا تخصيص التطبيق الرئيسي بعد ذلك ، دون القلق حول الخصائص التي حددت السلوكيات سابقا. باستخدام هذا النهج ، يمكن إنشاء تخطيطات التطبيق ومكونات واجهة المستخدم بسهولة.
</p>

no

<h1 align=“right”>تنسيق محرر النص</h1>
<h1 align=“right”>تنفيذ واجهة الدرج</h1>
<p dir=“rtl” lang=“ar” align=“right”>
محرر النص يبدو بسيطا، ونحن بحاجة لتنسيقه. باستخدام QML ، يمكن أن نعلن عمليات الانتقال ووضع حركات لمحرر النص لدينا. شريط القائمة لدينا يحتل ثلث الشاشة وسيكون من الجميل يظهر فقط عندما نريده.
</P>

<p dir=“rtl” lang=“ar” align=“right”>
ويمكننا أن نضيف واجهة الدرج ، التي من شأنها توسيع أو تقليص شريط القائمة عند النقر عليها. في برمجتنا ، لدينا مستطيل رقيق يستجيب لنقرات الماوس. ال drawer“الدرج“، فضلا عن التطبيق ،لديه حالتين: هناك حالة “درج مفتوح” وحالة“درج مغلق”. درج هذا البند هو قطاع من المستطيل مع ارتفاع صغير. هناك عنصر صورة متداخلة يعلن أن هناك ايقون سهم سوف يتمركز داخل درج. الدرج يعين حالة لجميع التطبيق، مع المعرف “screen”، كلما نقر المستخدم على منطقة الماوس.
</P>

  1.      Rectangle{
  2.          id:drawer
  3.          height:15
  4.  
  5.          Image{
  6.              id: arrowIcon
  7.              source: "images/arrow.png"
  8.              anchors.horizontalCenter: parent.horizontalCenter
  9.          }
  10.  
  11.          MouseArea{
  12.              id: drawerMouseArea
  13.              anchors.fill:parent
  14.              onClicked:{
  15.                  if (screen.state == "DRAWER_CLOSED"){
  16.                      screen.state = "DRAWER_OPEN"
  17.                  }
  18.                  else if (screen.state == "DRAWER_OPEN"){
  19.                      screen.state = "DRAWER_CLOSED"
  20.                  }
  21.              }
  22.              ...
  23.          }
  24.      }

<p dir=“rtl” lang=“ar” align=“right”>
والدولة هي مجرد مجموعة من التكوينات واعلنت انها عنصر في الدولة. ويمكن سرد قائمة من الدول ومنضمة إلى الخاصية الدول. في تطبيق لدينا ، وتسمى DRAWER_CLOSED الدولتين وDRAWER_OPEN. يتم تعريف عنصر في تكوينات العناصر PropertyChanges. في الدولة DRAWER_OPEN ، وهناك أربعة بنود من شأنها أن تلقي التغييرات الملكية. وسيكون الهدف الأول ، القوائم ، تغيير الخاصية إلى 0 ذ. وبالمثل ، فإن انخفاض ناحية النص إلى موضع جديد عندما تكون الدولة DRAWER_OPEN. سوف ناحية النص ، درج ، ورمز الساحب تغيرات الملكية لمواجهة الحالة الراهنة.
الاستماع
</P>

  1.      states:[
  2.          State {
  3.              name: "DRAWER_OPEN"
  4.              PropertyChanges { target: menuBar; y: 0}
  5.              PropertyChanges { target: textArea; y: partition + drawer.height}
  6.              PropertyChanges { target: drawer; y: partition}
  7.              PropertyChanges { target: arrowIcon; rotation: 180}
  8.          },
  9.          State {
  10.              name: "DRAWER_CLOSED"
  11.              PropertyChanges { target: menuBar; y:-height; }
  12.              PropertyChanges { target: textArea; y: drawer.height; height: screen.height - drawer.height }
  13.              PropertyChanges { target: drawer; y: 0 }
  14.              PropertyChanges { target: arrowIcon; rotation: 0 }
  15.          }
  16.      ]

<p dir=“rtl” lang=“ar” align=“right”>
تغييرات مفاجئة والدولة واحتياجات سلاسة الانتقال. يتم تعريف انتقالات بين الدول باستخدام العناصر الانتقالية ، والتي يمكن ثم ربط الخاصية التحولات العنصر. جهودنا لتحرير النص والانتقال الدولة كلما التغييرات إما إلى الدولة أو DRAWER_OPEN DRAWER_CLOSED. الأهم من ذلك ، يحتاج الى الانتقال من وإلى الدولة ولكن لدينا التحولات ، يمكننا استخدام بطاقة البرية * رمز للدلالة على أن الانتقال ينطبق على جميع التغييرات الدولة.
</P>
<p dir=“rtl” lang=“ar” align=“right”>
خلال التحولات ، يمكن أن نعلق صور متحركة للتغيرات الملكية. القوائم لدينا موقف من مفاتيح ص : 0 إلى ص : – التقسيم ونحن يمكن أن يديروا هذا التحول باستخدام عنصر NumberAnimation. ونعلن أن خصائص الأهداف ‘سوف تبث لمدة معينة من الزمن ، واستخدام منحنى تخفيف معينة. منحنى تخفيف الضوابط معدلات الرسوم المتحركة والسلوك الاستيفاء خلال التحولات الدولة. منحنى تخفيف اخترنا Easing.OutQuint هو الذي يؤدي إلى إبطاء حركة قرب نهاية للرسوم المتحركة. قراءة المادة Pleae QML الرسوم المتحركة.
</p>

  1.      transitions: [
  2.          Transition {
  3.              to: "*"
  4.              NumberAnimation { target: textArea; properties: "y, height"; duration: 100; easing.type:Easing.OutExpo }
  5.              NumberAnimation { target: menuBar; properties: "y"; duration: 100; easing.type: Easing.OutExpo }
  6.              NumberAnimation { target: drawer; properties: "y"; duration: 100; easing.type: Easing.OutExpo }
  7.          }
  8.      ]

<p dir=“rtl” lang=“ar” align=“right”>
طريقة أخرى لموحية التغييرات الملكية باعلان عنصر سلوك. وتمر بمرحلة انتقالية تعمل فقط خلال التغييرات حالة وسلوك يمكن أن يحدد للرسوم المتحركة لتغيير الملكية العامة. في محرر النص ، السهم لديه NumberAnimation موحية ممتلكاتها التناوب كلما التغييرات الملكية.
</p>

  1.  In TextEditor.qml:
  2.  
  3.      Behavior{
  4.          NumberAnimation{property: "rotation";easing.type: Easing.OutExpo }
  5.      }

بالإضافة إلى ذلك ، يمكننا تعزيز مظاهر مكونات QML لدينا عن طريق إضافة تأثيرات الألوان مثل التدرجات والآثار التعتيم. ولا شك أن إعلان عنصر التدرج تجاوز الخاصية لون العنصر. قد قمت بتعريف اللون في الانحدار باستخدام عنصر GradientStop. يتم وضع التدرج باستخدام مقياس ، بين 0،0 و 1،0.

  1.  In Button.qml:
  2.      ...
  3.  
  4.      color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor
  5.      Behavior on color { ColorAnimation{ duration: 55} }
  6.  
  7.      scale: buttonMouseArea.pressed ? 1.1 : 1.00
  8.      Behavior on scale { NumberAnimation{ duration: 55} }

Oltre a questo, possiamo intervenire sull’aspetto dei nostri componenti QML con l’aggiunta di effetti di colore, come sfumature ed effetti di trasparenza. Dichiarando un elemento Gradient [doc.qt.nokia.com] si sovrascrive la proprietà color dell’elemento. Si può quindi dichiarare il colore della sfumatura utilizzando l’elemento GradientStop [doc.qt.nokia.com]. La sfumatura è valorrizata utilizzando una scala tra 0,0 e 1,0.

  1.  In MenuBar.qml
  2.      gradient: Gradient {
  3.          GradientStop { position: 0.0; color: "#8C8F8C" }
  4.          GradientStop { position: 0.17; color: "#6A6D6A" }
  5.          GradientStop { position: 0.98;color: "#3F3F3F" }
  6.          GradientStop { position: 1.0; color: "#0e1B20" }
  7.      }

Questo gradiente è utilizzato dalla barra dei menu per visualizzare un gradiente che simula la profondità. Il primo colore è utilizzato al valore 0,0 e l’ultimo a 1.0.

Prossimi passi

Abbiamo così finito di costruire l’interfaccia utente di un semplice editor di testo. Andando avanti, completata l’interfaccia utente, siamo in grado di implementare la logica dell’applicazione con Qt e C++. Come abbiamo visto QML funziona bene come strumento di prototipazione, separando efficacemente la logica applicativa dalla progettazione dell’interfaccia utente.

Estendere QML usando Qt C++

Ora che abbiamo il layout del nostro editor di testo, possiamo ora implementare le funzionalità dell’editor in C++. L’utilizzo di QML con C++ permette di realizzare la logica della nostra applicazione utilizzando Qt. Siamo in grado di creare un context QML in una applicazione C++ usando le classi dichiarative di Qt [doc.qt.nokia.com] e visualizzare gli elementi QML tramite una Graphic Scene [doc.qt.nokia.com]. In alternativa, possiamo esportare il nostro codice C++ compilato in un plugin che il programma qmlviewer è in grado di leggere. Per la nostra applicazione, implementeremo le funzioni in C++ per caricare e salvare i file e le esporteremo come plugin. In questo modo, abbiamo solo bisogno di lanciare il file QML direttamente anziché eseguire un file eseguibile.

Esportare classi C++ per QML

Vogliamo implementare le funzioni di caricamento e salvataggio file utilizzando Qt e C++. Le classi e le funzioni C++ possono essere utilizzate in QML previa una loro registrazione. La classe ha inoltre bisogno di essere compilata come un plugin Qt e il file QML avrà bisogno di sapere dove si trova il plugin nel file system.

Per la nostra applicazione, abbiamo bisogno di creare i seguenti oggetti:

  1. una classe Directory che consenta di gestire le operazioni sulle directory (cartelle)
  2. una classe File che sia un QObject, che simuli l’elenco dei file in una directory
  3. una classe plugin che registri la classe nel corretto contesto QML
  4. un file di progetto (project file) Qt per compilare il plugin
  5. in file qmldir per indicare al programma qmlviewer dove trovare il plugin

Costruire un pugin Qt

Per costruire un plugin, è necessario impostare le direttive che seguono in project file Qt. Innanzi tutto vanno specificati i file contenenti i sorgenti e i file di include, nonché i moduli Qt utilizzati. Tutti i file sorgenti C++ e di progetto si trovano nella directory FileDialog.

  1.  In cppPlugins.pro:
  2.  
  3.      TEMPLATE = lib
  4.      CONFIG += qt plugin
  5.      QT += declarative
  6.  
  7.      DESTDIR +=  ../plugins
  8.      OBJECTS_DIR = tmp
  9.      MOC_DIR = tmp
  10.  
  11.      TARGET = FileDialog
  12.  
  13.      HEADERS +=     directory.h \
  14.              file.h \
  15.              dialogPlugin.h
  16.  
  17.      SOURCES +=    directory.cpp \
  18.              file.cpp \
  19.              dialogPlugin.cpp

Nello specifico, compiliamo con il modulo Qt declarative e lo configuriamo come un plugin, che necessita di un modello (template) di tipo lib. Dovremmo poi mettere il plugin compilato nella directory plugins del genitore della directory corrente.

Registrare una classe in QML

  1.  In dialogPlugin.h:
  2.  
  3.      #include <QtDeclarative/QDeclarativeExtensionPlugin>
  4.  
  5.      class DialogPlugin : public QDeclarativeExtensionPlugin
  6.      {
  7.          Q_OBJECT
  8.  
  9.          public:
  10.          void registerTypes(const char *uri);
  11.  
  12.      };

La nostra classe plugin, DialogPlugin è una sottoclasse di QDeclarativeExtensionPlugin [doc.qt.nokia.com]. Questa prevede che dobbiamo implementare la funzione ereditata, registerTypes(). Il file dialogPlugin.cpp assomiglia a questo:

  1.  DialogPlugin.cpp:
  2.  
  3.      #include "dialogPlugin.h"
  4.      #include "directory.h"
  5.      #include "file.h"
  6.      #include <QtDeclarative/qdeclarative.h>
  7.  
  8.      void DialogPlugin::registerTypes(const char *uri){
  9.  
  10.          qmlRegisterType<Directory>(uri, 1, 0, "Directory");
  11.          qmlRegisterType<File>(uri, 1, 0,"File");
  12.      }
  13.  
  14.      Q_EXPORT_PLUGIN2(FileDialog, DialogPlugin);

La funzione registerTypes() [doc.qt.nokia.com] registra le nostre classi File e Directory in QML. Questa funzione ha bisogno dell nome della classe per il suo template, un numero di versione principale, un numero di versione minore, e un nome per le nostre classi.

Abbiamo poi bisogno di esportare il plugin utilizzando la macro Q_EXPORT_PLUGIN2 [doc.qt.nokia.com]. Si noti che nel file dialogPlugin.h, abbiamo la macro Q_OBJECT in cima alla nostra classe. Inoltre, abbiamo bisogno di eseguire qmake sul file di progetto per generare il necessario codice meta-object.

Creare proprietà QML in una classe C++

Possiamo ora creare elementi e proprietà QML utilizzando C++ e il Qt Meta-Object System [doc.qt.nokia.com]. Siamo in grado di implementare le proprietà utilizzando gli slot e le signal, rendendole note anche a Qt. Queste proprietà possono poi essere utilizzate direttamente in QML.

Per l’editor di testo, dobbiamo essere in grado di caricare e salvare file. Normalmente, queste funzionalità sono contenute in una finestra di dialogo. Per fortuna, possiamo usare QDir [doc.qt.nokia.com], QFile [doc.qt.nokia.com] e QTextStream [doc.qt.nokia.com] per implementare la lettura di directory e gli stream di input/output.

  1.      class Directory : public QObject{
  2.  
  3.          Q_OBJECT
  4.  
  5.          Q_PROPERTY(int filesCount READ filesCount CONSTANT)
  6.          Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
  7.          Q_PROPERTY(QString fileContent READ fileContent WRITE setFileContent NOTIFY fileContentChanged)
  8.          Q_PROPERTY(QDeclarativeListProperty<File> files READ files CONSTANT )
  9.  
  10.          ...

La classe Directory utilizza il Meta-Object System di Qt per registrare le proprietà di cui ha bisogno per realizzare la gestione dei file. La classe Directory è esportata come un plugin ed è utilizzabile in QML come l’elemento Directory. Ciascuna delle proprietà definite utilizzando la macro Q_PROPERTY [doc.qt.nokia.com] è anche una proprietà QML.

La macro Q_PROPERTY [doc.qt.nokia.com] dichiara al Meta-Object System di Qt sia la proprietà, che le sue funzioni di lettura e scrittura. Ad esempio, la proprietà filename, di tipo QString [doc.qt.nokia.com], è leggibile con la funzione filename() e scrivibile utilizzando la funzione setFilename(). Inoltre, vi è una signal associato alla proprietà filename chiamata filenameChanged(), che viene emesso ogni volta che la proprietà cambia. Le funzioni di lettura e scrittura sono dichiarate come public nel file header (.h).

Analogamente, abbiamo le altre proprietà dichiarate secondo il loro utilizzo. La proprietà filesCount indica il numero di file in una directory. La proprietà filename è impostata con il nome del file attualmente selezionato ed il contenuto del file salvato. o caricato, viene memorizzato nella proprietà fileContent.

  1.      Q_PROPERTY(QDeclarativeListProperty<File> files READ files CONSTANT )

La lista di proprietà files è un elenco di tutti i file, filtrati, presenti in una directory. La classe Directory è implementato in modo da filtrare i file di testo non validi; solo i file con estensione .txt sono validi. Inoltre, una QList [doc.qt.nokia.com] può essere utilizzata nei file QML dichiarandola come QDeclarativeListProperty [doc.qt.nokia.com] in C++. L’oggetto deve ereditare da un QObject [doc.qt.nokia.com], quindi, la classe File deve anche ereditare da QObject [doc.qt.nokia.com]. Nella classe Directory, l’elenco di oggetti di tipo File è memorizzato in una QList [doc.qt.nokia.com] chiamata m_fileList.

  1.      class File : public QObject{
  2.  
  3.          Q_OBJECT
  4.          Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
  5.  
  6.          ...
  7.      };

Le proprietà possono quindi essere utilizzate direttamente in QML come parte integrante delle proprietà dell’elemento Directory. Si noti che non abbiamo dovuto creare un proprietà identificatore id nel nostro codice C++.

  1.      Directory{
  2.          id: directory
  3.  
  4.          filesCount
  5.          filename
  6.          fileContent
  7.          files
  8.  
  9.          files[0].name
  10.      }

Poiché QML utilizza la sintassi e la struttura di Javascript, siamo in grado di iterare l’elenco dei file e recuperare le sue proprietà. Per recuperare la proprietà nome del primo file, possiamo usare

  1. files[0].name

Anche le normali funzioni C++ sono accessibili da QML. Le funzioni di caricamento e di salvataggio dei file sono implementate in C++ e dichiarate utilizzando la macro Q_INVOKABLE [doc.qt.nokia.com]. In alternativa, possiamo dichiarare le funzioni come uno slot e renderle in questo modo accessibili da QML.

  1.  In Directory.h:
  2.  
  3.      Q_INVOKABLE void saveFile();
  4.      Q_INVOKABLE void loadFile();

La classe Directory deve anche notificare altri oggetti ogni volta che c’è un cambiamento nel contenuto della directory. Questa funzione viene eseguita utilizzando una signal. Come accennato in precedenza, le signal QML hanno un gestore associato che ha lo stesso nome preceduto dal prefisso on. La signal è denominato directoryChanged e viene emesso ogni volta che c’è un aggiornamento della directory. L’aggiornamento ricarica semplicemente il contenuto della directory e aggiorna l’elenco dei file validi della directory. Gli elementi QML possono poi essere notificati implementand il gestore di signal onDirectoryChanged.

Le proprietà list ha bisogno di essere ulteriormente esplorata. Questo perché le proprietà di tipo list utilizzano delle funzioni di callback per accedere e modificare il contenuto dell’elenco. La proprietà list è di tipo QDeclarativeListProperty<File> . Ogni volta che si accede alla lista, la funzione di accesso (accessor) deve restituire una oggetto di tipo QDeclarativeListProperty<File>. Il tipo del template, File, deve essere un derivato di QObject. Inoltre, per creare la QDeclarativeListProperty [doc.qt.nokia.com], le funzioni di accesso e di modifica (modifier) devono essere passati al costruttore della classe come puntatori a funzione. La lista, una QList nel nostro caso, deve anche essere una lista di puntatori a File.

p.Il costruttore di QDeclarativeListProperty [doc.qt.nokia.com] e l’implementazione in Directory:

  1.      QDeclarativeListProperty  ( QObject * object, void * data, AppendFunction append, CountFunction count = 0, AtFunction at = 0, ClearFunction clear = 0 )
  2.      QDeclarativeListProperty<File>( this, &m_fileList, &appendFiles, &filesSize, &fileAt,  &clearFilesPtr );

Il costruttore passa i puntatori alle funzioni che implementano rispettivamente: aggiungi alla lista, enumera la lista, recupera l’oggetto utilizzando un indice, e svuota la lista. Solo la funzione append è obbligatoria. Si noti che i puntatori a funzione devono corrispondere alla definizione di AppendFunction [doc.qt.nokia.com], CountFunction [doc.qt.nokia.com], AtFunction [doc.qt.nokia.com], e ClearFunction [doc.qt.nokia.com].

  1.      void appendFiles(QDeclarativeListProperty<File> * property, File * file)
  2.      File* fileAt(QDeclarativeListProperty<File> * property, int index)
  3.      int filesSize(QDeclarativeListProperty<File> * property)
  4.      void clearFilesPtr(QDeclarativeListProperty<File> *property)

Per semplificare la nostra finestra di dialogo file, la classe Directory filtra i file di testo non validi, che sono file che non hanno l’estensione .txt. Se un nome di file non ha l’estensione .txt, allora non sarà visibile nella nostra finestra di dialogo file. Inoltre, l’applicazione assicura che i file salvati abbiano l’estensione .txt nel nome del file. La classe Directory utilizza QTextStream [doc.qt.nokia.com] per leggere e scrivere il contenuto del file.

Tramite il nostro elemento Directory, è possibile recuperare tutti i file come una lista, sapere quanti sono i file di tipo testo nella directory dell’applicazione, ottenere il nome del file corrente e il suo contenuto come stringa, ed essere informati quando ci sono cambiamenti nel contenuto delle directory.

Per costruire il plugin, bisogna eseguire qmake con il file di progetto cppPlugins.pro, quindi lanciare make fare per compilare e trasferire il plugin nella directory plugins.

Importare un plugin in QML

Il programma qmlviewer importa i file che si trovano nella stessa directory dell’applicazione. Possiamo anche creare un file qmldir contenente la posizione dei file QML che vogliamo importare. Il file qmldir può anche memorizzare le posizioni di plugin e altre risorse.

  1.  In qmldir:
  2.  
  3.      Button ./Button.qml
  4.      FileDialog ./FileDialog.qml
  5.      TextArea ./TextArea.qml
  6.      TextEditor ./TextEditor.qml
  7.      EditMenu ./EditMenu.qml
  8.  
  9.      plugin FileDialog plugins

Il plugin che abbiamo appena creato si chiama FileDialog, come indicato dal campo TARGET nel file di progetto. Il plugin è compilato e copiato nella directory plugins.

Integrare una finestra di dialogo nel menu File

Il nostro FileMenu ha bisogno di visualizzare l’elemento FileDialog, contenente un elenco dei file di testo in una directory consentendo così all’utente di selezionare un file facendo clic sulla lista. Abbiamo anche bisogno di collegare i pulsanti per salvare, caricare e creare nuovo, alle loro rispettive azioni. Il FileMenu contiene anche un campo di input di testo per consentire all’utente di digitare un nome di file utilizzando la tastiera.

L’elemento Directory viene utilizzato nel file FileMenu.qml e avvisa l’elemento FileDialog quando la directory ha aggiornato il suo contenuto. Questa notifica viene eseguita nel gestore del segnale, onDirectoryChanged.

  1.  In FileMenu.qml:
  2.  
  3.      Directory{
  4.          id:directory
  5.          filename: textInput.text
  6.          onDirectoryChanged: fileDialog.notifyRefresh()
  7.      }

Allineandola con la semplicità della nostra applicazione, la finestra di dialogo file è sempre visibile e non visualizza file di testo non validi, che non hanno una estensione .txt nei loro nomi.

  1.  In FileDialog.qml:
  2.  
  3.      signal notifyRefresh()
  4.      onNotifyRefresh: dirView.model = directory.file

L’elemento FileDialog visualizza il contenuto di una directory leggendo la lista di proprietà chiamata files. I file vengono utilizzati come modello di un elemento GridView [doc.qt.nokia.com], che visualizza gli elementi dati in una griglia su indicazione di un componente delegato. Il delegato gestisce l’aspetto del modello e la nostra finestra di dialogo file utilizza semplicemente una griglia con il testo centrato nel mezzo. Cliccando sul nome del file compare un rettangolo per evidenziare il nome del file. Il FileDialog viene notificato ogni volta che la signal notifyRefresh viene emessa, ricaricando così i file nella directory.

  1.  In FileMenu.qml:
  2.  
  3.      Button{
  4.          id: newButton
  5.          label: "New"
  6.          onButtonClick:{
  7.              textArea.textContent = ""
  8.          }
  9.      }
  10.      Button{
  11.          id: loadButton
  12.          label: "Load"
  13.          onButtonClick:{
  14.              directory.filename = textInput.text
  15.              directory.loadFile()
  16.              textArea.textContent = directory.fileContent
  17.          }
  18.      }
  19.      Button{
  20.          id: saveButton
  21.          label: "Save"
  22.          onButtonClick:{
  23.              directory.fileContent = textArea.textContent
  24.              directory.filename = textInput.text
  25.              directory.saveFile()
  26.          }
  27.      }
  28.      Button{
  29.          id: exitButton
  30.          label: "Exit"
  31.          onButtonClick:{
  32.              Qt.quit()
  33.          }
  34.      }

Il nostro FileMenu può adesso essere connesso alle rispettive azioni. Il pulsante saveButton trasferirà il testo dal TextEdit alla proprietà fileContent della directory, quindi copia il nome del file nel campo di input testo. Infine, il pulsante chiama la funzione savefile(), per salvare il contenuto del file. Il pulsante loadButton ha una comportamento simile. Inoltre, l’azione New svuota il contenuto del TextEdit.

Per finire, i pulsanti EditMenu sono collegate alle funzioni di TextEdit per copiare, incollare e selezionare tutto il testo nell’editor.

http://doc.qt.nokia.com/4.7/images/qml-texteditor5_filemenu.png

L’editor di testo completo

http://doc.qt.nokia.com/4.7/images/qml-texteditor5_newfile.png

L’applicazione può funzionare come un semplice editor di testo, in grado di accettare del testo e salvarlo in un file. L’editor di testo può anche caricare il contenuto da un file ed eseguire manipolazioni del testo.