diff --git a/DemoPrograms/Demo_Multithreaded_Queued.py b/DemoPrograms/Demo_Multithreaded_Queued.py index 09ebf8ac..f141d8b7 100644 --- a/DemoPrograms/Demo_Multithreaded_Queued.py +++ b/DemoPrograms/Demo_Multithreaded_Queued.py @@ -7,8 +7,17 @@ import PySimpleGUI as sg """ DESIGN PATTERN - Multithreaded GUI One method for running multiple threads in a PySimpleGUI environment. - This design pattern works for all of the flavors of PySimpleGUI including the Web and also repl.it + The PySimpleGUI code, and thus the underlying GUI framework, runs as the primary, main thread + Other parts of the software are implemented as threads + A queue.Queue is used by the worker threads to communicate with code that calls PySimpleGUI directly. + The PySimpleGUI code is structured just like a typical PySimpleGUI program. A layout defined, + a Window is created, and an event loop is executed. + What's different is that within this otherwise normal PySimpleGUI Event Loop, there is a check for items + in the Queue. If there are items found, process them by making GUI changes, and continue. + + This design pattern works for all of the flavors of PySimpleGUI including the Web and also repl.it + You'll find a repl.it version here: https://repl.it/@PySimpleGUI/Async-With-Queue-Communicationspy """ @@ -21,7 +30,7 @@ def worker_thread(thread_name, run_freq, gui_queue): :param gui_queue: Queue used to communicate with the GUI :return: """ - print('Strarting thread - ', thread_name) + print('Starting thread - ', thread_name) i = 0 while True: sleep(run_freq/1000) @@ -43,17 +52,19 @@ def the_gui(gui_queue): window = sg.Window('Window Title').Layout(layout) while True: # Event Loop - event, values = window.Read(timeout=200) # wait for up to 200 ms for a GUI event + event, values = window.Read(timeout=100) # wait for up to 200 ms for a GUI event if event is None or event == 'Exit': break #--------------- Handle stuff coming in from threads --------------- - try: # see if something has been posted to Queue - message = gui_queue.get_nowait() - except: - message = None # indicate nothing posted - # if message received from queue, display the message in the Window - if message: - window.Element('_OUTPUT_').Update(message) + while True: # loop executes until runs out of messages in Queue + try: # see if something has been posted to Queue + message = gui_queue.get_nowait() + except: # will get exception when Queue is empty + break # break from the loop if no more messages are queued up + # if message received from queue, display the message in the Window + if message: + window.Element('_OUTPUT_').Update(message) + window.Refresh() # if user exits the window, then close the window and exit window.Close() @@ -63,9 +74,7 @@ if __name__ == '__main__': #-- Create a Queue to communicate with GUI -- gui_queue = Queue() # queue used to communicate between the gui and the worker #-- Start worker threads, one runs twice as often as the other - thread = Thread(target=worker_thread, args=('Thread 1', 1000, gui_queue,), daemon=True) - thread.start() - thread = Thread(target=worker_thread, args=('Thread 2', 500, gui_queue,), daemon=True) - thread.start() + Thread(target=worker_thread, args=('Thread 1', 500, gui_queue,), daemon=True).start() + Thread(target=worker_thread, args=('Thread 2', 200, gui_queue,), daemon=True).start() #-- Start the GUI passing in the Queue -- the_gui(gui_queue)