commit
4c8535f238
|
@ -2,26 +2,47 @@
|
||||||
import queue
|
import queue
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
|
|
||||||
# Put your long-running code in here
|
"""
|
||||||
|
Demo on how to add a long-running item to your PySimpleGUI Event Loop
|
||||||
|
If you want to do something that takes a long time, and you do it in the
|
||||||
|
main event loop, you'll quickly begin to see messages from windows that your
|
||||||
|
program has hung, asking if you want to kill it.
|
||||||
|
|
||||||
|
The problem is not that your problem is hung, the problem is that you are
|
||||||
|
not calling Read or Refresh often enough.
|
||||||
|
|
||||||
|
One way through this, shown here, is to put your long work into a thread that
|
||||||
|
is spun off, allowed to work, and then gets back to the GUI when it's done working
|
||||||
|
on that task.
|
||||||
|
|
||||||
|
If you have multiple long tasks to run, then you'll want a more sophisticated
|
||||||
|
format to your messages going back to the GUI so you'll know which task finished
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------
|
||||||
|
# Put your long-running code in here #
|
||||||
|
# ---------------------------------------
|
||||||
def worker_thread(thread_name, gui_queue):
|
def worker_thread(thread_name, gui_queue):
|
||||||
print('Starting thread - {} '.format(thread_name))
|
print('Starting thread - {} '.format(thread_name))
|
||||||
# this is our "long running function call"
|
# this is our "long running function call"
|
||||||
time.sleep(5) # sleep for a while
|
time.sleep(5) # sleep for a while
|
||||||
|
print('Ending thread - {} '.format(thread_name))
|
||||||
|
|
||||||
# at the end of the work, before exiting, send a message back to the GUI indicating end
|
# at the end of the work, before exiting, send a message back to the GUI indicating end
|
||||||
|
# in this case, we're using a simple string
|
||||||
gui_queue.put('{} - done'.format(thread_name)) # put a message into queue for GUI
|
gui_queue.put('{} - done'.format(thread_name)) # put a message into queue for GUI
|
||||||
|
|
||||||
|
|
||||||
###### ## ## ####
|
######## ## ## ####
|
||||||
## ## ## ## ##
|
## ## ## ## ##
|
||||||
## ## ## ##
|
## ## ## ##
|
||||||
## #### ## ## ##
|
## #### ## ## ##
|
||||||
## ## ## ## ##
|
## ## ## ## ##
|
||||||
## ## ## ## ##
|
## ## ## ## ##
|
||||||
###### ####### ####
|
######## ######### ####
|
||||||
|
|
||||||
def the_gui(gui_queue):
|
def the_gui(gui_queue):
|
||||||
|
|
||||||
|
@ -32,29 +53,27 @@ def the_gui(gui_queue):
|
||||||
|
|
||||||
window = sg.Window('Multithreaded Window').Layout(layout)
|
window = sg.Window('Multithreaded Window').Layout(layout)
|
||||||
# --------------------- EVENT LOOP ---------------------
|
# --------------------- EVENT LOOP ---------------------
|
||||||
message = None
|
|
||||||
count = 0
|
count = 0
|
||||||
while True:
|
while True:
|
||||||
event, values = window.Read(timeout=100) # wait for up to 100 ms for a GUI event
|
event, values = window.Read(timeout=100) # wait for up to 100 ms for a GUI event
|
||||||
if event is None or event == 'Exit':
|
if event is None or event == 'Exit':
|
||||||
break
|
break
|
||||||
if event == 'Go':
|
if event == 'Go': # clicking "Go" starts a long running work item by starting thread
|
||||||
window.Element('_OUTPUT_').Update('Starting long work %s'%count)
|
window.Element('_OUTPUT_').Update('Starting long work %s'%count)
|
||||||
# simulate STARTING long run by starting a thread
|
# STARTING long run by starting a thread
|
||||||
threading.Thread(target=worker_thread, args=('Thread %s'%count, gui_queue,), daemon=True).start()
|
threading.Thread(target=worker_thread, args=('Thread %s'%count, gui_queue,), daemon=True).start()
|
||||||
count += 1
|
count += 1
|
||||||
# --------------- Loop through all messages coming in from threads ---------------
|
# --------------- Read next message coming in from threads ---------------
|
||||||
try: # see if something has been posted to Queue
|
try:
|
||||||
message = gui_queue.get_nowait()
|
message = gui_queue.get_nowait() # see if something has been posted to Queue
|
||||||
except queue.Empty: # get_nowait() will get exception when Queue is empty
|
except queue.Empty: # get_nowait() will get exception when Queue is empty
|
||||||
pass # nothing in queue so do nothing
|
message = None # nothing in queue so do nothing
|
||||||
|
|
||||||
# if message received from queue, display the message in the Window
|
# if message received from queue, display the message in the Window
|
||||||
if message is not None:
|
if message is not None:
|
||||||
# this is the place you would execute code at ENDING of long running task
|
# this is the place you would execute code at ENDING of long running task
|
||||||
window.Element('_OUTPUT_').Update(message)
|
window.Element('_OUTPUT_').Update(message)
|
||||||
window.Refresh() # do a refresh because could be showing multiple messages before next Read
|
window.Refresh() # do a refresh because could be showing multiple messages before next Read
|
||||||
message = None
|
|
||||||
|
|
||||||
# if user exits the window, then close the window and exit the GUI func
|
# if user exits the window, then close the window and exit the GUI func
|
||||||
window.Close()
|
window.Close()
|
||||||
|
|
Loading…
Reference in New Issue