التطوير السريع للتطبيقات Rapid Application Development



السلام عليكم ،،

ملاحظة قبل البدء :
يفضل قراءة الجزء الاول والثاني لسلسة دروس للمبتدئين قبل هذا الدرس ، من هنا:
الجزء الاول
الجزء الثاني
+++++++++++++++++++++++++++++++++++++++

مقدمة :
انشاء ال widgets ووضعها في مخطط امر ممتع جدا ، ولكن عندما يكون عددها كبير ، فان العملية ستتحول من ممتع جدا الى ممل جدا و مضعية للوقت بشكل رهيب .
لهذا السبب وفرت لنا Qt برنامجا لتصميم الواجهات وانشاء المخططات ووضع خصائص كل widget بشكل بسيط وسريع وممتع ايضا .

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

فلسفة الـ Designer :
اول معلومة يجب ان تعرفها عن الـ Designer هو انه ليس بيئة تطوير مدمجة IDE.
فهو لا يحوي محرر نصوص لكتابة الشفرات ، ولا يحوي امكانية عمل مشروع ولا ترجمة ولا ربط ولا...الخ.

الهدف الرئيسي منه هو فقط انشاء الواجهة الرسومية لبرنامجك !!

ويعد ان تنشئ الواجهة 'كما سندرس الان' ستقوم بحفظ الملف بالامتداد ui .
هذا الملف ذات الامتداد ui هو عبارة عن ملف XML ، يحوي على شفرة مطابقة للواجهة التي قمت بتصميمها .

ثم بعد ذلك يجب ان ننشئ فئة جديدة بحيث ترث من احد فئات Qt مثلا QWidget ، وترث ايضا من الواجهة الرسومية التي قمت بانشائها .

الوراثة من احد فئات Qt كما تعلمنا سابقا تعطي الفئة القدرة على الكثير من الاشياء 'تجعلها تحمل خصائص اي widget “. اما الوراثة من الفئة الناتجة من الواجهة الرسومية التي انشأتها تعطي الفئة الجديدة نفس الشكل والكائنات الموجودة على الواجهة الرسومية .

المترجم User Interface Complier و اختصارا uic ، يقوم بقرائة ملف الـ XML وتحويله الى ملف راسي ياخذ الامتداد .h ، بداخل هذا الملف الرأسي سنجد الاعلان عن الفئة الاخرى التي قمنا بوراثتها .

سيتضح لك هذا الكلام في هذا المثال ..

سنكتب برنامج توضيحي Toys Example ، يعني الهدف هو توضيح فكرة معينة.
طبعا من الممكن ان نوضح الفكرة في برنامج واقعي ، ولكن عدد السطور سيزداد كثيرا ، وهذا سيخرجنا من الموضوع الرئيسي الى مواضيع اخرى .. :oops:

المخرج يجب ان يكون بهذا الشكل:


الشيء المثير هنا هو اللغة العربية ، وما أجملها من لغة !
نبدأ وعلى بركة الله ،،

افتح برنامج المصمم كما تعلمنا في الجزء الاول .
عن طريق قائمة البرنامج في ويندوز وفي لينوكس اكتب في سطر الاوامر designer.

راح تفتح لك هذه النافذة :


اختر القالب Widget ، وهو الذي سنستخدمه دائما ، لكن في مواضيع قادمة -ان شاء الله- سنتعرف على MainWindow ، وفي الذي يليه سندرس Dialog.
الان اضغط على انشاء Create .


هذه هي ساحة العمل ، لدينا في اليمين dock window يحوي خصائص اي كائن عليه التحديد. وفي اليسار لدينا dock window به قائمة بكل الكائنات الرسومية .تستطيع اغلاق هذه النوافذ واعادة فتحها من قائمة ادوات Tools.

قبل ان نبدأ في وضع الكائنات على النافذة الاب ، قم بتعديل الخاصية Layout Direction من
Left to Right الى Right to Left ، من القائمة في اليمين ذات اللون الاصفر.

