الخلاصات:
تدوينات
تعليقات

السلام عليكم ورحمة الله وبركاته

الإدخال والإخراج لبيانات الفئات

عندما تريد حفظ متغيرات من نوع “أ” في ملف ومن ثم تقرأها في وقت آخر أو حين تريد
تبادل بيانات من نوع “أ” عبر  الشبكة  فإنك بحاجة الى نقل البيانات الثنائية بطريقة
تسهل عليك التعامل معها وتوفر لك الوقت…

فمثلا في الفئات  QFont و QColor و …… الخ  تم توفير المعاملين

QDataStream & operator<< ( QDataStream & s, const QFont & font )

(QDataStream & operator>> ( QDataStream & s, QFont & font

الأول للكتابة من الفئة الى ملف او الى QByteArray او QIODevice او …. الخ
والثاني للقراءة من ملف أو من QByteArrayاو QIODevice او …. الخ .

مثال

QFont font1,font2;

QByteArray ba;

QDataStream ds(&ba,QIODevice::WriteOnly);

QDataStream ds2(&ba,QIODevice::ReadOnly);

ds<<font1;

ds2>>font2;

وبالتأكيد البيانات التي يتم حفظها بيانات ثنائية أي لو أنك حفظتها على ملف فإنه
ملف ثنائي …

والهدف الآن هو كيف تقوم أنت ببناء أسلوب أكثر ديناميكية في الإدخال والإخراج
للفئات التي قمت أنت بتصميمها …

خطوات العمل

1-      بناء الفئة

2-      التصريح عن الفئة ضمن metaType

3-      بناء معاملات الإدخال والإخراج

4-      تسجيل الفئة ضمن   meta type stream operators

أولا بناء الفئة:-

class A{

public:

A(){}

QString name;

qint32 age;

};

ثانيا التصريح عن الفئة ضمن metaType :-

Q_DECLARE_METATYPE(A);

ثالثا بناء معاملات الإدخال والإخراج :-

QDataStream &operator<<(QDataStream &out, const A &a){

out<<a.name<<(qint32)a.age;

return out;

}

QDataStream &operator>>(QDataStream &in, A &a){

in>>a.name>>a.age;

return in;

}

رابعا تسجيل الفئة ضمن   meta type stream operators :-

qRegisterMetaTypeStreamOperators<A>(“A”);

والآن أصبح بإمكانك القراءة والكتابة مع الفئة A بكل يسر وسهولة سواء مع الملفات او
القراءة والكتابة عبر الشبكة أو حتى كمتغير  .QByteArray

مثال شامل:-

#include <QtCore>

class A{

public:

A(){}

QString name;

qint32 age;

};

Q_DECLARE_METATYPE(A);

QDataStream &operator<<(QDataStream &out, const A &a){

out<<a.name<<(qint32)a.age;

return out;

}

QDataStream &operator>>(QDataStream &in, A &a){

in>>a.name>>a.age;

return in;

}

int main(int argc, char *argv[])

{

QCoreApplication app(argc, argv);

qRegisterMetaTypeStreamOperators<A>("A");

A from,to;

from.name="mohammed alabdaly";

from.age=20;

QByteArray ba;

QDataStream ds(&ba,QIODevice::WriteOnly);

QDataStream ds2(&ba,QIODevice::ReadOnly);

QMetaType::save(ds,qMetaTypeId<A>(),&from);//كتابة بيانات المتغير

QMetaType::load(ds2,qMetaTypeId<A>(),&to);//قراءة بيانات المتغير

qDebug()<<QObject::tr("%1,%2").arg(to.name).arg(to.age);

return app.exec();

1

وفي امان الله

                                          بسم الله الرحمن الرحيم

الفرز السريع Quicksort   

ü      لماذا أسلوب الفرز السريع؟

ü      التقسيم partitioning  .

ü      الاستدعاء الذاتي ( recursive ) من أجل الفرز السريع  .

ü      بعض طرق تعين محور التقسيم (pivot)  للحصول على فرز أسرع .

ü      الاستعانة بطرق فرز أخرى لتحسين أداء الفرز السريع.

 

لماذا أسلوب الفرز السريع ؟

      الترتيب بأسلوب الفرز السريع يعتبر الأكثر استخداما من جميع خوارزميات الفرز الأخرى لأنها الأسرع وأقل استهلاكا للذاكرة .

      إذ هي تتفوق على الفرز بأسلوب الفقاعة(bubble sort) و الفرز بأسلوب الإدخال(insertion sort) و الفرز بأسلوب الاختيار( selection sort )بالسرعة وتتميز عن الفرز بأسلوب الدمج (merge sort) بالسرعة وتوفيرها للذاكرة بالرغم من تفوق الأخير على نظرائه الثلاثة بالسرعة أيضا إلا انه يستهلك الذاكرة أكثر .

التقسيم partitioning :

يعتمد أسلوب  Quicksort على تقسيم المقسم وتجزئة المجزأ لعدة مرات حتى تحصل على ترتيب للعناصر داخل القائمة تصاعديا أو تنازليا.

التقسيم هنا هو تقسيم قائمة إلى جزأين أصغر وأكبر حيث هناك يكون مايسمى محور التقسيم (pivot ) وعليها يتم تحديد أصغر أو أكبر لا يشترط أن تكون عدد العناصر في كلا القسمين متساوية أو مرتبة ترتيبا تصاعديا أو تنازليا بل ما هو مهم في مرحلة التقسيم هو جعل الأصغر من محور التقسيم في قسم والأكبر في قسم آخر.

مثال على ذلك  تقسيم درجات الطلاب الحاصلين على أقل من 50 درجة والحاصلين على أكثر من 50 درجة حيث القيمة 50 هو محور التقسيم .

أحد أكثر الطرق نجاحا في التقسيم هي طريقة الأكبر يبدأ من اليمين باتجاه اليسار والأصغر يبدأ من اليسار باتجاه اليمين فلو كان لديك 5 عناصر من 0 إلى 4 الأكبر من محور التقسيم يبدأ من 4 ثم 3 ثم 2 …. , والأصغر يبدأ من 0 ثم 1 …. , حتى يلتقي مؤشر اليمين مع مؤشر اليسار هنا تنتهي عملية التقسيم .

مثال/ خمسة طلاب درجاتهم على التوالي 80 ثم 40 ثم 90 ثم 55 ثم 30 ومحور التقسيم 50 يتم التقسيم بالطريقة التالية …

30

55

90

40

80

اللون الأحمر هو الذي يتحرك من اليسار الى اليمين مع كل مرة يجد قيمة أصغر واللون الأخضر يتحرك من اليمين الى اليسار كلما وجد قيمة أكبر وسوف نبدأ باختبار القيم من اليمين الى اليسار …

80

55

90

40

30

القيمة 80 أكبر من 50 فلذلك نقلناها الى أقصى اليمين و العنصر فيأقصى اليمين أخذ مكانها وحركنا المؤشر الأخضر للعنصر التالي …

80

55

90

40

30

القيمة 30 أصغر من 50 فذلك لا حاجة لعملية استبدال أماكن فقط نقوم  بتحريك المؤشر الأحمر خطوة إلى اليمين وهو مايعني أننا سوف نختبر القيمة 40 في الخطوة التالية …

80

55

90

40

30

40 أصغر من 50 فلذلك نقوم بتحريك اللون الأحمر خطوة إلى اليمين لأحظ أنه لا يمكن الاستمرار لأن اللونين الأخضر والأحمر التقيا مما يعني ان عملية التقسيم انتهت فلو افترضنا أن القيمة عند اللون الأحمر أصغر فإن هذا لن يؤثر على التقسيم في حال الاستمرار وان كانت أكبر فأيضا ذلك لن يؤثر على التقسيم  في حال الاستمرار فكلما عالجنا الأمور بخطوات اقل كان ذلك أفضل …

لاحظ أن القيم أصغر من 50 تكون في اليسار والقيم الأكبر في اليمين .

ويمكن تمثيل الطريقة السابقة برمجيا بشفرة ++ c على الشكل التالي:-

 leftCurrentيعبر  عن اللون الأحمر و rightCurrent عن اللون لأخضر تتبع عمل الشيفرة على مثال   درجات الطلاب , ترجع الدالة partitioning رقم العنصر الذي يبدأ فيه الفصل بين الأصغر والأكبر 

فلو قمنا بتجربة مثال درجات الطلاب كما في الدالةmain 

نجد أن النتيجة تكون على الشكل التالي :-

 

والنتيجة مشابهة للتي حصلنا عليها يدويا …

 

الاستدعاء الذاتي ( recursive ) من أجل الفرز السريع  :

            كما ذكرنا سابقا يقوم الفرز السريع على تقسيم المقسم الى عدة مرات حتى نحصل على قائمة مرتبة تصاعديا أو تنازليا ويمكن تمثيل العملية هذه في c++ على الشكل التالي:-

لاحظ ان الوسيط الثالث وهو الذي يستقبل قيمة محور التقسيم pivot في الدالة partitioning  لم نضع مكانها شيئ في الحقيقة نحن لانعرف ماذا نضع مكانها ؟؟ في حال أردت وضع متوسط أعلى وأدنى قيمة فإن السرعة أنتفت عن هذا المثال للحاجة الى عمليات أكثر من الإسلوب ذاته .

بعض طرق تعين محور التقسيم (pivot ) للحصول على فرز أسرع :

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

 

 

 

 

 

 

 سوف يبدأ الاختبار من بعد أول عنصر (العنصر الثاني من اليسار) وأي عنصر أصغر منه يتم   استبدال موقع المحور مع موقعه حتى يكون موقع محور التقسيم في النهاية الأمر بين الأصغر من والأكبر من وترجع الدالة في النهاية موقع محور التقسيم …

نفس المثال السابق:

سوف نبدأ الإختبار من القيمة 80 وهي الثانية من اليسار والقيمة 50 هي محور التقسيم وموقعه أول القائمة  من اليسار.

 

30

55

90

40

80

50

80

55

90

40

30

50

80

55

90

40

50

30

80

55

90

50

40

30

80

90

55

50

40

30

لاحظ أن القيمة 50 تقع بين الأكبر من والأصغر من ويفيدنا هذا التقسيم في تقليص عدد الخطوات بحيث لا حاجة لأن ندخل المحور في عملية التقسيم مرة أخرى ولو طبقنا المثال السابق برمجيا فإننا نحصل على نفس الترتيب ..

إذا يمكن أيضا إعادة صياغة الدالة Quicksort  بطريقة أخرى :

 

 

 

إلى الآن لم نصل إلى الطريقة الأمثل لتحديد المحور من الأفضل أن تكون القيمة في الوسط بين أعلى وأصغر قيمة ولكن كما قلنا سابقا إن هذا الأسلوب يستخدم لزيادة السرعة  بهذا الأسلوب سوف تقل السرعة كثيرا…

 فلذا خرج لنا أسلوب أسرع وأنجع من سابقه وهو متوسط ثلاثة median of three حيث نختار ثلاثة عناصر وهي أول القائمة وآخر القائمة وعنصر وسط القائمة ثم نقوم بعملية ترتيب لهم الأصغر في اليسار والأكبر في اليمين والقيمة التي أصغر من الأكبر وأكبر من الأصغر يستبدل مع ثاني عنصر من اليسار حيث يكون هو المحور لماذا؟؟

لقد قلصنا بهذه الطريقة عدد العناصر الخاضعة لعملية التقسيم  حيث الأول والأخير لا يخضعان لعملية التقسيم لأنهم مقسمان سلفا أكبر وأصغر من المحور إذا سوف يكون المحور بعد استثناء الأطراف من التقسيم في الطرف الأيسر من القائمة حيث سوف يخضع لعملية التقسيم بطريقتنا السابقة …

مثال

30

55

90

40

80

90

55

40

80

30

القيمة 80 هي المحور و القيمتين 30 و 90 خارج عملية التقسيم …

وفي c++ نكتب الشفرة على الشكل التالي :

 

 

 

 

الاستعانة بطرق فرز أخرى لتحسين أداء الفرز السريع:

            قبل أن نبدأ ببناء فئة تقوم بجميع تلك الوضائف يجب أنن ننوه لموضوع مهم جدا وهو أن الطريقة السابقة يفضل إستخدامها مع قوائم طويلة إن هذا الأسلوب لن يؤثر على قائمة من عنصرين ستجد انهما غير مرتبين فإذا ما واجهت قائمة من عنصرين فلا تستخدم هذه الطريقة ويفضل أن تحدد في حال كانت العناصر في القائمة 10 أو أقل أن تستخدم أسلوب insertion sort

أما الآن فالفئة التي سوف نبنيها تعتمد بالكامل على أسلوب الفرز السريع ونستثني منها حال وجد عنصرين فإننا نرتبهم بأسلوب يدوي(تبديل الأماكن فيما بينهم إن لم يكونوا مرتبين)

انقر هنا لتحميل ملفات الشفرة المصدرية

وفي أمان الله

نوافذ شفافة                 

                        بسم الله الرحمن الرحيم

النوافذ الشبه شفافة في Qt :

انها أحد التقنيات الجديدة المقدمة في Qt4.5 والتي تسمح لك بإستخدام نمط التلوين RGBA لرسم النوافذ قبل هذا الإصدار كان لتحصل على نافذة شفافة على سطح المكتب يجب أن تستخدم الدالة setWindowOpacity

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

يمكنك تفعيل هذه الميزة عن طريق :

 استدعاء الدالة setAttribute مع الثابت Qt::WA_TranslucentBackground ويجب أيضا أن تكون النافذة بدون إطار حتى تتمكن من تفعيله وسوف نرى في المثال أنه كيف قمنا برسم دائرة شفافة RGBA على نافذة النظام مباشرة بأسطر برمجية  قليلة …

                                                 ملف widget.h

widget.h

لقد قمنا بالتعريف عن دالتين دالة البناء ودالة حدث الرسم على النافذة ويتم استدعاءها عند بدء البرنامج و أثناء الحاجة لذلك سوف نستعين بها لرسم رسومات  شفافة داخل النافذة…

 

                                              ملف widget.cpp

widget.cpp

 

السطر الثالث في الدالة قمنا بتهيئة النافذة بحيث تكون بلا إطار و تتعامل مع قائمة النظام (الإقفال والتصغير والتكبير …)                          

وفي السطر السابع قمنا بتفعيل الميزة Qt::WA_TranslucentBackground وفي السطر السادس عشر قمنا بإنشاء ألوان على نمط RGBA حيث القيمة A تعني الشفافية وقيمتها 100 و120 على التوالي من أصل 255   .               

     ملف main.cpp 

main.cpp

والسلام عليكم

 

بسم الله الرحمن الرحيم

 

Qt4.5

وأخيرا خرج لنا هذا الإصدار الذي هو يعتبر أفضل اصدار لمكتبة Qt والتي شملت تحسينات كثيرة اهمها:

 

تحسن في آداء وسرعة  المكتبة:

 حيث ان جميع الأجزاء الأساسية من Qt تم اعادة  هندستها للحصول على أداء ورسومات أكثر تطورا شمل محرك الرسم و تحسين تحوير النصوص بالإضافة ل تطوير إطار عمل   graphics Viewوتحسين أداء ورقة النمط .

يمكنك رؤية بعض التجارب من خلال الرابط التالي اضغط هنا .

 

منقح ل :QtScript

وهي عبارة عن وحدة تسمى QtScriptTools يتم ربطها مع QtScriptEngine لتتبع عمل ال script و ارسال تقارير عن وجود أخطاء ويمكن تضمين هذه النوافذ داخل التطبيقات  .

 

مزيد من الدعم للأنظمة:

تم اعادة كتابة    Qtلنظام mac os X بإستخدام Apple’s Cocoa API مما يجعل تطبقات Qt  تعمل على اجهزة ماكينتوش 64 bit .

ولنظام windows CE ابتداء من الإصدار السادس  تم استقطاب التحسينات من Qt4.4 و Qt4.5 اليها لتشمل إطار العمل phonon و  QtWebKit .

 

تحسينات رسومية :

يمكنك الأن إستخدام ورقة النمط على نمط mac os X .

أيضا بإمكانك الآن من إنشاء نافذة بها مناطق شبه شفافة على أنظمة تدعم التركيب على نوافذها وهي كل من X11 ونظام ويندوز ابتداء من الإصدار 2000 و ويمكن دعم هذه الخاصية بإستدعاء الدالة setAttribute  مع الثابت Qt::WA_TranslucentBackground .

وأيضا تم تطوير الفئة QGtkStyle التي تحاكي نمط GTK+ فيما اذا اردت انشاء تطبيق على GNOME .

 

بالإضافة الى ماسابق تم تطوير كلا من Qt Designer و Qt Linguist وأصبحت Qt webkit اداة متكاملة.

 

لمشاهدة التغييرات على الفئات في هذا الإصدار اضغط هنا

لمشاهدة المشاكل المعروفة الى الآن في هذا الإصدار اضغط هنا

 

الآن من وجهة نظر الموقع الرسمي هناك سبعة أسباب تجعلك تعمل على Qt دون غيرها من المكتبات :-

1-     أكتب الشيفرة مرة واحدة ويعمل في أي مكان .

2-     توفير التكلفة والوقت

3-     سرعة الحصول على فوائد اطار عمل واجهة المستخدم المتطورة .

4-     اصدار عقد,تطبيقات عالية الأداء .

5-     تعدد الرخص تجارية او LGPL او حتى GPL .

6-     الحصول على خدمات فنية والدعم والوثائق .

7-     الإشتراك في نظام بيئي نشط ل Qt .

لتنزيل المكتبة اضغط هنا .

 روابط مفيدة

        اعلان الخبر في وادي التقنية