Home Previous Up Next8.4 مكتبة QT لبرمجة التطبيقات الرسومية
حول
المحتويات
مشاريع
ثواب
مقالات
تنزيل
English

8.4 مكتبة QT لبرمجة التطبيقات الرسومية

محتويات هذا الفصل:

8.4.1 مقدمة

مكتبة QT من شركة www.trolltech.com هي من المكتبات الأقوى في عالم برمجة التطبيقات الرسومية GUI متعدة المنصات (لينكس ،وويندوز، وماك) من أشهر التطبيقات المصممة به هي Opera متصفح الإنترنت وطقم KDE بكل ما فيه من زلايين التطبيقات ذات الجودة العالية. وهذه المكتبة بلا منازع هي الأكثر نضوجاً. لا ينافسها إلا GTK+ وتلك الأخير في تطور مستمر لتواكب QT.

في بداية هذه المكتبة لم تكن رخصتها تعجب فلاسفة GNU ويعتبرونها خطر بل ومصيدة على البرامج الحرة (على الرغم من أنها مفتوحة المصدر إلا أنها ليست حرة بما يكفي وقتها) وقد قام مجتمع البرامج الحرة بالرد بطريقتين أولهما عمل مكتبة بديلة اسمها harmony تسمح بتشغيل البرامج المصممة على QT دون الحاجة لوجود QT! والرد الثاني هو مشروع غنوم GNOME ولكن بعد أن قامت الشركة بتعديل رخصتها في عام 2000 بحيث أصبحت حرة وفق GPL (التي تسمح باستعمالها مجاناً في البرامج الحرة وباشتراك في التجارية) اختفى مشروع harmony وبقي غنوم! على أي حال غنوم و GTK+ يخضان لرخصة GNU LGPL الأكثر حرية (يستعمل في الحرة والتجارية مجاناً) وهما الخيار الأول للمبرمج الحر على الرغم من أن QT أكثر نضوجاً.

 تلميح

مع الإصدار الثالث بدأت QT تدعم العربية.

8.4.2 تعلم QT

إذهب للمجلد /usr/share/doc/qt-3.1.2/doc/html (استبدل الرقم 3.1.2 بالإصدارة لديك) أو شغل برنامج assistant وهما موجودان في حزمة qt-devel. تجد هناك كل ما تحتاج معرفته. من أهم الأدوات التي تساعدك على تصميم برامج QT هي QT Designer شغله بتنفيذ designer-qt3 كما يستعمل linguist لترجمة البرامج من لغة لأخرى.

شغل برنامج QT Designer ثم انقر على قائمة File ثم New ثم اختر C++ Project اكتب اسم المشروع مثلاً myproj.pro إذا كت تريد تحديد مجلد انقر على (...) ثم تابع بعد الحصول على مشروع فارغ أضف صندوق حوار Dialog أو نافذة رئيسية Main Window بحسب التطبيق الذي تريد عمله وذلك بختيار File ثم New واختيار Dialog أو Main Window مع مراعات أنها ستضاف للمشروع نفسه. صمم مشروعك بجر الأزرار والكائنات إليه ثم من خصائص الكائنات هناك Signal Handler ستحصل على نافذة لكتابة الكود ثم اختر من قائمة File الخيار New ثم C++ Main-File(main.cpp) ثم خزّن كل شيء.

QT new dialog

لتحويل المشروع إلى برنامج تنفيذي تبع الخطوات التالية

bash$ qmake -o Makefile myproj.pro
bash$ make
أداة qmake تعمل ملف Makefile وتستدعي uic لتحويل ملفات التصميم ".ui" إلى ".cpp" و ".h"

يمكنك أن تكتب بنفسك الكود الذي يعرض ملف .ui تماماً مثل glade، ويكون ذلك باستعمال مكتتبة تسمى libqui أي عليك إضافة الخيار "-lqui" وذلك بفتح ملف ".pro" وإضافة "LIBS += -lqui" سيحتوي برنامجك على ما يشبه

    QDialog *foo=(QDialog *)QWidgetFactory::create("foo.ui");
    foo->show();
كما يمكنك أن تحصل على مؤشر لأي كائن بعد تحميل ملف ui بذكر اسمه ونوعه كما يلي
    QLabel *l1=(QLabel *)foo->child("mylabel","QLabel");

