New Demo - Multithreaded logging

This commit is contained in:
MikeTheWatchGuy 2018-10-30 23:45:12 -04:00
parent 8eeec3e2e8
commit e89e55f69a
2 changed files with 104 additions and 9 deletions

View File

@ -0,0 +1,98 @@
import sys
if sys.version_info[0] >= 3:
import PySimpleGUI 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.LayoutAndRead(layout, non_blocking=True)
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()

View File

@ -3083,7 +3083,7 @@ class Window:
self.RootNeedsDestroying = True
return None
def CloseNonBlocking(self):
def Close(self):
if self.TKrootDestroyed:
return
try:
@ -3092,13 +3092,12 @@ class Window:
except:
pass
CloseNonBlockingForm = CloseNonBlocking
Close = CloseNonBlockingForm
CloseNonBlockingForm = Close
CloseNonBlocking = Close
# IT FINALLY WORKED! 29-Oct-2018 was the first time this damned thing got called
def OnClosingCallback(self):
print('Got closing callback')
# print('Got closing callback')
self.TKroot.quit() # kick the users out of the mainloop
if self.CurrentlyRunningMainloop: # quit if this is the current mainloop, otherwise don't quit!
self.TKroot.destroy() # kick the users out of the mainloop
@ -5810,7 +5809,7 @@ PopupNoWait = PopupNonBlocking
# --------------------------- PopupQuick - a NonBlocking, Self-closing Popup ---------------------------
def PopupQuick(*args, button_type=POPUP_BUTTONS_OK, button_color=None, background_color=None, text_color=None,
auto_close=True, auto_close_duration=1, non_blocking=True, icon=DEFAULT_WINDOW_ICON, line_width=None,
auto_close=True, auto_close_duration=2, non_blocking=True, icon=DEFAULT_WINDOW_ICON, line_width=None,
font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None)):
"""
Show Popup box that doesn't block and closes itself
@ -5840,7 +5839,7 @@ def PopupQuick(*args, button_type=POPUP_BUTTONS_OK, button_color=None, backgroun
# --------------------------- PopupQuick - a NonBlocking, Self-closing Popup with no titlebar and no buttons ---------------------------
def PopupQuickMessage(*args, button_type=POPUP_BUTTONS_NO_BUTTONS, button_color=None, background_color=None, text_color=None,
auto_close=True, auto_close_duration=1, non_blocking=True, icon=DEFAULT_WINDOW_ICON, line_width=None,
auto_close=True, auto_close_duration=2, non_blocking=True, icon=DEFAULT_WINDOW_ICON, line_width=None,
font=None, no_titlebar=True, grab_anywhere=False, keep_on_top=False, location=(None, None)):
"""
Show Popup box that doesn't block and closes itself
@ -5868,8 +5867,6 @@ def PopupQuickMessage(*args, button_type=POPUP_BUTTONS_NO_BUTTONS, button_color=
font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location)
# --------------------------- PopupNoTitlebar ---------------------------
def PopupNoTitlebar(*args, button_type=POPUP_BUTTONS_OK, button_color=None, background_color=None, text_color=None,
auto_close=False, auto_close_duration=None, non_blocking=False, icon=DEFAULT_WINDOW_ICON,