71 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from queue import Queue
 | |
| from threading import Thread
 | |
| from time import sleep
 | |
| 
 | |
| import PySimpleGUI as sg
 | |
| 
 | |
| """
 | |
|     DESIGN PATTERN - Multithreaded GUI
 | |
|     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
 | |
|     
 | |
| """
 | |
| 
 | |
| 
 | |
| def worker_thread(thread_name, run_freq,  gui_queue):
 | |
|     """
 | |
|     A worker thrread that communicates with the GUI
 | |
|     These threads can call functions that block withouth affecting the GUI (a good thing)
 | |
|     :param thread_name: Text name used  for displaying info
 | |
|     :param run_freq: How often the thread should run in milliseconds
 | |
|     :param gui_queue: Queue used to communicate with the GUI
 | |
|     :return:
 | |
|     """
 | |
|     print('Strarting thread - ', thread_name)
 | |
|     i = 0
 | |
|     while True:
 | |
|         sleep(run_freq/1000)
 | |
|         gui_queue.put('{} - {}'.format(thread_name, i))
 | |
|         i += 1
 | |
| 
 | |
| 
 | |
| def the_gui(gui_queue):
 | |
|     """
 | |
|     starts and executes the GUI.  Returns when the user exits / closes the window
 | |
|     reads data from a Queue and displays the data
 | |
|     :param gui_queue: Queue the GUI should read from
 | |
|     :return:
 | |
|     """
 | |
|     layout = [ [sg.Text('Your GUI Window')],
 | |
|                [sg.Text('', size=(15,1), key='_OUTPUT_')],
 | |
|                [sg.Button('Exit')],]
 | |
| 
 | |
|     window = sg.Window('Window Title').Layout(layout)
 | |
| 
 | |
|     while True:             # Event Loop
 | |
|         event, values = window.Read(timeout=200)        # wait for up to 200 ms for a GUI event
 | |
|         if event is None or event == 'Exit':
 | |
|             break
 | |
|         #--------------- Handle stuff coming in from threads ---------------
 | |
|         try:                    # see if something has been posted to Queue
 | |
|             message = gui_queue.get_nowait()
 | |
|         except:
 | |
|             message = None      # indicate nothing posted
 | |
|         # if message received from queue, display the message in the Window
 | |
|         if message:
 | |
|             window.Element('_OUTPUT_').Update(message)
 | |
| 
 | |
|     # if user exits the window, then close the window and exit
 | |
|     window.Close()
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     #-- Create a Queue to communicate with GUI --
 | |
|     gui_queue = Queue()             # queue used to communicate between the gui and the worker
 | |
|     #-- 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.start()
 | |
|     thread = Thread(target=worker_thread, args=('Thread 2', 500, gui_queue,),  daemon=True)
 | |
|     thread.start()
 | |
|     #-- Start the GUI passing in the Queue --
 | |
|     the_gui(gui_queue)
 |