الان قم بسحب الكائنات المشابهة لمخرج البرنامج في الصورة الاولى ، والقائها على النافذة بنفس الترتيب ، لكن لا تتعب نفسك بعملية محاذاتها ، فهذه مهمة الـ Layouts ، اي هذا الشكل :


ثم اعد تسمية كل كائن بالضغط عليه مرتين او من نافذة الخصائص ، اختر الخاصية text واكتب ما تريد ، لكن لا تنسى تحديد الكائن المراد تغيير خصائصه .
فكل كائن لديه خصائصه ، حتى النافذة الاب التي تحوي الكائنات لديها خصائص .

المخططات layouts تستطيع تطبيقها من هنا :


الاول من اليسار هو لانشاء مخطط افقي ، والثاني عمودي والخامس مخطط شبكي.
والزر السابع هو لالغاء اي مخطط ، والاخير هو لتغيير حجم النافذة .

الان بعد ان انشأت الشكل السابق ، يجب ان ننشيء بعض المخططات ، كالاتي:
قم بتحديد الازرار الموجودة في الاسفل 'بالضغط المتواصل على زر Shift ثم حدد الازرار'
وقم بالضغط على المخطط الافقي ، النتيجة يجب ان تكون بهذا الشكل:


ملاحظة : عند الكتابة باللغة العربية فان تطبيق المخطط على النافذة لا ينجح من اول محاولة ، حيث يقوم بقلب الازرار الى الجهة المعاكسة ، ولاصلاحها يجب ان تقوم بالغاء المخطط بعد ان انشأته ، ثم تحدد الكائنات مرة اخرى وتضغط على المخطط المطلوب مرة ثانية. اي انك يجب ان تقوم بها مرتين ! لماذا ! الله اعلم .

النتيجة :


بنفس الخطوات ، قم بانشاء مخطط افقي للصف الاول ، النتيجة :


الان قم بالضغط مرتين على كائن QComboBox ، حيث ستخرج لك نافذة لكي تكتب فيها القائمة التي تريدها ، قم بكتابة اي شيء كالاتي :


الان قم بسحب Horizontal Spacer مرتين من قائمة الاشكال ، وضعهما في المنتصف بهذا الشكل:


ثم قم بتحديد الصف الثاني والثالث ، واختيار المخطط الشبكي 'لاتنسى اعادة الخطوة حتى لا يكون الشكل مقلوبا ' . واخيرا ، اضغط على النافذة حتى تلغي اي تحديد لاي كائن ، ثم اختر المخطط العمودي.
النتيجة تقريبا:



حاليا انتهينا من خطوتين في كتابة اي برنامج Qt :
1- انشاء الكائنات .
2- انشاء المخططات ووضع الكائنات عليها ، ثم وضع المخطط على النافذة الاب.


نأتي الى تعديل الخصائص..


اي كائن كما ذكرت تستطيع التحكم في خصائصه من خلال هذه النافذة .
وكما ترى يوجد الكثير من الخصائص ، والتي ستكون مهمتك هي اكتشاف هذه الخصائص.

الان قم بالضغط على النافذة الاب ،و تاكد انه لا يوجد اي تحديد على كائن ، ثم من نافذة الخصائص غير الخاصية objectName الى الاسم Window مثلا.
هذه الخاصية تحدد لنا اسم الكائن ، والذي سنستخدمه لاحقا عندما نبدأ بكتابة الشفرات.

لذلك قم بتحديد كائن كائن ، وقم بتغيير الخاصية objectName الى الاتي:

الزر 'حول البرنامج' -------> aboutButton
الزر 'مسح' ---------------> clearButton
الزر 'عرض' ---------------> showButton
الزر 'خروج' ---------------> exitButton
الزر 'استعراض' ----------> browseButton


ودع بقية الكائنات كما هي .

