text: import sys
  import traceback
  
  from PyQt5.QtCore import QRunnable, pyqtSignal, QObject, pyqtSlot
  
  from python.zaf_plus.context import Context
  
  
  class WorkerSignals(QObject):
      '''
      Defines the signals available from a running worker thread.
  
      Supported signals are:
  
      finished
          No data
  
      error
          `tuple` (exctype, value, traceback.format_exc() )
  
      result
          `object` data returned from processing, anything
  
      progress
          `int` indicating % progress
  
      '''
  
      finished = pyqtSignal()
      error = pyqtSignal(tuple)
      result = pyqtSignal(object)
      progress = pyqtSignal(str)
      early_stop = pyqtSignal()
  
  
  class Worker(QRunnable):
      '''
      Worker thread
  
      Inherits from QRunnable to handler worker thread setup, signals and wrap-up.
  
      :param callback: The function callback to run on this worker thread. Supplied args and
                       kwargs will be passed through to the runner.
      :type callback: function
      :param args: Arguments to pass to the callback function
      :param kwargs: Keywords to pass to the callback function
  
      '''
  
      def __init__(self, fn, *args, **kwargs):
          super(Worker, self).__init__()
  
          self.early_stop = False
  
          # Store constructor arguments (re-used for processing)
          self.fn = fn
          self.args = args
          self.kwargs = kwargs
          self.signals = WorkerSignals()
          # Add the callback to our kwargs
          self.kwargs['progress_callback'] = self.signals.progress
          self.kwargs['check_early_stop'] = self.check_early_stop
  
      @pyqtSlot()
      def run(self):
          '''
          Initialise the runner function with passed args, kwargs.
          '''
  
          # Retrieve args/kwargs here; and fire processing using them
          try:
              self.fn(*self.args, **self.kwargs)
          finally:
              self.signals.finished.emit()  # Done
  
      def check_early_stop(self):
          return self.early_stop
  
      def set_early_stop(self):
          self.early_stop = True
  