আমি কিউজিআইএস 1.8 এর পাইথন প্লাগইন হিসাবে কিছু ব্যাচ প্রসেসিং সরঞ্জাম বিকাশ করছি।
আমি দেখতে পেয়েছি যে আমার সরঞ্জামগুলি চলাকালীন জিইউআই অ-প্রতিক্রিয়াশীল হয়ে ওঠে।
সাধারণ জ্ঞান হ'ল কর্মটি থ্রেডে কাজটি করা উচিত, স্থিতি / সমাপ্তির তথ্য জিইউআইতে সিগন্যাল হিসাবে ফিরিয়ে দেওয়া উচিত।
আমি নদীর তীরের ডক্সগুলি পড়েছি এবং doGeometry.py ( ftools থেকে কার্যকর বাস্তবায়ন ) এর উত্স অধ্যয়ন করেছি ।
এই উত্সগুলি ব্যবহার করে আমি একটি প্রতিষ্ঠিত কোড বেসে পরিবর্তন করার আগে এই কার্যকারিতাটি অন্বেষণ করতে একটি সাধারণ বাস্তবায়ন গড়ে তোলার চেষ্টা করেছি।
সামগ্রিক কাঠামোটি প্লাগইন মেনুতে একটি এন্ট্রি that বোতামগুলি এমন একটি থ্রেড নিয়ন্ত্রণ করে যা 100 হিসাবে গণ্য হয়, প্রতিটি সংখ্যার জন্য জিইউআইতে ফিরে একটি সংকেত প্রেরণ করে। জিইউআই প্রতিটি সিগন্যাল গ্রহণ করে এবং বার্তা লগ এবং উইন্ডো শিরোনাম উভয় সংখ্যক স্ট্রিং প্রেরণ করে।
এই প্রয়োগের কোডটি এখানে:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
class ThreadTest:
def __init__(self, iface):
self.iface = iface
def initGui(self):
self.action = QAction( u"ThreadTest", self.iface.mainWindow())
self.action.triggered.connect(self.run)
self.iface.addPluginToMenu(u"&ThreadTest", self.action)
def unload(self):
self.iface.removePluginMenu(u"&ThreadTest",self.action)
def run(self):
BusyDialog(self.iface.mainWindow())
class BusyDialog(QDialog):
def __init__(self, parent):
QDialog.__init__(self, parent)
self.parent = parent
self.setLayout(QVBoxLayout())
self.startButton = QPushButton("Start", self)
self.startButton.clicked.connect(self.startButtonHandler)
self.layout().addWidget(self.startButton)
self.stopButton=QPushButton("Stop", self)
self.stopButton.clicked.connect(self.stopButtonHandler)
self.layout().addWidget(self.stopButton)
self.show()
def startButtonHandler(self, toggle):
self.workerThread = WorkerThread(self.parent)
QObject.connect( self.workerThread, SIGNAL( "killThread(PyQt_PyObject)" ), \
self.killThread )
QObject.connect( self.workerThread, SIGNAL( "echoText(PyQt_PyObject)" ), \
self.setText)
self.workerThread.start(QThread.LowestPriority)
QgsMessageLog.logMessage("end: startButtonHandler")
def stopButtonHandler(self, toggle):
self.killThread()
def setText(self, text):
QgsMessageLog.logMessage(str(text))
self.setWindowTitle(text)
def killThread(self):
if self.workerThread.isRunning():
self.workerThread.exit(0)
class WorkerThread(QThread):
def __init__(self, parent):
QThread.__init__(self,parent)
def run(self):
self.emit( SIGNAL( "echoText(PyQt_PyObject)" ), "Emit: starting work" )
self.doLotsOfWork()
self.emit( SIGNAL( "echoText(PyQt_PyObject)" ), "Emit: finshed work" )
self.emit( SIGNAL( "killThread(PyQt_PyObject)"), "OK")
def doLotsOfWork(self):
count=0
while count < 100:
self.emit( SIGNAL( "echoText(PyQt_PyObject)" ), "Emit: " + str(count) )
count += 1
# if self.msleep(10):
# return
# QThread.yieldCurrentThread()
দুর্ভাগ্যক্রমে এটি আশানুরূপে কাজ করে নি:
- উইন্ডো শিরোনামটি কাউন্টারটির সাথে "লাইভ" আপডেট করছে তবে আমি যদি ডায়লগটিতে ক্লিক করি তবে এটি প্রতিক্রিয়াশীল নয়।
- কাউন্টারটি শেষ না হওয়া পর্যন্ত বার্তা লগ নিষ্ক্রিয় থাকে, তারপরে সমস্ত বার্তাগুলি একবারে উপস্থাপন করে। এই বার্তাগুলি কিউএমসেসেজলগ দ্বারা টাইম স্ট্যাম্পের সাথে ট্যাগ করা হয়েছে এবং এই সময়ের স্ট্যাম্পগুলি নির্দেশ করে যে তারা কাউন্টারটির সাথে "লাইভ" পেয়েছিল অর্থাৎ তারা কর্মী থ্রেড, বা কথোপকথনের দ্বারা সারিযুক্ত নয়।
লগের বার্তাগুলির ক্রমানুসারে (এক্সারপ্ট অনুসারে) ইঙ্গিত দেয় যে স্টার্টবটনহ্যান্ডলার কর্মী থ্রেড আসার আগেই কার্য সম্পাদন সম্পন্ন করে অর্থাৎ থ্রেডটি থ্রেড হিসাবে আচরণ করে।
end: startButtonHandler Emit: starting work Emit: 0 ... Emit: 99 Emit: finshed work
মনে হচ্ছে কর্মী থ্রেড কেবল জিইউআই থ্রেডের সাথে কোনও সংস্থান ভাগ করছে না। উপরের উত্সের শেষে বেশ কয়েকটি মন্তব্য রেখা রয়েছে যেখানে আমি এমএসপ্লিপ () এবং উত্পাদনকারেন্টথ্রেড () কল করার চেষ্টা করেছি, তবে উভয়ই সহায়তা করেছে বলে মনে হয় নি।
এই অভিজ্ঞতা আছে এমন কেউ কি আমার ত্রুটি চিহ্নিত করতে সক্ষম? আমি আশা করছি এটি একটি সাধারণ তবে মৌলিক ভুল যা এটি চিহ্নিত হয়ে গেলে এটি সংশোধন করা সহজ।