text: from PyQt5 import QtCore,QtWidgets
  
  import traceback
  import sys
  
  
  class WorkerSignals(QtCore.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
          
      started
          used when there is a first step to pass in the process has to be set to emit manually in the runner function
      
      output
          emits everyline in stdout
          
  
  
      '''
      finished = QtCore.pyqtSignal()
      error = QtCore.pyqtSignal(tuple)
      result = QtCore.pyqtSignal(object)
      output =QtCore.pyqtSignal(str)
      
      started=QtCore.pyqtSignal() 
      
      
      
     
  class Worker(QtCore.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__()
          # Store constructor arguments (re-used for processing)
          self.fn = fn
          self.args = args
          self.kwargs = kwargs
          self.signals = WorkerSignals()
  
  
      # this is a decorator
      # now when this run function is executed it actually calls the QtCore.pyqtSlot function wuth run function as argument
      @QtCore.pyqtSlot()
      def run(self):
          '''
          Initialise the runner function with passed args, kwargs.
          '''
  
          # Retrieve args/kwargs here; and fire processing using them
          try:
              result = self.fn(
                  *self.args, **self.kwargs
              )
          except:
              traceback.print_exc()
              exctype, value = sys.exc_info()[:2]
              self.signals.error.emit((exctype, value, traceback.format_exc()))
          else:
              self.signals.result.emit(result)  # Return the result of the processing
          finally:
              self.signals.finished.emit()  # Done