import sys if sys.version_info[0] >= 3: import PySimpleGUIQt as sg else: import PySimpleGUI27 as sg import queue import logging import threading import time """ This code originated in this project: https://github.com/john144/MultiThreading Thanks to John for writing this in the early days of PySimpleGUI Demo program showing one way that a threaded application can function with PySimpleGUI Events are sent from the ThreadedApp thread to the main thread, the GUI, by using a queue """ logger = logging.getLogger('mymain') def externalFunction(): logger.info('Hello from external app') logger.info('External app sleeping 5 seconds') time.sleep(5) logger.info('External app waking up and exiting') class ThreadedApp(threading.Thread): def __init__(self): super().__init__() self._stop_event = threading.Event() def run(self): externalFunction() def stop(self): self._stop_event.set() class QueueHandler(logging.Handler): def __init__(self, log_queue): super().__init__() self.log_queue = log_queue def emit(self, record): self.log_queue.put(record) def main(): window = sg.FlexForm('Log window', default_element_size=(30, 2), font=('Helvetica', ' 10'), default_button_element_size=(8, 2), return_keyboard_events=True) layout = \ [ [sg.Multiline(size=(50, 15), key='Log')], [sg.Button('Start', bind_return_key=True, key='_START_'), sg.Button('Exit')] ] window.Layout(layout).Read(timeout=0) appStarted = False # Setup logging and start app logging.basicConfig(level=logging.DEBUG) log_queue = queue.Queue() queue_handler = QueueHandler(log_queue) logger.addHandler(queue_handler) threadedApp = ThreadedApp() # Loop taking in user input and querying queue while True: # Wake every 100ms and look for work event, values = window.Read(timeout=100) if event == '_START_': if appStarted is False: threadedApp.start() logger.debug('App started') window.FindElement('_START_').Update(disabled=True) appStarted = True elif event in (None, 'Exit'): break # Poll queue try: record = log_queue.get(block=False) except queue.Empty: pass else: msg = queue_handler.format(record) window.FindElement('Log').Update(msg+'\n', append=True) window.Close() exit() if __name__ == '__main__': main()