8.4.3 لنكتب أول البرامج

افتح مجلد خاص بكل مشروع، لنعمل مجلد باسم 'goodbye' ونضع فيه ملف المثال التقليدي التالي:

// goodbye.cpp - trivial QT example
#include<qapplication.h>
#include<qpushbutton.h>

int main(int argc,char **argv) {
	QApplication app(argc,argv);
	QPushButton *btn= new PushButton("Goodbye, world!!",0);
	// quit when btn is clicked
	QObject::connect(btn,SIGNAL(clicked()),&app,SLOT(quit()));
	app.setMainWidget(btn);     // quit main loop when distruct btn
	btn->show();
	return app.exec();          // QT main loop
}
ونسميه goodbye.cpp أو main.cpp
 تلميح

جرت العادة أن نسمي الملف الذي يحتوي وظيفة main باسم main.cpp في المشاريع ذات الملفات المتعددة

اعمل ملف المشروع المستقل عن بيئة العمل(المنصة؛ سواء أكانت لينكس أم غيره) بالأمر "qmake -project" لاحظ ظهور ملف جديد يحمل اسم المجلد الذي نحن به والامتداد pro أي في مثالنا goodbye.pro قد تحتاج لتتعديل هذا الملف قليلاً لتنجح عملية التصنيف
 تحذير

أكثر الأخطاء شيوعاً عند المبرمجين الجدد هو نسيان وضع قيمة مناسبة للمتغيّر QTDIR بأمر يشبه "export QTDIR=/usr/share/qt3".

لعمل ملف المشروع الخاص بالبيئة التي تعمل عليها الآن من ملف pro السابق بالأمر "qmake -makefile goodbye.pro" مما سينتج لك ملف Makefile تتعامل معه كما تحدثنا في فصل "3.5 تركيب الحزم المصدرية" مثلاً لبناء وتشغيل الملف التنفيذي اكتب "make && ./goodbye"
 تحذير

الأمر الآخر الذي قد يعطل عملية التتصنيف هو أن بعض التوزيعات تسمي المكتبة libqt-mt لذا عليك في هذه الحالة فتح ملف Makefile والبحث عن "-lqt" وتعديلها لتصبح "-lqt-mt"

كما تلاحظ أن المكتبة تستغل مزايا سي++ في البرمجة الموجهة، أولاً نحتوي الملف المسؤول عن تطبيقات QT بواسطة #include<qapplication.h> وذلك لنتمكن من تعريف كائن (متغير) يمثل التطبيق الذي نبرمجه بواسطة QApplication app(argc,argv); حيث argc و argv التي مررناها لوظيفة الإنشاء constructer هي معاملات الوظيفة main. على عكس المكتبات الأخرى يمكن عمل برنامج رسومي دون عمل نافذة تحتوي كائناته حيث يحاط كل كائن ليس له نافذة أم بنافذة، في المثال أعلاه حجزنا كائن لزر ديناميكياً يحتوي على نص بواسطة QPushButton *btn= new PushButton("Goodbye, world!!",0); (وفره لنا احتواء #include<qpushbutton.h>) المعامل الثاني يشير للحاوية الأم (النافذة) وفي هذه الحالة (صفر أو NULL) فإنها تُصنع لنا. ولتحديد الكائن الرئيسي في التطبيق الذي نصممه (أي الذي ينتهي البرنامج باختفاؤه) استدعينا الطريقة (الوظيفة) setMainWidget الخاصة بالتطبيق app -الذي عرفناه مسبقاً- بواسطة app.setMainWidget(btn); أظهرنا الزر (وبالتالي النافذة التي تحتويه التي عملتها لنا QT) بواسطة الطريقة show أي btn->show(); لاحظ استخدام -> لأن btn مؤشر راجع "7.3 البرمجة الموجهة للكائنات". الآن طلبنا الانتظار حتى ينتهي التطبيق (مثلاً بإغلاق الكائن الرئيسي) بواسطة app.exec(); أو لإعادة أي خطأ ينتج استعملنا return app.exec();. ولأننا نريد أن يؤدي الضغط على زر btn إلى الخروج استعملنا طريقة(وظيفة) connect الستاتيكية للصنف QObject أي تلك التي تستدعى دون كائن، ومررنا لها مؤشر للكائن الذي سنربط حدثاً عليه بنشاط معين، ثم ذلك الحدث (نسميه الإشارة التي تتولد عليه عند ذلك الحدث) ثم مؤشر للكائن الذي يحتوي رد الفعل(النشاط) على ذلك الحدث(الإشاراة) ثم رد الفعل وهي طريقة (وظيفة عضو) في الكائن السابق ، في المثال كان ذلك بواسطة

