‏إظهار الرسائل ذات التسميات كيوت Qt. إظهار كافة الرسائل
‏إظهار الرسائل ذات التسميات كيوت Qt. إظهار كافة الرسائل

فبراير 09، 2009

سلسلة البرمجة الرسومية بواسطة باي كيوت PyQt4 للمبتدئين 04

اليوم تنتهي رحلتنا مع الآلة الحاسبة حيث سنضيف اللمسات الأخيرة على الواجهة و الشفرة المصدرية.

بخصوص الواجهة الرسومية سنقوم بحدف الحقلين الأول و الثاني و ستصبح الواجهة كالتالي:



و الشفرة المصدرية أصبحت كالتالي:



import sys

from PyQt4 import QtGui, QtCore, uic

from functools import partial



class CalcDialog(QtGui.QDialog):



    iMathOp = 0

    fstValue = 0

    MathOps = " + ", " - ", " * ", " / "



    def __init__(self, *args):

        QtGui.QWidget.__init__(self, *args)

        uic.loadUi("PyCalc.ui", self)



        NumButtonsList = self.c0, self.c1, self.c2, self.c3, self.c4, self.c5, self.c6, self.c7, self.c8, self.c9

        for x in range(0, len(NumButtonsList)) :

            self.connect(NumButtonsList[x], QtCore.SIGNAL("clicked()"), partial(self.fAddNbr, str(x)))



        MathOpButtonsList = self.opplus, self.opminus, self.opmulti, self.opdiv

        for x in range(0, len(MathOpButtonsList)) :

            self.connect(MathOpButtonsList[x], QtCore.SIGNAL("clicked()"), partial(self.fEntrySwitch, x+1 ))



        self.connect(self.opequal, QtCore.SIGNAL("clicked()"), self.fCalculate)

        self.connect(self.opdot, QtCore.SIGNAL("clicked()"), self.fDecimal)

        self.connect(self.opclear, QtCore.SIGNAL("clicked()"), self.fClear)



    def fAddNbr(self, x):

        self.valresult.setText(self.valresult.text() + x)



    def fEntrySwitch(self, iMathOp):

        self.iMathOp = iMathOp

        self.fstValue = float(self.valresult.text())

        self.valresult.setText('')



    def fDecimal(self):

        x = str(self.valresult.text())

        if x.find('.') == -1:

            self.valresult.setText(self.valresult.text() + '.')



    def fCalculate(self):

        if self.iMathOp >0:

            rCalc = eval("self.fstValue" + self.MathOps[self.iMathOp-1] +  "float(self.valresult.text())")

            self.valresult.setText(str(rCalc))



        self.iMathOp = 0



    def fClear(self):

        self.iMathOp = 0

        self.fstValue = 0

        self.valresult.setText('')



if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)



    widget = CalcDialog()

    widget.show()

    sys.exit(app.exec_())




الآن سأشرح التغييرات التي طرأت على الشفرة المصدرية:

أولا، لاحظنا في الشفرة المصدرية السابقة (التدوينة الثالثة) أن هنالك عشرة أسطر متعلقة بربط الأزرار بالدالة fAddNbr متشابهة في كل شيء إلا العدد الذي نمرره فكل مرة للدالة.

للتخلص من تلك الأسطر يمكن وضع كل أسماء الأزرار في قائمة، ثم المرور على كل واحد منها بإستخدام حلقة و تنفيد أمر ربط الزر بدالة fAddNbr

 نفس الشيء فعلناه بالنسبة لأزرار العمليات الحسابية.

ثانيا، أصبحت الدالة fAddNbr تقوم بشيء واحد وهو إضافة العدد الجديد إلى العدد المتواجد في الحقل.

ثالثا، قمنا بتعديل دالة fEntrySwitch بحيث إستغنينا عن المتغيرة bSwitch و أضفنا سطر جديد يسمح بالإحتفاض بالعدد الأول في المتغيرة fstValue

رابعا، قمنا بتحديث دالة fDecimal حتى تتمشى مع الوضع الجديد و هو وجود حقل واحد بدلا من إثنين.

