(continued from previous page) 

# Start a new worker thread and connect the slots for the worker self.start_thread() self.work_button .clicked.connect( self.worker.start) # Once started, the button should be disabled self.work_button .clicked.connect( lambda :self.work_button . ↪ → setEnabled( False )) def start_thread(self): self.worker =Worker() self.worker_thread =QtCore.QThread() self.worker.setObjectName('Worker ') self.worker_thread.setObjectName('WorkerThread ') # for qThreadName self.worker.moveToThread(self.worker_thread) # This will start an event loop in the worker thread self.worker_thread.start() def kill_thread(self): # Just tell the worker to stop, then tell it to quit and wait for that # to happen self.worker_thread.requestInterruption() if self.worker_thread.isRunning(): self.worker_thread.quit() self.worker_thread.wait() else : print('worker has already exited.') def force_quit(self): # For use when the window is closed if self.worker_thread.isRunning(): self.kill_thread() # The functions below update the UI and run in the main thread because # that's where the slots are set up @Slot (str, logging .LogRecord) def update_status (self, status, record): color =self.COLORS .get(record.levelno, 'black') s ='<pre><font color= " %s "> %s </font></pre> '%(color, status) self.textedit.appendHtml(s) @Slot () def manual_update (self): # This function uses the formatted message passed in, but also uses # information from the record to format the message in an appropriate # color according to its severity (level). level=random.choice(LEVELS) extra ={ 'qThreadName ': ctname() } logger.log(level, 'Manually logged! ', extra =extra) @Slot () def clear_display (self): self.textedit.clear() def main(): QtCore.QThread .currentThread() .setObjectName('MainThread ') logging.getLogger() .setLevel(logging .DEBUG) app =QtWidgets.QApplication(sys .argv) example=Window(app) example.show() 

(continues on next page) 