QObject::connect(btn,SIGNAL(clicked()),&app,SLOT(quit()));
لاحظ استعمال الاختصاران SIGNAL و SLOT لتحديد الإشارة والرد. الوظيفة quit() يجب أن تكون معرفة(وظيفة عضوة أو طريقة) في صنف الكائن الثاني (في المثال app) ولولا أن quit موجودة لكن علينا عمل صنف مشتق derived class لنضعها فيه.

المثال التالي مأخوذ من كتاب C++ GUI Programming with QT 3 لمؤلفه Bruce Perens:

// age.cpp - a slider and a spinbox having the same value
// based on C++ GUI Programming with QT 3 by Bruce Perens
#include <qapplication.h>
#include <qhbox.h>
#include <qslider.h>
#include <qspinbox.h>
int main (int argc, char *argv[]) {
  QApplication app (argc, argv);
  QHBox *hbox = new QHBox (0);
  hbox->setCaption ("Enter Your Age");	//  set title bar
  hbox->setMargin (6);
  hbox->setSpacing (6);
  QSpinBox *spinBox = new QSpinBox (hbox);
  QSlider *slider = new QSlider (Qt::Horizontal, hbox);
  spinBox->setRange (0, 130);
  slider->setRange (0, 130);
  QObject::connect (spinBox, SIGNAL (valueChanged (int)),
		    slider, SLOT (setValue (int)));
  QObject::connect (slider, SIGNAL (valueChanged (int)),
		    spinBox, SLOT (setValue (int)));
  spinBox->setValue (35);
  app.setMainWidget (hbox);
  hbox->show ();
  return app.exec ();
}
لاحظ أننا جعلنا كائن صندوق التكديس الأفقي QHBox هو الكائن الأساسي الأم للكائنين الأخريين في تطبيقنا spinBox و slider.

8.4.4 البرمجة الموجهة للكائنات ومكتبة QT

الآن سنعيد تصميم برنامج جمع رقمين التقليدي الذي قدمناه في فصل GTK+ بطريقة مكتبة QT، علينا أولاً أن نتبع تصميم موجه للكائنات لأن تصميم التعامل مع الإشارات signal handling في QT كذلك، أولاً نكتب ملف header حيث نشتق صنف من QDialog أو QMainWindow

/*
 * sum.h: the header file for sum.cpp
 *
 * by Moayyad Al-Sadi<alsadi[at]gmail.com>
 * released under the terms of the GNU General Public License
 * visit www.gnu.org/copyleft
 *
 */
#ifndef SUMDIALOG_H
#define SUMDDIALOG_H
#include <qlabel.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qdialog.h>
class SumDialog:public QDialog {
Q_OBJECT public:
  SumDialog (QWidget * parent = 0, const char *name = 0);
    signals:
	void calc (const float a,const float b);
    private slots:
	void okClicked ();
private:
  QLabel * label1,*label2,*label3;
  QLineEdit *num1,*num2,*num3;
  QPushButton *ok;
};
#endif
لاحظ كيف جاء Q_OBJECT قبل كل شيء داخل الصنف، هذا الاختصار macro يخبر qmake أن يقوم ببعض الحيل. بنفس الطريقة التي نستعمل بها public و private نستعمل signals و slots حيث الأولى نستخدمهما لنحدد الإشارات وطرق التعامل معها. البرنامج نفسه هو كما يلي:
/*
 * sum.cpp: A sample QT application to add two numbers.
 *
 * by Moayyad Al-Sadi<alsadi[at]gmail.com>
 * released under the terms of the GNU General Public License
 * visit www.gnu.org/copyleft
 *
 */