خامسا، وقع لدالة fCalculate تغيير مهم و هو كل العمليات الحسابية يتم معالجتها بسطر واحد فقط. بحيث إستخدمنا دالة eval التي تقوم بتقيم العمليات الحسابية من نص إلى قيمة عددية.
فمثلا إن كتبنا "6 * 3" محتفظين بعلامتي "" فنقصد من ذلك أن هذا نصا و ليس عددا، لكن بايثون يتوفر على دالة إسمها eval تستطيع فهم و تقييم ما كتب في ذلك النص و إظهار النتيجة الحسابية.

سادسا تم تحديث دالة fClear حتى تقوم بمسح كل القيم. يضا تمت إعادة تسمية القسم من CalcApp إلى CalcDialog

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

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

و إن كنت تعتقد أنك لن تستطيع البرمجة ببايثون و كيوت يمكن تجربة KBasic أو Gambas إن كانت لك خلفية في VB أو Lazarus إن كنت من مبرمجي Delphi/Pascal. المهم هو أن لينوكس غني بلغات البرمجة و أدواتها.


بالنسبة للمتقدمين في البرمجة في PyQt4 هل هنالك أية ملاحظات أو تحسينات يمكن إضافتها على الشفرة المصدرية؟

تحديث 1 (14-04-2009): يمكن تحميل الشفرة المصدرية من هنا.

فبراير 07، 2009

سلسلة البرمجة الرسومية بواسطة باي كيوت PyQt4 للمبتدئين 03

هدفنا هو أن نجعل الأعداد التي ستكتب في كل من الحقل الأول و الثاني تظهر كنتيجة في الحقل الثالث بعد القيام بالعملية الحسابية المطلوبة.

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

أولا يجب علينا أن نتصور الطريقة التي يمكن من خلالها التعبير على عدد ما، مثل 125.
إحدى هذه الطرق هي (1x100) + (2x10) + (5x1)
 أو
القيمة السابقة مضروبة في 10 + العدد الجديد. مثال: X=(X*10) + y 
او
أن نعتبر أن كل رقم بمثابة نص يتم إضافته في أخر السطر للقيمة السابقة، مثال: "1"+"2" النتيجة ستكون هي "21"

سأعتمد على الطريقة الأخيرة لبساطتها.

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


الآن سأحاول أن أوضح لكم كيف سيعمل البرنامج بلغة نفهمها نحن ثم بعدها نحولها إلى لغة بايثون:
1. ستظهر الواجهة الرسومية البرنامج.
2. بعدها سيقوم المستخدم بكتابة العدد 935.
3. في كل مرة يتم الضغط على زر ما، يجب عليه أن يقرر في أي حقل (الأول أم الثاني) سيقوم بإضافة العدد الذي عبر عنه إلى العدد المكتوب مسبقا. مثلا إضافة "5" إلى "93"
4. بعد ذلك سيقوم المستخدم بعملية الجمع +
5. تتكرر نفس العملية بالنسبة للعدد الثاني تماما كما في الخطوة الثالثة.
6. عندما يضغط المستخدم على زر = يجب إجراء العملية الحسابية المطلوبة بحيث سيستخدم البرنامج القيمة المتواجدة في الحقل الأول و الثاني ثم يقرر أي نوع من العمليات الحسابية سيقوم بها، ثم يظهر النتيجة في الحقل الثالث.


قبل أن أكتب الشفرة المصدرية سأدكر بأن الأزرار التي تعبر عن 0 حتى 9 إسمها c0 إلى c9
أزرار العمليات الرياضية:
+ opplus
- opminus
* opmulti
/ opdiv
زر = إسمه opequal
زر الفاصلة . opdot
زر المسح opclear
الحقل الأول إسمه value1، الحقل الثاني value2، حقل النتيجة valresult

الشفرة المصدرية للبرنامج هي:




import sys

from PyQt4 import QtGui, QtCore, uic

from functools import partial



