تخطيط البرامج Program Layout



تلعب المخططات Layouts دورا كبيرا في تطبيقات Qt ، حيث توفر العديد من المميزات ، منها :


•ترتيب الـ widgets على النافذة.
•لا حاجة لتعيين الاب لكل widgets يتم انشائه ، فهذه ستصبح من مهام ال Layouts.
• اعطاء الـ widgets احجام مثالية ، تتاثر مع التغيير في حجم البرنامج سواء بالتكبير او التصغير.
• الانتهاء من المشاكل الناتجة من تغيير حجم الخط ، او ترجمة لغة التطبيق ، حيث بدون استخدام المخططات فانه يجب اعادة تعيين احداثيات ال widgets في حالة اذا تم تغيير اللغة او تغيير حجم الخط.


في هذا الموضوع سنتعرف على كيفية تخطيط الـ Widgets داخل المخططات .

انواع المخططات Layouts:
المخططات في Qt ترث من الفئة QLayout بشكل مباشر او غير مباشر.
وسندرس اهم الانواع واكثرها استخداما .

المخطط الافقي Horizontal Layout :
هذا المخطط QHBoxLayout يستخدم لكي تكون ال widgets مرتبة افقيا من اليسار الى اليمين ، ويمكننا تغيير الاتجاه باستخدام الدالة QBoxLayout::setDirection.

الدوال الاكثر استخداما هي الدالة addWidget والتي تستخدم لاضافة widget الى المخطط .
الدالة addLayout والتي تستخدم لاضافة مخطط الى هذا المخطط اي كـ Sub-Layout.
الدالة addStretch والتي تستخدم لاضافة مسافة بين ال widgets.

مثال صغير :



  1. //... some code
  2. QHBoxLayout* layout=new QHBoxLayout;
  3. layout->addWidget(oneButton);
  4. layout->addWidget(twoButton);
  5. layout->addStretch();
  6. layout->addWidget(threeButton);



المخطط العمودي Vertical Layout :
المخطط QVBoxLayout يستخدم لكي تكون ال widgets مرتبة عموديا من الاعلى الى الاسفل.
ويمكن تغيير الاتجاه ليكون من الاسفل الى الاعلى باستخدام الدالة setDirection.

والدوال الاكثر استخداما هي نفسها المستخدمة في الفئة QHBoxLayout.

مثال:



  1. //... some code
  2. QVBoxLayout* layout=new QVBoxLayout;
  3. layout->addWidget(oneButton);
  4. layout->addWidget(twoButton);
  5. layout->addStretch();
  6. layout->addWidget(threeButton);



المخطط الشبكي QGridLayout :
يستخدم هذا المخطط لترتيب الـ widgets على صفوف واعمدة .

واكثر الدوال استخداما هي :
  1. addWidget(QWidget*,int fromRow,int fromColumn,int rowSpan=1,int columnSpan=1)


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

الدالة addLayout تستخدم لاضافة مخطط .

الدالتان :
  1. setColumnStretch(int column,int factor)
  2. setRowStretch(int row,int factor)


تستخدمان لتحديد حجم العمود او الصف.
حيث ان الوسيط الاول يمثل رقم العمود او الصف ، اما الوسيط الاخر فهو لتحديد معامل التكبير .

مثال :



  1. //... some code .
  2. QGridLayout *layout=new QGridLayout;
  3. layout->addWidget(b1,0,0);
  4. layout->addWidget(b2,0,1);
  5. layout->addWidget(b3,0,2);
  6. layout->addWidget(b4,1,0);
  7. layout->addWidget(b5,1,1);
  8. layout->addWidget(b6,1,2);
  9. layout->addWidget(b7,2,0);
  10. layout->addWidget(b8,2,1);
  11. layout->addWidget(b9,2,2);
  12. layout->addWidget(b10,3,0,1,3);


++++++++++++++++++++++++++++++

حجم الـ widgets داخل الـ Layouts :
ربما قد تسائلت عن كيفية تغيير حجم ال widgets داخل الـ Layouts !!

ارجع الى المثال في نهاية الجزء الاول، وقم بتنفيذ البرنامج .

قم بتكبير النافذة ، ماذا تلاحظ ؟ لماذا كائن الفئة QLCDNumber قد اخذ مساحة كبيرة من ناحية العرض والارتفاع ؟ ولماذا كائنات الفئات QSpinBox,QLineEdit,QProgressBar قد زاد حجم العرض فقط وليس الارتفاع !
هل يمكن تغيير هذه الحجوم !