#include "sum.h"
SumDialog::SumDialog (QWidget * parent, const char *name):
QDialog (parent, name)
{
  setCaption (tr ("Find Summation"));
  label1 = new QLabel (tr ("&First number:"), this);
  label2 = new QLabel (tr ("&Second number:"), this);
  label3 = new QLabel (tr ("Su&mmation:"), this);
  num1 = new QLineEdit (this);
  num2 = new QLineEdit (this);
  num3 = new QLineEdit (this);
  label1->setBuddy (num1);  label2->setBuddy (num2);
  ok = new QPushButton (tr ("OK."), this);
  ok->setDefault (true);
  // num3->setEnabled (false);
  connect (ok, SIGNAL (clicked ()), this, SLOT (okClicked ()));
  QHBoxLayout *hbox1 = new QHBoxLayout;
  hbox1->addWidget (label1);
  hbox1->addWidget (num1);
  QHBoxLayout *hbox2 = new QHBoxLayout;
  hbox2->addWidget (label2);
  hbox2->addWidget (num2);
  QHBoxLayout *hbox3 = new QHBoxLayout;
  hbox3->addWidget (label3);
  hbox3->addWidget (num3);
  QVBoxLayout *vbox = new QVBoxLayout;
  vbox->addLayout (hbox1);
  vbox->addLayout (hbox2);
  vbox->addLayout (hbox3);
  vbox->addWidget (ok);
}
void SumDialog::okClicked () {
  float a = a2f( num1->text () );
  float b = a2f( num2->text () );
  emit calc (a,b);
}
void SumDialog::calc(const float a, const float b) {
  char str[40];
  float c=a+b;
  sprintf(str,"%g",c);
  num3->setText (c);
}
int main(int argc, char *argv[]) {

    QApplication app(argc,argv);
    SumDialog *dialog=new SumDialog;
    app.setMainWidget(dialog);
    dialog->show();
    app.exec();

}
لاحظ أن وظيفة البناء constructer تستخدم لعمل التصميم ولاخظ أيضاً استخدام المؤشر الذاتي this. لننفذ برنامجنا ونلاحظ النتيجة
bash$ qmake -project
bash$ qmake -makefile sum.pro
bash$ make && ./sum

المحتويات
حقوق النسخ والملكية الفكرة
ما هو لينكس؟
كيف تركب نظام لينكس؟
حقوق النسخ المرفوعة
وثائق التخويف

عرب-آيز
مجتمع لينكس العربي
موسوعة ثواب
موسوعة ويكيبيديا
تعريف البرمجيات الحرة
تعريف مفتوحة المصدر
LinuxToday
Linux.org
Linux.com
SlashDot
FreshMeat
LWN.net
توزيعات لينكس
النسخة الإسلامية لأوبنتو
عَرَبيان
جواثا (أول مسجد في أوروبا)
المزيد من التوزيعات هنا

إسلاميات
    برامج:
بريمج أوقات الصلاة
بريمج التقويم الهجري
    صوتيات:
محاضرات: قصص الأنبياء (نبيل العوضي)
أناشيد
اطلب نسختك مجاناً
لكي تصلك أقراص لينكس أوبونتو Ubuntu أصلية مجاناً والتوصيل مجاناً لن تدفع فلساً واحداً ولن تجبر على رؤية دعايات. كل ما عليك هو أن تنقر هنا.
مقالات
    تقنية:
تسجيل وتحويل الصوتيات
تعريف الماسح الضوئي في لينكس
    ساخرة:
من أجل ذلك لا تقرأ
الفيلة والصراع العربي الإسرائيلي
بلاغات
التبليغ عن إعلانات غير مرغوبة
عثرات وأخطاء إملائية
وصلات لا تعمل:

 

ننصح باستخدام متصفحات الوب الحرة، جرب ثعلب النار الآن

يمكنك الحصول على الكثير من البرامج الحرة عالية الجودة من هنا مجاناً
proud to be 100% Microsoft FREE GNU FDL
التدخين حرام

كن كحامل المسك ولا تكن كنافخ الكير

Generously Hosted by www.JadMadi.net

Previous Up 8.4 مكتبة QT لبرمجة التطبيقات الرسومية Next
Copyright © 2007, Muayyad Saleh AlSadi