class CalcApp(QtGui.QDialog):



    bSwitch = False

    iMathOp = 0



    def __init__(self, *args):

        QtGui.QWidget.__init__(self, *args)

        uic.loadUi("PyCalc.ui", self)



        self.connect(self.c0, QtCore.SIGNAL("clicked()"), partial(self.fAddNbr, '0'))

        self.connect(self.c1, QtCore.SIGNAL("clicked()"), partial(self.fAddNbr, '1'))

        self.connect(self.c2, QtCore.SIGNAL("clicked()"), partial(self.fAddNbr, '2'))

        self.connect(self.c3, QtCore.SIGNAL("clicked()"), partial(self.fAddNbr, '3'))

        self.connect(self.c4, QtCore.SIGNAL("clicked()"), partial(self.fAddNbr, '4'))

        self.connect(self.c5, QtCore.SIGNAL("clicked()"), partial(self.fAddNbr, '5'))

        self.connect(self.c6, QtCore.SIGNAL("clicked()"), partial(self.fAddNbr, '6'))

        self.connect(self.c7, QtCore.SIGNAL("clicked()"), partial(self.fAddNbr, '7'))

        self.connect(self.c8, QtCore.SIGNAL("clicked()"), partial(self.fAddNbr, '8'))

        self.connect(self.c9, QtCore.SIGNAL("clicked()"), partial(self.fAddNbr, '9'))



        self.connect(self.opplus, QtCore.SIGNAL("clicked()"), partial(self.fEntrySwitch, True, 1))

        self.connect(self.opminus, QtCore.SIGNAL("clicked()"), partial(self.fEntrySwitch, True, 2))

        self.connect(self.opmulti, QtCore.SIGNAL("clicked()"), partial(self.fEntrySwitch, True, 3))

        self.connect(self.opdiv, QtCore.SIGNAL("clicked()"), partial(self.fEntrySwitch, True, 4))



        self.connect(self.opequal, QtCore.SIGNAL("clicked()"), self.fCalculate)



        self.connect(self.opdot, QtCore.SIGNAL("clicked()"), self.fDecimal)



        self.connect(self.opclear, QtCore.SIGNAL("clicked()"), self.fClear)





    def fAddNbr(self, x):

        if self.bSwitch == False:

            self.value1.setText(self.value1.text() + x)

        else:

            self.value2.setText(self.value2.text() + x)





    def fEntrySwitch(self, bSwitch,  iMathOp):

        self.bSwitch = bSwitch

        self.iMathOp = iMathOp





    def fDecimal(self):

        if self.bSwitch == False:

            x = str(self.value1.text())

            v = self.value1

        else:

            x = str(self.value2.text())

            v = self.value2



        if x.find('.') == -1:

            v.setText(v.text() + '.')





    def fCalculate(self):

        if self.iMathOp == 1 :

            rCalc = float(self.value1.text()) + float(self.value2.text())

        elif self.iMathOp == 2:

            rCalc = float(self.value1.text()) - float(self.value2.text())

        elif self.iMathOp == 3:

            rCalc = float(self.value1.text()) * float(self.value2.text())

        elif self.iMathOp == 4:

            rCalc = float(self.value1.text()) / float(self.value2.text())

        else:

            return None



        self.valresult.setText(str(rCalc))





    def fClear(self):

        self.bSwitch = False

        self.iMathOp = 0

        self.value1.setText('')

        self.value2.setText('')

        self.valresult.setText('')





if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)



    widget = CalcApp()

    widget.show()



    sys.exit(app.exec_())





