98 lines
2.6 KiB
Python
98 lines
2.6 KiB
Python
|
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()
|