بسم الله الرحمن الرحيم ,
أحاول فى التالى تقديم شرح لتطبيق عملى لل Python + ال Qt باستخدام ال PyQt4 Extension
التطبيق الذى سنحاول فية هو Rss Reader شديد البساطة ...
1) QDesigner
2) Eric 4
ملحوظة :-
المثال بدائى الى حد كبير فقط توضيح لمفاهيم ولا نستخدم أى Xml Parsing class وانما Pure RegEx فقط
بداية عن طريق ال QDesigner صمم ال Form التالية
و أن يحتوى على ال Signals / Slots الابتدائية التالية (كسلت أكتبهم :P )
مع ملاحظه احتوئها على :-
1) QLabel 2) QTextBrowser 3) QTreeWidget 4) QLineEdit 5) QPushButton
ثم تم تنظيمها عن طريق Lay out in Grid
التالى يفترض مهارات الأساسية فى التعامل مع Eric و ال Code Generator الخاص بة (المعتمد على PyQt )
فى البداية سنقسم الشغل لجزئين (2 Classes ) واحد حيتولى أمور ال UI وواحد حيتولى الشغل من تحت
1) MainOperation Class
هذا هو المعنى بالعمليات الأساسية ستناول ال Methods الخاصة بة تباعا :-
أ) الدالة GetFeed :-
هذة ال Function خاصة بالحصول على ال Feed وتحديد ال Encoding الخاص بة
def GetFeed(self):
c= self.getlinks(str(self.UIclass.LE_Inp.text()))
self.UIclass.L_Prg.hide()
#Detect Encoding
Enc=re.findall("<?xml(?:.*?)encoding="(.*?)"(?:.*?)>", c,re.DOTALL)
if Enc==[] :
Enc.append('utf-8')
self.Enc=Enc[0]
c=unicode(c,self.Enc, 'ignore')
self.ExtractInfo(c)بداية
c= self.getlinks(str(self.UIclass.LE_Inp.text()))
للحصول على ال Feed من الانترنت
Enc=re.findall("<?xml(?:.*?)encoding="(.*?)"(?:.*?)>", c,re.DOTALL)للحصول على ال Encoding الخاص بال Feed
ب) الدالة ExtractInfo :-
هذة الدالة خاصة باستخلاص المعلومات من ال Feed بحيث يمكن عرضها على ال TreeView
def ExtractInfo(self, fst):
for t in re.findall("<item>(.*?)</item>", fst,re.DOTALL):
item = QtGui.QTreeWidgetItem(self.UIclass.treeWidget)
title=re.findall("<title>(.*?)</title>", t,re.DOTALL)[0]
t=t.replace("<title>"+title+"</title>", "")
item.setText(0,title)
item.setToolTip(0, title)
for tt in re.findall("<(.*?)>(.*?)</\\1>", t,re.DOTALL):
item2=QtGui.QTreeWidgetItem(item)
item2.setText(0, tt[0])
if tt[0]=='link' :
datain="""<a href="%s">%s</a>""" % (tt[1],tt[1])
else:
datain=tt[1]
datain=QVariant(datain)
item2.setData(0, 32, datain)
for t in re.findall("<item>(.*?)</item>", fst,re.DOTALL):هنا نصل ال item tags فى ال xml feed ثم نمشى عليهم واحد واحد
title=re.findall("<title>(.*?)</title>", t,re.DOTALL)[0]هنا نحصل على ال title tag داخل كل item لكى نستخدمة لوضع اسم لل item
for tt in re.findall("<(.*?)>(.*?)</1>", t,re.DOTALL):هنا جزء ظريف J نصل لكى xml tag داخل ال item الذى نحن فية ثم نستخلص اسمة وقيمتة ونمشى عليهم واحد واحد
datain="""<a href="%s">%s</a>""" % (tt[1],tt[1])
else:
datain=tt[1]
if tt[0]=='link' :
هنا نجعل ال link field لو كان موجود يبقى valid html link مش مجرد text
ج) الدالة getlinks :-
الدالة الأخيرة لا تحتاج لشرح هى أقرب كونها سطمبة لسحب محتويات Url
def getlinks (self, address): file_request = urllib2.Request(address) file_opener = urllib2.build_opener() file_object = file_opener.open(file_request) return file_object.read()
2) Qr_UI
هذا هو المعنى بال UI وفية وضعنا ال Slots المستخدمة ( غير الثابتة طبعا )
أ) الدالة on_textBrowser_anchorClicked :-
def on_textBrowser_anchorClicked(self, p0): webbrowser.open(p0.toString())
هذة الدالة هى المعنية بالضغط على Link فى ال TextBrowser
webbrowser.open(p0.toString())
هذة الدالة الصغيرة ربما تجلعك تحب ال Python أو تكرهه J ولكنها ممتازة
هى تقوم بفتح اللنك المعطى لها فى ال Default Web Browser
ب) الدالة on_treeWidget_itemClicked :-
الدالة المستجيبة للضغط على أحد عناصر ال Tree
def on_treeWidget_itemClicked(self, item, column): self.textBrowser.setHtml(item.data(column, 32).toString())
self.textBrowser.setHtml(item.data(column, 32).toString())
كل ما نفعلة هنا هو عرض محتوى ال Cliked Item Data ونعرضة فى TextBrowser
ج) الدالة on_B_1_clicked :-
هذة الدالة المستجيبة للضغط على الزر Go
thread.start_new_thread(self.Opt.GetFeed, ())
def on_B_1_clicked(self):
تقوم باستدعاء ال function فى ال MainOperation Class فى Thread جديدة حتى لاتكون عملية الحصول على ال Feed بتعطيل ال UI
المرفقات :-
1) كمان ًWindows Exe لا يحتاج ل Python أو Qt لمن يريد التجربة :D مع ملاحظة انه مضغوط مرتين (لأمور متعلقة بالامتدادات المسموح بها )
2) الSource الكامل على هيئة py
الأدوات المستخدمة :-