بالنسبة للتغيرات التي حصلت فهي كالتالي:
1. تم إستيراد دالة partial من قسم functools. سيتم الإستعانة بهذه الدالة لربط بين الدوال التي سنضيفها نحن و بين الأحداث (الضغط على الأزرار)
2. تم الإستعانة بمتغيرتين bSwitch التي سنستخدمها لتحديد الحقل الذي سيكتب فيه العدد، و iMathOp لتحديد نوع العملية الحسابية المطلوبة.
3. تم إضافة دالة fAddNbr لتقوم بمهمة إضافة العدد الذي ضغط عليه المستخدم إلى العدد الموجود سابقا، و هذه الدالة قادرة على معرفة أي حقل ستستخدم إعتمادا على متغيرة bSwitch
4. تم إضافة دالة fEntrySwitch التي ستقوم بتغير قيمة المتغيرة bSwitch إلى قيمة صحيح أو خطأ و  بتغير قيمة iMathOp إلى قيمة عددية من 1 إلى 4
5. دالة fCalculate التي ستقوم بمعرفة العملية الحسابية المطلوبة إعتمادا على قيمة المتغيرة iMathOp ثم تقوم بإجرائها على قيمة الحقل الأول و الثاني، ثم تضع النتيجة في الحقل الثالث.
6. دالة fClear التي تقوم بمسح محتوى الحقول و تغير قيمة المتغيرتين إلى القيمة المفترضة.
7. دالة fDecimal وظيفتها هو إضافة الفاصلة إلى العدد المتواجد في الحقل الأول أو الثاني، ثم التأكد من عدم إسناد أكثر من فاصلة واحدة إلى نفس العدد.
8. عودة إلى الدالة __init__ و التي سيتم تعديلها حتى تقوم:
8.1. بربط كل زر من أزرار الأعداد بدالة fAddNbr و بالتالي نحصل على وظيفة كتابة الأعداد في الحقلين الأول و الثاني.
8.2. بربط كل زر من أزرار العمليات الحسابية بدالة fEntrySwitch و بالتالي يستشعر البرنامج تغير قيمة المتغيرتين bSwitch و iMathOp
8.3. ربط زر يساوي = بدالة fCalculate التي ستتكلف بحساب النتيجة و وضعها في الحقل الثالث.
8.4. ربط زر الفاصلة بدالة fDecimal التي خصصناها إلى التحكم في الفاصلة.
8.5. ربط زر المسح C بدالة fClear لمسح و إعادة القيم في الحقول و المتغيرتين إلى القيم المفترضة

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

يالنسبة للأصدقاء الأكثر خبرة في PyQt4 هل لذيكم أي ملاحظة على الطريقة التي إعتمدتها و الشفرة المصدرية التي كتبتها؟

تحديث 1 (14-04-2009): يمكن تحميل الشفرة المصدرية من هنا.

يناير 30، 2009

سلسلة البرمجة الرسومية بواسطة باي كيوت PyQt4 للمبتدئين 02

في أول تدوينة قمنا بإنشاء الواجهة الرسومية لآلتنا الحاسبة بإستخدام Qt Designer (مصمم الواجهات لـ كيوت) ثم قمنا بحفضها تحت إسم PyCalc.ui

إن قمت بفتح ملف الواجهة بواسطة notepad مثلا سترى أن الواجهة حفظت على شكل نصي تراتبي.

لإستخدام تلك الواجهة مع بايثون هنالك طريقتين على حد علمي:
1. القيام بعملية تحويل (compiling) لملف الواجهة حتى يصبح قابل للإستخدام مع بايثون.
2. إستخدام و ربط ملف الواجهة بطريقة ديناميكية. و أنا سأستخدم هذه الأخيرة للمرونتها.

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

أولا، خصص مجلد خاص بالعمل تضع فيه ملف PyCalc.ui و باقي الملفات التي سنظيفها لحقا داخله.

ثانيا يجب أن تنتبه إلى الطريقة التي كتبت بها الشفرة المصدرية Source Code خصوصا الفرق بين الحروف الصغيرة و الكبيرة (q ليست Q) و الفرق بين النقطة (.) و الفاصلة (,)
أيضا يجب عليك أن تفهم أن بايثون يستخدم مفتاح (tab) للتمييز بين أجزاء الشفرة على عكس اللغات الأخرى التي قد تستخدم {} أو begin و end


من هنا تبدأ الرحلة (لا تنسى أن تضع قطعة شوكلاتة في فمك قبل أن تبدأ) :)

سيكون هذفنا هو ربط واجهة الآلة الحاسبة مع بايثون و إظهارها للمستخدم.

1. قم بتشغيل محرر IDLE الذي تم تثبيته مع بايثون و قم بتحرير ملف جديد File->New Window

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

