commit
4cdcda44ad
|
@ -7,8 +7,17 @@ import PySimpleGUI as sg
|
||||||
"""
|
"""
|
||||||
DESIGN PATTERN - Multithreaded GUI
|
DESIGN PATTERN - Multithreaded GUI
|
||||||
One method for running multiple threads in a PySimpleGUI environment.
|
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
|
:param gui_queue: Queue used to communicate with the GUI
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
print('Strarting thread - ', thread_name)
|
print('Starting thread - ', thread_name)
|
||||||
i = 0
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
sleep(run_freq/1000)
|
sleep(run_freq/1000)
|
||||||
|
@ -43,17 +52,19 @@ def the_gui(gui_queue):
|
||||||
window = sg.Window('Window Title').Layout(layout)
|
window = sg.Window('Window Title').Layout(layout)
|
||||||
|
|
||||||
while True: # Event Loop
|
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':
|
if event is None or event == 'Exit':
|
||||||
break
|
break
|
||||||
#--------------- Handle stuff coming in from threads ---------------
|
#--------------- Handle stuff coming in from threads ---------------
|
||||||
try: # see if something has been posted to Queue
|
while True: # loop executes until runs out of messages in Queue
|
||||||
message = gui_queue.get_nowait()
|
try: # see if something has been posted to Queue
|
||||||
except:
|
message = gui_queue.get_nowait()
|
||||||
message = None # indicate nothing posted
|
except: # will get exception when Queue is empty
|
||||||
# if message received from queue, display the message in the Window
|
break # break from the loop if no more messages are queued up
|
||||||
if message:
|
# if message received from queue, display the message in the Window
|
||||||
window.Element('_OUTPUT_').Update(message)
|
if message:
|
||||||
|
window.Element('_OUTPUT_').Update(message)
|
||||||
|
window.Refresh()
|
||||||
|
|
||||||
# if user exits the window, then close the window and exit
|
# if user exits the window, then close the window and exit
|
||||||
window.Close()
|
window.Close()
|
||||||
|
@ -63,9 +74,7 @@ if __name__ == '__main__':
|
||||||
#-- Create a Queue to communicate with GUI --
|
#-- Create a Queue to communicate with GUI --
|
||||||
gui_queue = Queue() # queue used to communicate between the gui and the worker
|
gui_queue = Queue() # queue used to communicate between the gui and the worker
|
||||||
#-- Start worker threads, one runs twice as often as the other
|
#-- 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(target=worker_thread, args=('Thread 1', 500, gui_queue,), daemon=True).start()
|
||||||
thread.start()
|
Thread(target=worker_thread, args=('Thread 2', 200, gui_queue,), daemon=True).start()
|
||||||
thread = Thread(target=worker_thread, args=('Thread 2', 500, gui_queue,), daemon=True)
|
|
||||||
thread.start()
|
|
||||||
#-- Start the GUI passing in the Queue --
|
#-- Start the GUI passing in the Queue --
|
||||||
the_gui(gui_queue)
|
the_gui(gui_queue)
|
||||||
|
|
Loading…
Reference in New Issue