Skip to content

Commit 3ce0e8e

Browse files
Lots of comments
1 parent e3286ae commit 3ce0e8e

File tree

1 file changed

+32
-13
lines changed

1 file changed

+32
-13
lines changed

DemoPrograms/Demo_Threaded_Work.py

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,47 @@
22
import queue
33
import threading
44
import time
5-
65
import PySimpleGUI as sg
76

8-
# Put your long-running code in here
7+
"""
8+
Demo on how to add a long-running item to your PySimpleGUI Event Loop
9+
If you want to do something that takes a long time, and you do it in the
10+
main event loop, you'll quickly begin to see messages from windows that your
11+
program has hung, asking if you want to kill it.
12+
13+
The problem is not that your problem is hung, the problem is that you are
14+
not calling Read or Refresh often enough.
15+
16+
One way through this, shown here, is to put your long work into a thread that
17+
is spun off, allowed to work, and then gets back to the GUI when it's done working
18+
on that task.
19+
20+
If you have multiple long tasks to run, then you'll want a more sophisticated
21+
format to your messages going back to the GUI so you'll know which task finished
22+
"""
23+
24+
25+
# ---------------------------------------
26+
# Put your long-running code in here #
27+
# ---------------------------------------
928
def worker_thread(thread_name, gui_queue):
1029
print('Starting thread - {} '.format(thread_name))
1130
# this is our "long running function call"
1231
time.sleep(5) # sleep for a while
32+
print('Ending thread - {} '.format(thread_name))
1333

1434
# at the end of the work, before exiting, send a message back to the GUI indicating end
35+
# in this case, we're using a simple string
1536
gui_queue.put('{} - done'.format(thread_name)) # put a message into queue for GUI
1637

1738

18-
###### ## ## ####
39+
######## ## ## ####
1940
## ## ## ## ##
2041
## ## ## ##
2142
## #### ## ## ##
2243
## ## ## ## ##
2344
## ## ## ## ##
24-
###### ####### ####
45+
######## ######### ####
2546

2647
def the_gui(gui_queue):
2748

@@ -32,29 +53,27 @@ def the_gui(gui_queue):
3253

3354
window = sg.Window('Multithreaded Window').Layout(layout)
3455
# --------------------- EVENT LOOP ---------------------
35-
message = None
3656
count = 0
3757
while True:
3858
event, values = window.Read(timeout=100) # wait for up to 100 ms for a GUI event
3959
if event is None or event == 'Exit':
4060
break
41-
if event == 'Go':
61+
if event == 'Go': # clicking "Go" starts a long running work item by starting thread
4262
window.Element('_OUTPUT_').Update('Starting long work %s'%count)
43-
# simulate STARTING long run by starting a thread
63+
# STARTING long run by starting a thread
4464
threading.Thread(target=worker_thread, args=('Thread %s'%count, gui_queue,), daemon=True).start()
4565
count += 1
46-
# --------------- Loop through all messages coming in from threads ---------------
47-
try: # see if something has been posted to Queue
48-
message = gui_queue.get_nowait()
49-
except queue.Empty: # get_nowait() will get exception when Queue is empty
50-
pass # nothing in queue so do nothing
66+
# --------------- Read next message coming in from threads ---------------
67+
try:
68+
message = gui_queue.get_nowait() # see if something has been posted to Queue
69+
except queue.Empty: # get_nowait() will get exception when Queue is empty
70+
message = None # nothing in queue so do nothing
5171

5272
# if message received from queue, display the message in the Window
5373
if message is not None:
5474
# this is the place you would execute code at ENDING of long running task
5575
window.Element('_OUTPUT_').Update(message)
5676
window.Refresh() # do a refresh because could be showing multiple messages before next Read
57-
message = None
5877

5978
# if user exits the window, then close the window and exit the GUI func
6079
window.Close()

0 commit comments

Comments
 (0)