سنحتاج في هذه المرحلة إلى وحدة sys و PyQt4 (لاحظ الفرق في الكتابة بين الحروف الصغيرة و الكبيرة)

من أجل ذلك سنقوم بعملية الإستراد لهذه الوحدات بواسطة

import sys
from PyQt4 import QtCore, QtGui, uic


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

نعم، هذه الطريقة موجودة و تسمى بالأقسام بحيث نعتبر برنامجنا كقسم يمكن إستخدامه في برانامج آخر، و الذي قد يصبح قسم في برنامج آخر ذات يوم. هذا النوع من البرمجة يسمى بالبرمجة الموجهة نحو أو المعتمدة على الكائنات (Object-Oriented Programming) أو (OOP)

مفهوم الأقسام أكبر من الشرح الذي قدمته لكن هذا كل ما نحتاج إلى معرفته الآن.

ستكون الشفرة المصدرية كما يلي:
class CalcApp(QtGui.QDialog):
    def __init__(self, *args):
        QtGui.QWidget.__init__(self, *args)
        uic.loadUi("PyCalc.ui", self)

بحيث نعتبر أن برنامج الآلة الحاسبة سيكون قسم تحت إسم CalcApp (السطر 1) و الذي سيقوم بتحميل ملف الواجهة الرسومية PyCalc.ui (السطر 4) فور تشغيل القسم. بالنسبة للسطر 2 و 3 يمكن إعتبارها صالحة للإستعداد المبدئي لعرض الواجهة و تهيئة البرنامج لذلك.

غير أن قسم CalcApp لا يعمل من تلقاء نفسه بل يحتاج لمن يستدعيه حتى يعمل و هذا ما سنراه بعد قليل.

إذا قلنا أنه يتم الإستعداد للتهيئة و بدأ برنامج أو قسم ما، فهنا يمكن أن نفهم أنه يجب تحديد إسم القسم الذي نريد أن نهيئه. فماذا إن كنا نريد أن نهيئ نفس القسم الذي نعمل عليه؟ هنا نستخدم كلمة self للتعبير عن القسم الذي نعمل عليه، بحيث يغنينا هذا عن ذكر الإسم كل مرة و نكتفي بدكر self=نفسك.

و كيف بعدها نميز بين الشفرة المصدرية التي ستتكلف بإعداد/تهيئة القسم عن باقي الشفرة المصدرية التي سنضيفها لحقا؟ لهذا وجدة __init__ التي يتم إستخدامها لتهية الأقسام.

كما سبق و أن أشرنا أنه من الممكن أن يحتوي قسم على قسم أخر عندما قدمنا مثال برنامج المحاسبة الذي يستخدم الآلة الحاسبة لإجراء عملية حسابية ما. فكيف ننادي على قسم الآلة الحاسبة لإجراء حساب معين و نحن نعمل أو متواجدين في برنامج المحاسبة؟ للقيام بدلك نستخدم رمز (.) النقطة للفصل بين الأقسام مثل QtGui.QWidget.__init__ بحيث نستدعي __init__ التي تتواجد بقسم QWidget الذي بدوره يتواجد بقسم QtGui

جيد، الآن حان الوقت لكتابة الشفرة المصدرية المسؤولة عن إستدعاء قسم CalcApp ثم إظهار الواجهة الرسومية للآلة الحاسبة. ستكون الشفرة على ما يلي:

app = QtGui.QApplication(sys.argv)

widget = CalcApp()
widget.show()

sys.exit(app.exec_())


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

سيكون شكل الشفرة المصدرية عند الإنتهاء على هذا الشكل:

import sys
from PyQt4 import QtCore, QtGui, uic

class CalcApp(QtGui.QDialog):
    def __init__(self, *args):
        QtGui.QWidget.__init__(self, *args)
        uic.loadUi("PyCalc.ui", self)


app = QtGui.QApplication(sys.argv)

widget = CalcApp()
widget.show()

sys.exit(app.exec_())

قم بحفظه تحت إسم PyCalc.py ثم قم بتشغيله من خلال قائمة run->run module أو بالضغط مباشرة على مفتاح F5.
بالتوفيق :)

يناير 23، 2009

