হিসাবে নাথান ডব্লিউ তুলে ধরে যেভাবে এই কাজ করতে multithreading সঙ্গে, কিন্তু subclassing QThread সেরা অনুশীলনের নয়। এখানে দেখুন: http://mayaposch.wordpress.com/2011/11/01/how-to-really-t بيشڪ-use-qthreads-the-ful-explanation/
কীভাবে তৈরি করবেন তার উদাহরণ নীচে দেখুন QObject
, তারপরে এটিতে স্থানান্তরিত করুন QThread
( এটি করার সঠিক "উপায়)। এই উদাহরণটি ভেক্টর স্তরের সমস্ত বৈশিষ্ট্যের মোট ক্ষেত্রের গণনা করে (নতুন কিউজিআইএস ২.০ এপিআই ব্যবহার করে!)।
প্রথমত, আমরা "শ্রমিক" অবজেক্ট তৈরি করি যা আমাদের জন্য ভারী উত্তোলন করবে:
class Worker(QtCore.QObject):
def __init__(self, layer, *args, **kwargs):
QtCore.QObject.__init__(self, *args, **kwargs)
self.layer = layer
self.total_area = 0.0
self.processed = 0
self.percentage = 0
self.abort = False
def run(self):
try:
self.status.emit('Task started!')
self.feature_count = self.layer.featureCount()
features = self.layer.getFeatures()
for feature in features:
if self.abort is True:
self.killed.emit()
break
geom = feature.geometry()
self.total_area += geom.area()
self.calculate_progress()
self.status.emit('Task finished!')
except:
import traceback
self.error.emit(traceback.format_exc())
self.finished.emit(False, self.total_area)
else:
self.finished.emit(True, self.total_area)
def calculate_progress(self):
self.processed = self.processed + 1
percentage_new = (self.processed * 100) / self.feature_count
if percentage_new > self.percentage:
self.percentage = percentage_new
self.progress.emit(self.percentage)
def kill(self):
self.abort = True
progress = QtCore.pyqtSignal(int)
status = QtCore.pyqtSignal(str)
error = QtCore.pyqtSignal(str)
killed = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal(bool, float)
কর্মীটি ব্যবহার করতে আমাদের এটি একটি ভেক্টর স্তর দিয়ে সূচনা করতে হবে, এটি থ্রেডে সরানো হবে, কিছু সংকেত সংযুক্ত করতে হবে এবং তারপরে এটি শুরু করুন। এখানে কী চলছে তা বোঝার জন্য উপরের লিঙ্ক করা ব্লগটি দেখা ভাল ।
thread = QtCore.QThread()
worker = Worker(layer)
worker.moveToThread(thread)
thread.started.connect(worker.run)
worker.progress.connect(self.ui.progressBar)
worker.status.connect(iface.mainWindow().statusBar().showMessage)
worker.finished.connect(worker.deleteLater)
thread.finished.connect(thread.deleteLater)
worker.finished.connect(thread.quit)
thread.start()
এই উদাহরণটি কয়েকটি মূল বিষয় তুলে ধরে:
run()
শ্রমিকের পদ্ধতির ভিতরে থাকা সমস্ত কিছুই চেষ্টা-বাদ দেওয়া বিবৃতিতে। যখন আপনার কোডটি থ্রেডের অভ্যন্তরে ক্রাশ হবে তখন এটি পুনরুদ্ধার করা কঠিন। এটি ত্রুটি সংকেতটির মাধ্যমে ট্রেসব্যাকটি নির্গত করে যা আমি সাধারণত এর সাথে সংযোগ করি QgsMessageLog
।
- প্রক্রিয়াটি সফলভাবে সমাপ্ত হলে ফলাফলের সাথে সংযুক্ত পদ্ধতিটি সমাপ্ত সিগন্যালটি বলে।
- অগ্রগতি সংকেত কেবল তখনই বলা হয় যখন প্রতিটি বৈশিষ্ট্যের জন্য একবারের চেয়ে শতাংশ সম্পূর্ণ পরিবর্তিত হয়। এটি কর্মী প্রক্রিয়াটিকে ধীরগতির করে অগ্রগতি বার আপডেট করার জন্য অনেকগুলি কলকে বাধা দেয়, যা শ্রমিককে অন্য থ্রেডে চালানোর পুরো পয়েন্টকে পরাস্ত করবে: ব্যবহারকারী ইন্টারফেস থেকে গণনা পৃথক করতে।
- কর্মী একটি
kill()
পদ্ধতি প্রয়োগ করে , যা কার্যটি নিখুঁতভাবে শেষ করতে দেয়। চেষ্টা করুন এবং terminate()
পদ্ধতিটি ব্যবহার না করে QThread
- খারাপ জিনিসগুলি ঘটতে পারে!
আপনার প্লাগইন কাঠামোর কোথাও আপনার thread
এবং worker
অবজেক্টের ট্র্যাক রাখতে ভুলবেন না । না করলে কিউটি রাগান্বিত হয়। এটি করার সবচেয়ে সহজ উপায় হ'ল আপনি যখন এগুলি তৈরি করবেন তখন তা আপনার ডায়লগে সংরক্ষণ করুন, যেমন:
thread = self.thread = QtCore.QThread()
worker = self.worker = Worker(layer)
অথবা আপনি Qt কে কিউথ্রেডের মালিকানা নিতে দিতে পারেন:
thread = QtCore.QThread(self)
এই টেমপ্লেটটি একসাথে রাখার জন্য সমস্ত টিউটোরিয়াল খনন করতে আমার অনেক সময় লেগেছে, তবে তখন থেকে আমি সমস্ত জায়গা জুড়ে এটি পুনরায় ব্যবহার করছি।