لكن يجب ان تتذكر دائما تغيير مسميات الكائنات ، لانها تأخذ اسامي تلقائية ، مثلا الزر الاول اسمه pushButton_1 ، والثاني pushButton_2 ... وهكذا ، لذلك اذا كانت الواجهة تحوي اكثر من كائن من نفس النوع يجب ان نغير مسمياتهم فورا ، لاننا عندما نذهب للشفرة 'كما سنرى' فانه يصعب تذكر هذه الاسامي التلقائية .

لكن لو لاحظت اننا لم نغير الكائنات من الفئة QLable ؟ وذلك لاننا لن نحتاج اليهم في برنامجنا هذا ، ولكن يجب عليك ان تتعود وتعيد مسميات اي كائن دائما .

قم الان بحفظ الملف ، ويفضل بنفس اسم الفئة الاب ، يعني الاسم سيكون window .
ولا تنسى ان يكون الملف window.ui في مجلد جديد حيث سنستخدمه لاحقا ..

وبعدها افتح قائمة Form ثم اختر ال Preview in ، وحدد اي Style تريده ، وذلك لكي تشاهد شكل البرنامج النهائي ..


تعديل خصائص size policy :
في هذا الموضوع Here
تحدثنا عن الـ size policy وامكانية تغييره من خلال ال Designer ،، وحان الوقت لكي
نشاهد كيف يمكن ذلك ..

من نافذة الخصائص ،، ستجد خاصية size policy كالاتي :



وكما تلاحظ يكمن ان نغير القانون الخاص باي كائن ،، جرب مثلا ان تختار الكائن spinBox و dateEdit وتغير خصائص ال Horizontal Policy الى Preferred ، بهذا الشكل :


ثم قم بحفظ الملف وعرض البرنامج على الشاشة من قائمة Form كما ذكرنا سابقا ..
وبعدها كبر البرنامج من خلال الضغط على زر Maximize ، وقارن بين هذا المخرج وبين المخرج السابق.

وسأترك لك اكتشاف جميع الخصائص الاخرى حتى لانزحم الموضوع بكلام تطبيقه عمليا اسهل من شرحه . :mrgreen:

تأكد الان من حفظ الملف window.ui ، ثم اقفل ال Designer ، وتوجه الى المجلد الذي يحوي الملف السابق ،، وانشئ ثلاث ملفات جديدة بالاسماء window.h و window.cpp و main.cpp .


حقيقة ملف الـ ui :
الملف window.ui الذي أنشاناه هو عبارة عن ملف بلغة XML يحوي tags يمثل الشاشة التي انشاناها ،،
هذا الملف يتعامل معه المترجم UIC فياخذه كمدخلات ويخرج لنا ملف راسي ui_window.h
الملف الرأسي يحوي فئة Class مطابقة لملف XML ،، اسم الفئة هو Ui_Window ،ولكننا لن نتعامل مع هذا الاسم 'مجرد عادة فقط' ، وذلك لوجود مساحة اسماءnamespace UI تحوي بداخلها فئة اسمها Window وهي مورثة من Ui_Window.

باختصار ،، سنستخدم Ui::Window للدلالة على الفئة التي انشاناها باستخدام الـ Designer.

الان افتح ملف window.h وقم بكتابة الشفرة الاتية :

  1. #ifndef WINDOW_H
  2. #define WINDOW_H
  3.  
  4. #include 'ui_window.h'
  5. #include <QWidget>
  6.  
  7. class Window:public QWidget,private Ui::Window
  8. {
  9. Q_OBJECT
  10. public:
  11. Window(QWidget* =0);
  12.  
  13. public slots:
  14. void browseClicked();
  15. void aboutClicked();
  16. void clearClicked();
  17. void showClicked();
  18. };
  19.  
  20. #endif // WINDOW_H