سلسلة البرمجة الرسومية بواسطة باي كيوت PyQt4 للمبتدئين

هل سبق لك و أن برمجت من قبل أو أردت أن تجرب البرمجة، هل كنت من مبرمجي ويندوز و إستصعب عليك الأمر عندما جربت أو إنتقلت إلى جنو/لينوكس. لا تقلق، لست وحدك من يفكر هكذا.

سنختار لغة بايثون (Python) و مكتبة واجهة باي كيوت (PyQt) الرسومية لإنشاء آلة حاسبة.
إختياري مبني على كون بايثون سهل و مرن و لأن واجهة كيوت غنية، و أهم من هذا كله لكونهما متوفرين على كل المنصات تقريبا بما في ذلك بعض أجهزة الهاتف النقال و المساعدات الذكية.

إن كنت من مستخدمي جنو/لينوكس إستخدم مدير الحزم لتثبيت PyQt ، Qt، و محرر IDLE، أما بالنسبة لبايثون فأغلب الظن أنه مثبت مسبقا.

و إن كنت من مستخدمي ويندوز فقم بتحمل بايثون من هنا و باي كيوت من هنا.

في الوقت الذي تنتظر فيه إنتهاء التحميل، أفضل أن تحظر مشروبك المنبه المفضل لذيك أو تضع قطعة أو قطعتين من الشوكلاتة في فمك.

هنالك ملاحظة بسيطة و هي أن بايثون 2.6 و مكتبة PyQt المتوافقة معها يحصلان على تحديثات تصحيحية دورية بإستمرار لذلك إن أصبح رابط التحميل لا يعمل يكفي أن تزور صفحة التحميل لكل من بايثون و باي كيوت و تقوم بتحميلهما.

بعد التحميل، قم بتثبيت بايثون أولا ثم باي كيوت ثانيا.

جيد، إسترح قليلا فأنا أعرف أنك لا تعرف شيئا عنهما و لا حتى أنا، إلا بعض المفاهيم المبدئية. سنتعلم معا :)

1. بعد الإنتهاء من التثبيت قم بتشغيل Qt Designer و اختر إنشاء Dialog without Buttons، بعدها ستحصل على واجهة رسومية فارغة.


2. قم بسحب Line Edit فوق الواجهة، ثم قم بتغير خاصية الإسم objectName إلى value1 من خلال شريط/نافدة Property Editor كما في الصورة.

ملاحظة سريعة: Line Edit و كل الأشكال المتواجدة فوق Qt Designer تسمى في معجم المبرمجين بالكائنات أو كائن، و في باي كيوت تحديدا يسمى ب وِيجِدْ (Widget). لتسهيل هذه التدوينة سنسمي هذه الأشكال بالكائنات الرسومية.


3. الآن سنضيف كائنين رسوميين من نوع Line Edit على الواجهة، تماما مثلما في الصورة. ثم نسمي الثاني ب value2 في خاصية objectName و الثالث ب valresult في objectName كذلك.


الآن، من سيستخدم هذه الآلة الحاسبة؟ أنت أو أي مستخدم آخر. إذا فكيف له أن يعرف مالذي يجب أن يُكتب في السطر الأول و الثاني و الثالث؟ علينا بتقديم لفتة إلى المعلومة/مات المراد إدخالها.

4. من أجل ذلك يوجد كائن رسومي إسمه Label، قم سحب Label على الواجهة و كرر ذلك بالنسبة لكل سطر (صندوق تحرير) مثلما في الصورة.


5. الآن لا نرى مكتوبا إلى TextLabel و هذا ليفيد المستخدم بشيء. علينا كتابة نص دو معنى. لفعل ذلك قم بتغير خاصية text من شريط/نافدة Property Editor. النص الأول سيكون First Value و الثاني Second Value و الثالث Result، تماما كما في الصورة.


6. حان الوقت لإضافة الأزرار. قم سحب الكائن الرسومي Push Button على الواجهة. ثم قم بتغير إسمه من خلال خاصية objectName إلى c0. ثم بعد ذلك تغيير النص الذي يظهر للمستخدم من خلال خاصية text تماما كما في الصورة.


