Changed multi-threaded demos to use new Window.write_event_value method
This commit is contained in:
parent
934cea5881
commit
04dfa364d5
6 changed files with 109 additions and 139 deletions
|
@ -1,11 +1,8 @@
|
|||
#!/usr/bin/python3
|
||||
import queue
|
||||
import threading
|
||||
import time
|
||||
import PySimpleGUI as sg
|
||||
|
||||
# This program has been tested on all flavors of PySimpleGUI and it works with no problems at all
|
||||
# To try something other than tkinter version, just comment out the first import and uncomment the one you want
|
||||
|
||||
"""
|
||||
DESIGN PATTERN - Multithreaded Long Tasks GUI
|
||||
|
@ -13,18 +10,20 @@ import PySimpleGUI as sg
|
|||
The PySimpleGUI code, and thus the underlying GUI framework, runs as the primary, main thread
|
||||
The "long work" is contained in the thread that is being started.
|
||||
|
||||
A queue.Queue is used by the threads to communicate with main GUI code
|
||||
July 2020 - Note that this program has been updated to use the new Window.write_event_value method.
|
||||
This method has not yet been ported to the other PySimpleGUI ports and is thus limited to the tkinter ports for now.
|
||||
|
||||
Internally to PySimpleGUI, a queue.Queue is used by the threads to communicate with main GUI code
|
||||
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
|
||||
"""
|
||||
|
||||
|
||||
def long_operation_thread(seconds, gui_queue):
|
||||
def long_operation_thread(seconds, window):
|
||||
"""
|
||||
A worker thread that communicates with the GUI through a queue
|
||||
This thread can block for as long as it wants and the GUI will not be affected
|
||||
|
@ -34,7 +33,7 @@ def long_operation_thread(seconds, gui_queue):
|
|||
"""
|
||||
print('Starting thread - will sleep for {} seconds'.format(seconds))
|
||||
time.sleep(seconds) # sleep for a while
|
||||
gui_queue.put('** Done **') # put a message into queue for GUI
|
||||
window.write_event_value('-THREAD-', '** DONE **') # put a message into queue for GUI
|
||||
|
||||
|
||||
def the_gui():
|
||||
|
@ -44,7 +43,6 @@ def the_gui():
|
|||
Returns when the user exits / closes the window
|
||||
"""
|
||||
sg.theme('Light Brown 3')
|
||||
gui_queue = queue.Queue() # queue used to communicate between the gui and the threads
|
||||
|
||||
layout = [[sg.Text('Long task to perform example')],
|
||||
[sg.Output(size=(70, 12))],
|
||||
|
@ -57,29 +55,17 @@ def the_gui():
|
|||
|
||||
# --------------------- EVENT LOOP ---------------------
|
||||
while True:
|
||||
event, values = window.read(timeout=100)
|
||||
event, values = window.read()
|
||||
if event in (sg.WIN_CLOSED, 'Exit'):
|
||||
break
|
||||
elif event.startswith('Do'):
|
||||
try:
|
||||
seconds = int(values['-SECONDS-'])
|
||||
print('Thread ALIVE! Long work....sending value of {} seconds'.format(seconds))
|
||||
threading.Thread(target=long_operation_thread,
|
||||
args=(seconds, gui_queue,), daemon=True).start()
|
||||
except Exception as e:
|
||||
print('Error starting work thread. Bad seconds input: "%s"' %
|
||||
values['-SECONDS-'])
|
||||
seconds = int(values['-SECONDS-'])
|
||||
print('Thread ALIVE! Long work....sending value of {} seconds'.format(seconds))
|
||||
threading.Thread(target=long_operation_thread, args=(seconds, window,), daemon=True).start()
|
||||
elif event == 'Click Me':
|
||||
print('Your GUI is alive and well')
|
||||
# --------------- Check for incoming messages from threads ---------------
|
||||
try:
|
||||
message = gui_queue.get_nowait()
|
||||
except queue.Empty: # get_nowait() will get exception when Queue is empty
|
||||
message = None # break from the loop if no more messages are queued up
|
||||
|
||||
# if message received from queue, display the message in the Window
|
||||
if message:
|
||||
print('Got a message back from the thread: ', message)
|
||||
elif event == '-THREAD-':
|
||||
print('Got a message back from the thread: ', values[event])
|
||||
|
||||
# if user exits the window, then close the window and exit the GUI func
|
||||
window.close()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue