22import queue
33import threading
44import time
5-
65import 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+ # ---------------------------------------
928def 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
2647def 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