بسم الله الرحمن الرحيم
اخي العزيز السلام علكم ورحمة الله وبركاته
ان هذا المقال يتكون من شقين الأول للتعرف على معايير لغة ecmascript والثاني للربط بين ecmascript و Qt في حال انك اتقنت اساسيات javascript او jscript او حتى actionscript فبإمكانك الإنتقال الى الشق الثاني من المقال وانصحك بقراءة ملخص ecmascript لكي لاتجع مجالا لعدم الفهم وفي حال انك اردت تطبيق هذه اللغة فبإستطاعتك تحميل المحرر التعليمي من خلال هذا الرابط http://www.ecmascript.org/download.php ويتوفر على انظمة الوندوز واللينوكس وال mac .
قبل ان نتعرف على ECMAScript فإنه من المنطق أن نعرف ماذا يعني scripting language ؟
لغة برمجة نصية تتحكم بالتطبيقات وغالبا ما يتم تسميتها بأسماء تختلف عن برامجها مثل actionscript وبرنامجه الفلاش وكلاهم مكتوبين بلغتين مختلفة وهي في الغالب تكون في يد المستخدم النهائي لكي يتحكم بشكل او بمخرجات البرنامج .
الآن دعنا نرجع الى لغة ecmascript وهي لغة برمجة كائنية التوجه ،،
ولقد برمجت في الأصل لتكون web script language لتقوم بتزويدها بآلية لتنشيط الويب وهذا مابدا جليا في لغات انبثقت منها مثل javascript(mozila) و jscript(microsoft) و actionscript(adobe) ولكن تطورت فيما بعد لتدخل في كل شيئ ولكن ضمن بيئتها او برنامجها وهي الآن تعتمد في محارفها على معايير unicode ابتداء من النسخة 2.1 وما تلاها من نسخ ،وهي لغة تنفذ عمليات حسابية ومعالجة ضمن بيئة عملها ( برنامجها) ففي actionscript مثل هي تنفذ ضمن بيئة الفلاش وكذلك في javascript هي تنفذ ضمن بيئة المتصفح fireFox فالفكرة هنا انه كيف بالإمكان ان تقوم بربط الكائنات من لغة برمجة أخرى مثلا c++(Qt) بلغة ecmascript .
دعنا الآن نترك تقنية Qt على جانب ونعرف ماهي معايير لغة ecmascript التي جعلت البرامج الأخرى تنشد نحوها كلغة برمجة لبيئتها .
في حال انك تعاملت مع لغات مثل javascript او غيرها ستكون مدركا لمذا التدافع على ecmascript كخيار أول لتطوير لغات برمجة لبيئات بحيث تصبح وسيلة تطوير هذا البرنامج او البيئة هي اللغة التي قمت انت بصناعتها بواسطة ecmascript التي هي بالنسبة لمبرمجي c++ ابن بار لها لأنها ببساطة تكتسب تعابيرها الرياضية والشرطية والتكرارية وووو من لغة c++ فلذلك دعنا نأخذ جولة على مابهذه اللغة :
تعاريف :
المتغيرات : وهي حاويات للقيم وتنطبق عليها نفس شروط التسمية التي تنطبق على c++ وتتأثر لحالة الحرف ولكن مايميزها هو انها لا تطلب منك تحدد نوع المتغير بل بإمكانك جعل متغير واحد يحوي قيم مختلفة ويمكنك اضافة قبلها الكلمة المفتاحية var في حال كان المتغير خاصا .
القيم والأنواع: الأرقام وتشمل العشرية منها والصحيحة بالإضافة الى NaN وهو ماليس برقم والقيم البولينية و النصية التي اما ان تكون بين علامتي تنصيص ثنائية او بين علامتي تنصيص مفردة "" او ' ' واللاشيئ Null في حال انك لم تنشئ المتغير بالإضافة القيمة الغير المحددة undefined اي انه تم انشاء متغيره ولكن لم تحدد له قيمة والنوع هو Object وسوف نفرد له حديثا آخر وبالإضافة الى الأنواع السابقة هناك الدوال function و المصفوفات array وجميعها سوف نأتي على ذكرها .
الكائنات : في ecmascript فإن الكائنات هي عبارة عن خواص ( متغيرات) و طرق(دوال) وسوف نأتي في تفصيلها اكثر.
المعاملات :
الفاصلة المنقطة ";" وتعني نهاية جملة برمجة وكن في ecmascript فليس هناك من داعي لوضعها
المعاملات الرياضية :
+ للجمع و – للطرح و * للضرب و / للقسمة و % لباقي القسمة و ++ لإضافة واحد و – لإنقاص واحد
المعاملات المحرفية :
+ للجمع بين نصين او نص ورقم و بالإضافة الى سلاسل الهروب .
المعاملات الشرطية :
هناك كلمات مفتاحية متعارفة لدى مبرمجي اللغات الأخرى
الشرط if(){} و elseif(){} و else{}
و لكنها تختلف عن ما عهدناه في لغة c++ ان عامل المقارنة == يختبر المساواة بين القيم بغض النظر عن الأنواع .
فمثلا 12=="12" هذه القيمة true ولكن في حال انك كتبت 12=== "12" فإن هذه القيمة خاطئة فثلاث علامات = تعني المساواة المطلقة في النوع و القيمة بالإضافة الى المعاملات المنطقية || و && و ! .
المتغيرات العامة والمحلية والثابتة
المتغيرات الخاصة
Var m
المتغيرات العامة
M
ويستخدم الأول في حال انك انشأت دالة واردت تجنب استخدام المتغيرات العامة حفاظا على سلامة المتغيرات خارج الدالة فمثلا
N=12
Function r(){
N=0
}
R()
Print(n);الناتج : 0
بينما
N=12
Function r(){
Var N=0
}
R()
Print(n);الناتج: 12
المتغيرات الثابتة ويتم تعريفها بواسطة الكلمة المفتاحية const في حال انك عرفت متغير ثابت فإن قيمته المبدئية تبقى هي قيمته ولايمكن تغييرها
مثاله
Const m=12 m=1 print(m) الناتج = 12 .
الدوال :
بإستخدام الكلمة المفاحية function بإمكانك صنع الدوال ولإرجاع قيمها بواسطة الكلمة المفتاحية return وليس هناك تحديد لنوع المخرجات كما تآلفنا مع لغة c .
أمثلة :
f = function(p){print(p)}
f("mohammed")الناتج : mohammed .
او بطريقة أخرى :
Function f(p){print(p)}
f("mohammed")الناتج:mohammed .
المصفوفات :
وتكون عبارة عن قوسين [] بينهم قيم تفصل بينها فواصل "," ويأخذ اول عنصر التصنيف 0
مثاله :
a=[1,2,3,[1,2,3]] Print(a[1]) Print(a[3][0])
الناتج :
2
1
في حال اردت حذف قيمة من المصفوفة فإنه بالإمكان فعل ذلك بإستخدام الكلمة المفتاحية delete لتصبح القيمة undfined مثالها delete a[0] ويعيد القيمة true في حال نجح .
الإستثناءات :
وهي عبارة عن ثلاث كلمات مفتاحية try و catch و throw وقد تم دعمها في ecmascript ابتداء من النسخة الثانية
وصيغتها
Try{statement}
Catch(errorvar){statement}ف try تقوم بعمل مابداخلها والإستمرار في حال القاء استثناء تقوم بالإنتقال مباشرة الى الجملة catch الذي يقوم بمعالجة الإستثناء ويحتوي على متغير يقوم بتلقي جملة الإستثناء الملقاة عبر الكلمة المفتاحية throw بصيغتها
Throw expressin
ومثال عليها
Function test(n){
Try{
If(n==0) throw "mohammed"
}
Catch(a){
Print(a);
}
}
Test(0);الناتج mohammed .
الجملة switch والكلمات المفتاحية case و default
وهي معروفة لدى أغلب لغات البرمجة فلذلك سوف نكتفي بصيغتها
Switch(var){
Case value1:
Statements1
Break
Case value2:
Statements2
Break
Default:
Statements3
}يتم مقارنة كل قيمة موجودة في case بالقيمة المتواجدة في switch في حال تساوي أي من القيم فإنه يتم تنفيذ جملتها والا يتم تنفيذ جملة default .
جملة الشرط الثلاثي
وصيغتها
(condition)?value1:value2
في حال كان مابداخل القوسين جملة صحيحة فإنه يتم ارجاع قيمة value1 والا فإنه يتم ارجاع قيمة value2
ومثاله
l=12 r=(l<10)?1:2 print(r)
الناتج
2
جمل التكرار for و while و do-while
For
تفيد في تنفيذ مجموعة من الجمل حتى يصبح شرطها في وسيطها الثاني غير صحيح ومثال على صيغتها
For(var=1;var<10;var++){statement}While
في حال انتفى الشرط في وسيطها الوحيد يتم ايقاف عملية التكرار
While(condition){statement}Do – while
يتم تنفيذ مابداخل do بشكل متكرر الى ان ينتفي الشرط في وسيط while الوحيد وصيغتها
Do{statement}
While(condition)الجملتين continue و break
وهي تستخدم داخل جمل التكرار والشرط فالأول يكمل جملة التكرار وهي تنهي جملة statement التي يجري تنفيذها الآن بينما break ينهي من جملة التكرار .
عناوين الجمل label
وهدفها وضع عناوين للجمل ليمكنك التنقل بين هذه الجمل بإستخدام جمل break و continue
وصيغتها
Mylabel:statement Break mylabel
الكلمة المفتاحية typeof
وتعيد نوع البيانات على شكل نص
وصيغتها
Typeof var
مثالها
N=12 Print(typeof N)
الناتج number
الكائنات
كما ذكرنا مسبقا فإن الكائنات عبارة عن صفات وطرق وهي مشابهة في طريقة بنائها للدوال ولكي تضيف لها خاصية او طريقة اضف قبل متغيراتها او دوالها الجملة this تليها نقطة " . "
مثال
Function mohammed(a,n){
This.age=a
This.name=n
This.printAll=function(){
Print(a+"…"+n)
}
}في المثال السابق a و n هم عبارة عن خصائص ثم تلتهم الطريقة printAll وفي حال اردت انشاء متغير لهذا الكائن
M=new mohammed (20,"mohammed")
لاحظ لقد قمنا بإستخدام الجملة new تلاها اسم الكائن ولإستدعاء الخصائص والطرق
Print(M.age) Print(M.name) M.printAll()
فكان الناتج
20
mohammed
20…mohammed
سجل الأنواع record type
وصيغته
Var={a1:value1,a2:value2,a3:value3,……}وعند استدعاء مابداخلها فإنها تعامل معاملة كائن لأنها كائن بكل بساطة .
Print(Var.a)
الكلمة المفتاحية with
وهي تساعدك في التعامل مع الكائنات بتخصيص الخصائص والطرق لكائن محدد بحيث تستغني عن وضع اسم الكائن قبل كل خاصية او طريقة .
وصيغتها
With(object){statement}ومثاله
Function mohammed(a,n){
This.age=a
This.name=n
This.printAll=function(){
Print(a+"…"+n)
}
}
M=new mohammed (20,"mohammed")
With(M){
Print(age)
Print(name)
printAll()
}الناتج
20
mohammed
20…mohammed
لاحظ انه في المثال المسابق لم نحتاج الى وضع اسم الكائن تليه نقطة قبل كل خاصية وطريقة لأننا قمنا بتخصيص الجمل لكائن بإستخدام الكلمة المفتاحية with .
الكلمة المفتاحية for-in
لإعادة وتكرار خواص كائن ما
وصيغتها
For( var , object){statement}فمثلا
Function mohammed(a,n){
This.age=a
This.name=n
This.printAll=function(){
Print(a+"…"+n)
}
}
M=new mohammed (20,"mohammed")
For(z in M){
Print(z)
}الناتج
Age
Name
وتستخدم أيضا مع المصفوفات بحيث تمر على جميع عناصرها
مثاله
A=[10,20,30,40]
For(m in A){
Print m
}الناتج
10
20
30
40
ويماثلها في Qt foreach للحاويات .
مراجعة سريعة لأهم الكائنات في ecmascript
قبل ان نتعرف على أهم الكائنات فإننا يجب ان نعرف بعض الأمور :
الكلمة المفتاحية delete : كما تحدثنا عنها في المصفوفات وأنها تقوم بحذف عنصر من مصفوفة فكذلك هي هنا تقوم بحذف خاصية او طريقة من كائن او حتى الكائن بالكامل
delete object
.
الخاصية Prototype : وهي لإضافة خصائص وطرق لكائن ما.
بشرط ان يكون الكائن قابل للتمثيل في متغيرات .
ومثال عليها
Function myClass(a,n){
This.age=a;
This.name=n;
}
myClass.prototype.printAll=function(){
print(this.name+"::"+this.age)
r=new myClass(20,"mohammed")
r.printAll();الناتج mohammed::20 .
بالإضافة الى بعض الخواص الأخرى التي تشترك او تنفرد بها بعض الكائنات عن الأخرى .
الكائن Array
ويستخدم لتوليد المصفوفات ويحوي خاصيتين prototype و length والثاني لإرجاع عدد العناصر وبعض الطرق مثل toString و join و sort و reverse
ومثالها
A=new Array(4,3,5,"rami") A.length // 4
واضافة خاصية بإستخدام prototype
Array.prototype.age=12 A=new Array(1,2,3,4,5,6) Print(A.age())
الكائن Function
بالإضافة الى خاصية prototype فهو ايضا لديه خاصية length لإرجاع عدد الوسائط
وصيغتها
new Function("var1","var2",…,"statement")مثال
F=new Function("x","y","print(x*y)")
F(2,4)الناتج : 8
بالإضافة الى الخصائص السابقة فإن الخاصية الأكثر أهمية هي arguments وهي مصفوفة بها جميع القيم في الوسائط
مثاله :
function F(){
A=arguments.length
total=0
For(i=0;i<A;i++){total+=arguments}
Return total
}
Print(F(1,2,3,4,5,6,7,8,9,10,11,12))الناتج :78 .
الكائن الرئيسي Object
هو الكائن الرئيسي الذي ترث منه جميع الكائنات بإستثناء Global وهي تدعم الخاصيتين prototype والخاصية constructor أي اسم المنشئ فلذلك جميع الكائنات تدعمهم أيضا بالإضافة الى الطرق toString وتعيد تمثيله بالحروف والثاني valueOf وتعطي القيمة البدائية .
الكائنين Global و Math
وكلاهما لايمكن تمثيلهم في متغيرات فالأول تستخدم خصائصه وطرقه مباشرة والثاني مباشرة ايضا ولكن بعد التعبير Math. لأنها static .
الأول هدفه ربط أي كائن بوظائف ومتغيرات عامة و له ثلاث خواص NaNو Infinity و Undefined وجميعهم ثوابت الأول في حال كانت القيمة غير رقمية والثني في حال القسمة على 0 ويمكنك ان تستخدمه على أي عدد لينتج لك القيمة 0 وآخر خاصية هي للمتغيرات الغير معرفة .
اما طرقه فيمكن مراجعتها من خلال الرابط التالي :
http://phrogz.net/objjob/objects.asp
وكذلك ايضا Math فهي للثوابت والدوال الرياضية فلها خواص ثابتة مثل PI و E و LN2 و LN10 وووو
ولها طرق ويمكن ايضا مراجعتها من خلال الرابط التالي:
http://phrogz.net/objjob/objects.asp
الكائنات Boolean و Number و String
بالإضافة الى دعمها خواص الكائن الرئيسي وطرقه فإن لدى كل من String و Number طرق وخواص أخرى يمكن الوصول اليها من خلال الرابط التالي:
http://phrogz.net/objjob/objects.asp
كائن التاريخ Date
بالإضافة الى خواص وطرق الكائن الرئيسي فإن لديه طرق لتحديد الوقت بالإضافة وصيغتها ويمكن الوصول الى طرقها من خلال الرابط :
http://phrogz.net/objjob/objects.asp
كائن التعابير النظامية RegExp
وهي عبارة عن تعبيرات حرفية تصف نموذجا او اسلوبا متتابعا من الحروف pattern وقد تم ضمها مع الكائنات القياسية في الإصدار الثاني من ecmascript وكانت قبلها مدعومة في javescript لمعرفة الخواص والطرق
http://phrogz.net/objjob/objects.asp
بالإضافة الى الكائنات السابقة هناك كائنات اخرى ايضا يمكنك التعرف على جميع الكائنات من خلال الرابط التالي :
http://phrogz.net/objjob/objects.asp
الشق الثاني
Qt & ecmascript262
ان تدعم لغة او مكتبة او تقنية لغة الوثائق(النصية) بجانب اللغات المرئية فإن هذا بلا شك يمثل قوة وعبقرية لهذه اللغة او المكتبة او حتى التقنية فلذلك كان من واجبات Qt4 تقديم دعم لهذا النوع فكانت البداية في Qt4.3 فقامت ببناء الوحدة QtScript ومنذ البداية جعلوها تعتمد على معايير ecmascript3 وكان قبل هذا الإصدار محاولات لدعم البرمجة بلغات نصية ولكن ليس على معايير ecmascript فنشأ مايسمى QSA اختصار ل Qt script for Application في حال انك كنت قد تعرفت على QSA وتريد الإنتقال الى QtScript الداعمة ل ecmascript فبإمكانك مرفة الفروقات وتعلم الإضافات من خلال صفحة خصصتها QtAssistant للمنتقلين من QSA الى QtScript ولكن نحن هنا نريد ان نتعلم من البداية فدعنا نبدأ على بركة الله .
اعداد QtScipt داخل المشروع :
من خلال ملف المشروع .pro قم بإضافة هذا السطر
QT+=script
ثم اضف الوحدة QtScript الى الشفرة المصدرية
#include< QtScript>
محرك ecmascript واستعراض سريع لأهم الفئات:
تعتبر الفئة QscriptEngine هو رأس الوحدة QtScript فالتعامل مع الشفرات النصية يتم عن طريقها فهي تمثل بيئة لعمل هذه الشفرات .
بينما تمثل الفئة QscriptValue انواع البيانات وهي تدعم جميع انواع البيانات المدعومة من ecmascript .
QscriptValueIterator اذا ما اردت في التجول داخل خصائص الكائنات في QtScript .
برنامجك الأول
برنامج alslam 3likom
#include <QtGui>
#include <QtScript>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QScriptEngine engine;
QScriptValue ecma=engine.evaluate("m=new String('alslam 3likom')");
QLabel lab(ecma.toString());
lab.show();
return app.exec();
}سوف يضهر على label جملة alslam 3likom
قمنا بالتصريح عن المتغير engine والذي من خلاله سوف نقوم بتنفيذ شفرات ال script وهذا ماحدث فعلا فمن خلال الأمر evaluate التابع للفئة QscriptEngine قمنا بإرسال نص ecmascript
m=new String('alslam 3likom')وتعيد الدالةevaluate متغير من النوع QscriptValue والذي كما ذكرنا مسبقا انه حاوي لمخرجات برنامج ال script ثم انشأن label لنظيف اليه قيمة ecma بعد ماقمنا بتحويلها الى نص .
اضافة كائن من Qt للتحكم به بواسطة QtScript
#include <QtGui>
#include <QtScript>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QScriptEngine engine;
QLabel *lab=new QLabel;
QScriptValue mylab = engine.newQObject(lab);
engine.globalObject().setProperty("lab", mylab);
engine.evaluate("lab.text='alslam 3likom'");
engine.evaluate("lab.show()");
return app.exec();
}QScriptValue mylab = engine.newQObject(lab); هنا قمنا بإنشاء كائن QtScript وهي عملية تغليف كائن Qt بكائن ecmascript وعملية التغليف تشمل الإشارات والمستقبلات والخصائص والأبناء ايضا
ثم اضفنا خاصية للكائن العام وسميناها lab وهي في الأصل الكائن الذي قمنا بصناعته ولكن هذا يسمح لنا بتحديد الكائن بإسم والتحكم بخصائصه وطرقه ثم قمنا بإضافة شفرات script في آخر الموضوع ليكون مخرجات البرنامج هو عبارة عن label مكتوب عليها alslam 3likom.
وبما اننا في هذا البرنامج تطرقنا الى global opject فإنه علينا ان نفصل في هذا الموضوع أكثر عند انشاء QscriptEngine فإنه يبدأ ومعه كائن رئيسي وحيد تضاف اليه كائنات أخرى ولكن على هيئة خصائص وتكون هذه الخاصية ايضا بها خواص أخرى وهي متوفرة معه وسوف تجد الخصائص لك كائن في ملف assistant كذلك تصبح دوال المستقبلات والإشارات طرق .
الربط بين الإشارات والمستقبلات
وتكون طريقة الربط بين الكائنات بواسطة شيفرة script على هذا النحو
function myInterestingScriptFunction() { ... }
myQObject.event.connect(myInterestingScriptFunction);ومثال عليه
1. #include <QtGui>
2. #include <QtScript>
3. int main(int argc, char *argv[])
4. {
5. QApplication app(argc, argv);
6. QScriptEngine engine;
7. QPushButton *button=new QPushButton("Qt-ar.com");
8. QLabel *lab=new QLabel("mohammed");
9. QScriptValue mybutton=engine.newQObject(button);
10. QScriptValue mylab=engine.newQObject(lab);
11. engine.globalObject().setProperty("button", mybutton);
12. engine.globalObject().setProperty("lab", mylab);
13. engine.evaluate("function slot(){this.lab.text='alabdaly'}; button.clicked.connect(slot);");
14. QVBoxLayout layout;
15. layout.addWidget(lab);
16. layout.addWidget(button);
17. QWidget w;
18. w.setLayout(&layout);
19. w.show();
20. return app.exec();
21. }اذا انتقلنا الى السطر الثالث عشر مباشرة فإن الشفرة النصية تص على في حال الضغط على الزر فإن النص mohammed على ال label يتم تغييره الى alabdaly
وفي المقابل فإن الشفرة النصية
myQObject.event.disconnect(myInterestingFunction);
لقطع الإرتباط بين الكائن والدالة.
وفي حال اردت الربط بين كائنين فإن
myQObject.event.connect(obj, "fun");
وعكسها
myQObject.event.disconnect(obj, "fun");
ولإرسال اشارات بواسطة اللغة النصية
myQObject.event("any");الربط بين الإشارات والمستقبلات بإستخدام QtScript
bool qScriptConnect ( QObject * sender, const char * signal, const QScriptValue & receiver, const QScriptValue & function )
او لقطع االإرتباط
bool qScriptDisconnect ( QObject * sender, const char * signal, const QScriptValue & receiver, const QScriptValue & function )
مثال :
1. #include <QtGui>
2. #include <QtScript>
3. int main(int argc, char *argv[])
4. {
5. QApplication app(argc, argv);
6. QScriptEngine engine;
7. QPushButton *button=new QPushButton("Qt-ar.com");
8. QLabel *lab=new QLabel("mohammed");
9. QScriptValue mybutton=engine.newQObject(button);
10. QScriptValue mylab=engine.newQObject(lab);
11. QScriptValue slot=engine.evaluate("slot=function(){this.text='alabdaly'};");
12. qScriptConnect(button,SIGNAL(clicked()),mylab,slot);
13. QVBoxLayout layout;
14. layout.addWidget(lab);
15. layout.addWidget(button);
16. QWidget w;
17. w.setLayout(&layout);
18. w.show();
19. return app.exec();
20. }هو مشابه للبرنامج السابق ولكن هذه المرة وفي السطر 12 بالتحديد استخدمنا الدالة qScriptConnect
لاحظ ان في شيفرة script أن this تشير الى الكائن lab وذلك لأنها يتعامل معها مباشرة أي بداخلها وليس على انها خاصية .
التعامل مع الأبناء
عندي تغليف احد الكائنات ب QtScript فإن من ضمن مايلتحق بها الى QtScript هو ابناء هذا الكائن
وذلك بأخذ اسمائها ووضعها كمتغير في QtScript ويكون تسمية الكائنات بإستخدام الأمر
setObjectName("QString") التابعة للفئة Qobject .
مثال:
1. #include <QtGui>
2. #include <QtScript>
3. int main(int argc, char *argv[])
4. {
5. QApplication app(argc, argv);
6. QScriptEngine engine;
7. QPushButton *button=new QPushButton("Qt-ar.com");
8. button->setObjectName("button");
9. QLabel *lab=new QLabel("mohammed");
10. lab->setObjectName("lab");
11. QVBoxLayout layout;
12. layout.addWidget(lab);
13. layout.addWidget(button);
14. QWidget w;
15. w.setLayout(&layout);
16. //======================================
17. QScriptValue myw=engine.newQObject(&w);
18. engine.globalObject().setProperty("w", myw);
19. engine.evaluate("w.button.text='mohammed';w.lab.text='qt-ar.com'");
20. w.show();
21. return app.exec();
22. }انظر في السطرين 8 و 10 تم تسمية الكائنين ثم بعد ترتيب في الكائن الأب المسمى w قمنا بتغليف الكائن الأب في السطرين 17 و 18 ومن ثم بتنفيذ الشيفرة النصية التالية
"w.button.text='mohammed';w.lab.text='qt-ar.com'"
ولاحظ اننا استخدمنا اسماء الكائنين button و lab الذي وضعناه مسبقا للتعريف عنهما داخل QtScript .
في حال كان لديك مجموعة كبيرة من الأبناء فبإمكانك استخدام كلا من الأمرين داخل ال script
parent.findChild("anyname");
parent.findChildren("RegExp");الأول يرجع اسم الكائن ان وجد والثاني يرجع مصفوفة بمعايير emascript لأسماء الكائنات التي وجدها .
وهذا مثال من assistant
var okButton = myDialog.findChild("okButton");
if (okButton != null) {
// do something with the OK button
}
var buttons = myDialog.findChildren(RegExp("button[0-9]+"));
for (var i = 0; i < buttons.length; ++i) {
// do something with buttons
}التحكم بنمط ملكية الكائنات
تقوم QtScript بإنشاء حاوية تجميع (garbage) لإستعادة الذاكرة المستخدمة من قبل كائنات اللغة النصية في حال انها لم تعد ذا قيمة . فأي كائن يمكن ان تسترد ذاكرته في حال لم يكن له وجود في بيئة تنفيذ اللغة النصية و Qt Script تترك لك كامل الحرية في التحكم في مايحدث في كائنات c++ في حال تم استعادة(تحرير) الذاكرة من كائنات script (مثاله : هل يتم حذف كائن c++ ام لا) ويتم تمرير من خلال الوسيط الثاني من الدالة newQObject .
ان معرف طريقة تعامل Qt Script مع ملكية كائن جدا مهم لأنها تساعدك في تجنب حالات عدم حذف كائن c++ بينما يجب ان يكون محذوف (تسرب في الذاكرة) او العكس .
Qt Ownership QScriptEngine::QtOwnership
وهي الحالة الإفتراضية للكائنات المغلفة وهي تعني ان ملكة الكائن ليست لمحرك اللغة النصية وبمعنى آخر انها سوف تدار وفق " Qt's object ownership" فعلى سبيل المثال اذا غلفت كائن جزء من صميم التطبيق فإنه سوف يتجاهل أي حدث في بيئة اللغة النصية .
Script Ownership QScriptEngine::ScriptOwnership
وهذا يعني ان محرك اللغة النصية سوف يأخذ الملكية الكاملة للكائن ويقوم بحذفه عندما يجد الفرصة الملائمة لذلك وبتعبير آخر عند عدم توفر مؤشر للكائن في محرك اللغة النصية . وحتى يكون هذا النمط فعال يشترط ان لا يكون للكائن أب وأن يكون انشئ في محرك اللغة النصية على النسق التالي
return engine->newQObject(new MyQObject(), QScriptEngine::ScriptOwnership);
Auto-Ownership QScriptEngine::AutoOwnership
في حال لم يكن لهذا الكائن أب ووجدت حاوية التجميع (garbage) ان هذا الكائن المغلف غير متواجد ضمن بيئة محرك اللغة النصية فإنه يتم حذفهغير ذلك فإنه يعامل معاملة Qt Ownership .
ماذا يحدث اذا قام شخص ما بحذف كائن Qobject ؟
في حالة ان شخص قام بتغليف كائن ثم قام بحذفه خارج إطار Qt script بدون أي اعتبار لنمط الملكية فإن
في هذه الحالة الكائن المغلف سيبقى كما هو كائن بعكس c++ فإن الكائن في الغة النصية (script) لايتم استبداله ب nullعلى كل حال في حال حاولت الوصول لأحد خصائصه او طرقه فإنه يلقي استثناء .
ملاحظة : اذا كانت الدالة QScriptValue::isQObject() ترسل القيمة true و الدالة QScriptValue::toQObject() ترسل مؤشر null فهذا دليل ان الكائن تم حذفه خارج بيئة لغة البرمجة النصية .
تخصيص طرق تغليف الكائنات
كما ذكرنا مسبقا ان اضافتك لكائن عن طريق الأمر newQObject بدون ان تخصص له طريقة للتغليف فإنه يؤدي الى تغليف الخصائص والإشارا والمستقبلات وكذلك الأبناء ولكن في حال انك قمت بتخصيص ماسوف يقوم بتغليفه فإنه لن يغلف الا ماطلبته منه وجميع هذه الطرق موجودة في الثابت التعدادي QScriptEngine::QobjectWrapOption وذلك بإضافتها الى الوصيط الثالث من newQObject .
ومن هذه الطرق
QScriptEngine::ExcludeChildObjects لمنع تغليف الكائنات الأبناء في QtScript
QScriptEngine::ExcludeSuperClassMethods لمنع تغليف دوال الإشارات والمستقبلات المورثة من الفئة Qobject
QScriptEngine::ExcludeSuperClassProperties لمنع تغليف الخصائص المورثة من الفئة QObject
QScriptEngine::SkipMethodsInEnumeration عدم ضم الطرق( الإشارات والمستقبلات) اثناء عملية فرز محتوى الكائن بإستخدام for-in ولكنها تغلف .
QScriptEngine::PreferExistingWrapperObject اذا كان الكائن وفق الإعدادات المطلوب موجود مسبقا يتم ارجاعه .