شرح مبسيط :
اهم ما في الملف هو الوراثة من الفئة QWidget ، و الفئة Ui::Window.
الوراثة من الفئة QWidget تعطي الفئة الجديدة نفس ميزات اي فئة رسومية .
اما الوراثة من الفئة Ui::Window فهي تعطي الفئة الجديدة كل ميزات وخصائص الفئة التي انشأناها عن طريق المصمم Designer “اي تعطينا كل الازار والكائنات التي انشأناها'.

وقد ورثنا منها عن طريق المحدد private وذلك حتى نمنع وصول كائن الفئة Window الى محتويات الفئة Ui::Window .
راجع موضوع قسم سي++ ، حتى تتعرف على الموضوع بشكل افضل .

ايضا قمنا بتعريف عدة دوال slots وذلك حتى نقوم بربطها مع احداث الضغط على الازرار .


الان افتح ملف window.cpp واكتب بداخله :

  1. #include <QMessageBox>
  2. #include <QFileDialog>
  3.  
  4. #include 'window.h'
  5.  
  6. Window::Window(QWidget* parent):
  7. QWidget(parent)
  8. {
  9. // install ui on this widget
  10. setupUi(this);
  11.  
  12. // establish a connection
  13. connect(browseButton,SIGNAL(clicked()),this,SLOT(browseClicked()));
  14. connect(clearButton,SIGNAL(clicked()),this,SLOT(clearClicked()));
  15. connect(showButton,SIGNAL(clicked()),this,SLOT(showClicked()));
  16. connect(aboutButton,SIGNAL(clicked()),this,SLOT(aboutClicked()));
  17. connect(exitButton,SIGNAL(clicked()),this,SLOT(close()));
  18.  
  19. // No need to set Properties and Layout,because we do it in the UI file.
  20. }
  21.  
  22. void Window::browseClicked()
  23. {
  24. QString file=QFileDialog::getOpenFileName(this);
  25.  
  26. lineEdit->setText(file);
  27. }
  28.  
  29. void Window::aboutClicked()
  30. {
  31. QMessageBox::about(this,'About Programmer','Ahmad EssamnSudaNixnwww.qt-ar.orgnwww.sudancs.com');
  32. }
  33.  
  34. void Window::clearClicked()
  35. {
  36. textEdit->clear();
  37. }
  38.  
  39.  
  40. void Window::showClicked()
  41. {
  42. textEdit->append('Path: '+lineEdit->text());
  43.  
  44. textEdit->append('Value: '+QString::number(spinBox->value()));
  45.  
  46. textEdit->append('Date: '+dateEdit->date().toString());
  47.  
  48. if( checkBox->checkState() == Qt::Checked )
  49. textEdit->append('Checked');
  50. else
  51. textEdit->append('Unchecked');
  52.  
  53. textEdit->append('Your Home: '+comboBox->currentText());
  54. }


شرح مبسط :
في دالة البناء قمنا بعملية ضرورية وهي تنزيل الواجهة التي انشأناها على هذه الفئة ، وهذا يتم عن طريق الدالة setupUi
هذه الخطوة ضرورية دائما عندما نصمم الفئة عن طريق الـ Designer.

ثم قمنا بعملية ربط احداث الضغط على الازرار بالـ slots التي انشاناها ..

اخيرا عمل دوال slots بسيط جدا ، اذا كنت قد قرات السلسة الموجودة في المنتدى وطبقتها جيدا .
وراجع الـ Assistant للتعرف على عمل هذه الدوال .


ملف main.cpp

  1. #include <QApplication>
  2. #include 'window.h'
  3.  
  4. int main(int argc,char* argv[])
  5. {
  6. QApplication app(argc,argv);
  7.  
  8. Window window;
  9. window.show();
  10.  
  11. return app.exec();
  12. }


النتيجة النهائية :



ا.هـ



تمت طباعة الدرس من موقع مكتبة الدروس
http://qt-ar.org/lessons/show27.html