2019-10-23 20:10:03 +00:00
|
|
|
import PySimpleGUI as sg
|
2018-10-31 03:45:12 +00:00
|
|
|
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():
|
|
|
|
|
2019-10-23 20:10:03 +00:00
|
|
|
layout = [
|
2019-11-19 16:54:35 +00:00
|
|
|
[sg.Multiline(size=(50, 15), key='-LOG-')],
|
2019-10-23 20:10:03 +00:00
|
|
|
[sg.Button('Start', bind_return_key=True, key='-START-'), sg.Button('Exit')]
|
2018-10-31 03:45:12 +00:00
|
|
|
]
|
|
|
|
|
2019-11-19 16:54:35 +00:00
|
|
|
window = sg.Window('Log window', layout,
|
2019-10-23 20:10:03 +00:00
|
|
|
default_element_size=(30, 2),
|
|
|
|
font=('Helvetica', ' 10'),
|
2019-11-19 16:54:35 +00:00
|
|
|
default_button_element_size=(8, 2),)
|
|
|
|
|
2018-10-31 03:45:12 +00:00
|
|
|
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
|
2019-10-23 20:10:03 +00:00
|
|
|
event, values = window.read(timeout=100)
|
2018-10-31 03:45:12 +00:00
|
|
|
|
2019-10-23 20:10:03 +00:00
|
|
|
if event == '-START-':
|
2018-10-31 03:45:12 +00:00
|
|
|
if appStarted is False:
|
|
|
|
threadedApp.start()
|
|
|
|
logger.debug('App started')
|
2019-10-23 20:10:03 +00:00
|
|
|
window['-START-'].update(disabled=True)
|
2018-10-31 03:45:12 +00:00
|
|
|
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)
|
2019-11-19 16:54:35 +00:00
|
|
|
window['-LOG-'].update(msg+'\n', append=True)
|
2018-10-31 03:45:12 +00:00
|
|
|
|
2019-10-23 20:10:03 +00:00
|
|
|
window.close()
|
2018-10-31 03:45:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|