إن تساءلت كيف غيرت شكله إلى مربع، فما عليك إلا تمديده من خلال المربعات الصغيرة التي تظهر عند الجوانب بعد تحديد الزر بنقرة (mouse click)

7. ستكرر نفس العملية بالنسبة لباقي الأزرار التسع. حيث ستضيف الزر، ثم تغير إسم الكائن إلى c1, c2 و هكذا، ثم تغير نص كل زر إلى الرقم الذي يعبر عنه مثلا c1 مع 1 و c2 مع 2 و هكذا. ستكون النتيجة كما في الصورة التالية.


8. الآن سنضيف أزرار للوظائف. بحيث سنضيف:
زر ل "يساوي"، خاصية text هي = و خاصية objectName هي opequal
زر ل "الجمع"، خاصية text هي + و خاصية objectName هي opplus
زر ل "الطرح"، خاصية text هي - و خاصية objectName هي opminus
زر ل "الضرب"، خاصية text هي x و خاصية objectName هي opmulti
زر ل "القسمة"، خاصية text هي / و خاصية objectName هي opdiv
زر ل "الفاصلة"، خاصية text هي . و خاصية objectName هي opdot
زر ل "المسح"، خاصية text هي C و خاصية objectName هي opclear

تماما مثلما في الصورة.


إنتهينا من تصميم الواجهة الرسومية لآلتنا الحاسبة، الآن قم بحفظ الواجهة تحت إسم PyCalc.ui و سأكمل في تدوينة لاحقة.

ديسمبر 13، 2008

Eric 4 من أحسن المحررات للبرمجة بلغة بايثون Python و كيوت Qt

إنتهيت مؤخرا من تجربة العديد من محررات و بيئات التطوير المتكاملة Integrated Development Environment باحثا عن برنامج يساعدني على البرمجة بلغة بايثون Python.

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

البرامج التي جربتها على مدى أسبوعين كانت SciTE، Kate، Gedit، Geany، Komodo IDE، Eclipse/Aptana PyDev و Eric4.

وقع الإختيار في البداية على Eclipse/Aptana PyDev لأنه وفر خاصية تكملة الشفرة و اكتشاف و إصلاح الأخطاء بطريقة تلقائية. أعجبني لأنه وفر أغلب ما كنت أبحث عنه، لكن ما جعلني أبحث عن بديل هو أن إضافة PyDev لا تشمل بعض الخصيات لوجود إصدار أخر يحتوي كل شيء و يحتاج إلى شراء رخصة. الشيء الأخر هو أنني لم أستطيع إعداده لتوفير خاصية إكمال الشقرة بالنسبة لمكتبة PyQt.


لم يبقى أمامي غير Eric 4 الذي سبق و أن جربته و لم يشدني إليه لأنه يحتاج إلى تخصيص العديد من الإعدادات حتى يلائم إحتياجي. لكن لم يبقا لي خيار أخر. إليكم الصعوبة التي أخدت مني وقت طويل حتي أجعل Eric4 يقدم خاصية تكملة الشفرة بشكل كامل:
في Preferences->Editor->APIs عليك بتحديد ملفات ال API التي تريد من Eric الإعتماد عليها لتكملة الشفرة. أهم ملفين هما PyQt4.API و Python-2.6.API (متواجدين في أمكنة مختلفة حسب توزيعة جنو/لينوكس التي تستخدم) ثم بعدها عليك الضغط على زر Compile APIs.


بعد ذلك قمت بتغير الألوان المعتمدة في تلوين الشفرة و التي كانت تشبه الألوان المعتمدة في ويندوز Windows 95 و أنا لا أريد تذكر مثل تلك الذكريات في كل مرة أستخدم فيها Eric :)

بعد إجراء بعض التخصيصات الإضافية حصلت على محرر بالمواصفات التي كنت أبحث عنها و أكثر من ذلك. و يبقا محرر TextMate على منصة Mac OS X أقوى برنامج عرفته لحد الساعة.

هل يجود محرر أخر يقدم مثلما بحثت عنه؟