طبعا يمكن ، من خلال الفئة QSizePolicy !!

اي widget لديه كائن افتراضي من الفئة QSizePolicy ، بحيث هذا الكائن يحمل القوانين الخاصة بحجم الـ widget داخل الـ Layout.
اي اذا لم تستخدم المخططات ، فلا تاثير لهذا ال size policy .

الان لتغيير الجحم المفترض لاي widget داخل مخطط ، يجب علينا ان نحدد القوانين التي يجب ان يأخذها الـ widget داخل المخطط ، بالنسبة للارتفاع'Vertical policy” والعرض'Horizontal policy“

الدالة المستخدمة هي
  1. Qwidget::setSizePolicy(QSizePolicy::policy horizontal,QSizePolicy::policy vertical)

او
  1. Qwidget::setSizePolicy(QSizePolicy)


كذلك اي widget لديه حجم مثالي ، مثلا بالنسبة للزر QPushButton فان العرض هو 75 بكسل والارتفاع هو 25 بسكل ، هذا الحجم المثالي 'تستطيع معرفته من الدالة Qwidget::sizeHint()” له علاقة مع ال size policy.

فمثلا لو استخدمنا القانون fixed مع العرض والارتفاع ، فان هذا يعني ان حجم الكائن سيكون هو الحجم المثالي ، وغير قابل للزيادة في حالة تم تكبير النافذة ولا للنقصان في حالة التصغير.


القوانين :



الفئات مثل QSpinBox,QLineEdit,QProgressBar تستخدم القانون QSizePolicy::Expanding لل horizontal increment ، و القانون QsizePolicy::Fixed مع vertical increment .


الان ارجع الى المثال السابق ، وقم باضافة هذا السطر مع الاسطر التي تحوي الخصائص :
  1. dial->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);


لاحظ اننا اعطينا الكائن dial القدرة على التوسعة في حالة ما تم تكبير البرنامج.
ولا تنسى اضافة ملف
  1. include <QSizePolicy>
، ثم نفذ البرنامج لترى النتيجة !


ملاحظة اخيرة على هذا الموضوع :
لا تقلق نفسك بتجربة كل size policy ، فعندما نتحدث لاحقا عن برنامج المصمم Designer سنستخدم طريقة سريعة جدا بحيث نستطيع ان نرى المخرجات بسرعة ايضا .

++++++++++++++++++++++++++++

معامل التكبير Stretch Factor :
عند وضع الـ widgets داخل المخطط Layout فان المخطط سيكون مسؤول عن تنففيذ ال size policy لكل widgets فيه ،وذلك في حالة ما اذا تم تغيير حجم البرنامج سواءا بالتكبير او التصغير .

ولكن لنفرض ان لدينا 3 ازرار موجودة في مخطط افقي كالاتي :



واردنا تكبير الزر الاول بحيث يكون اكبر من الزرين الاخرين !
ال size policy لا يعطينا مثل هذه الامكانيات ، لذلك سنستخدم الدالة :
  1. setStretchFactor(QWidget*,int)


حيث تاخذ وسيطين ، الاول هو مؤشر للكائن المراد تكبيره ، والثاني هو معامل التكبير .

مثال :



  1. QHBoxLayout *layout=new QHBoxLayout;
  2. layout->addWidget(b1);
  3. layout->addWidget(b2);
  4. layout->addWidget(b3);
  5. layout->setStretchFactor(b1,1);


لاحظ ان المعامل الذي وضعناه هو 1 ، وفي هذا المثال لو وضعنا 1 او 14 او حتى 1000 فلا يوجد فرق!
هذا الرقم سيكون له تأثير في حالة قمنا ياستخدامه على عدة كائنات ، اثنين او اكثر .


لاحظ في هذا المثال:



  1. QHBoxLayout *layout=new QHBoxLayout;
  2. layout->addWidget(b1);
  3. layout->addWidget(b2);
  4. layout->addWidget(b3);
  5. layout->setStretchFactor(b1,3);
  6. layout->setStretchFactor(b2,2);
  7. layout->setStretchFactor(b3,1);


حيث الزيادة في حجم الزر الاول هي ثلاث اضعاف مقارنة مع البقية .وهكذا.

الى هنا نصل الى ختام الموضوع .
وللاستزادة عليك بالرجوع الى ال Assistant ، لكن يكفي هذا الموضوع كبداية .

دمتم بخير .



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