Search code examples
loopsprogram-entry-pointtk-toolkitpysimplegui

pysimpleGUI - creating a thread on the fly


I have created a GUI with PysimpleGUI that has multiple buttons, the intentionss is that users click on a button and continue to work on othe task while the action on the first clicked button is running, and when the action of the clicked button finished, then the thread exits (distroys the current thread),

the code is throwing : RuntimeError: main thread is not in main loop

Can someone help me create the _thread.start_new_thread process and incorporated to the main loop or maybe a solution to avoid RuntimeError

for threading i am using : _thread

the code:

class Windows:

    def newOpenGraph(self, window, event, values):
        '''
        opens a new graph with no problem
        '''

    def newThread(self, window, event, values):

        isRunning = True
        if event == 'OPEN GRAPH':
            _thread.start_new_thread(self.newOpenGraph, (window, event, values ))
        isRunning = False

        while isRunning:
            schedule.run_pending()
            time.sleep(1)

    def mainLayout(self):
        '''
        layout frame work
        '''

        while True:

            event, values = window.read()
            if event == 'OPEN GRAPH':
                # self.newOpenGraph(window, event, values)
                self.newThread(window, event, values)

the image:

enter image description here


Solution

  • Use library schedule in your thread, not in main loop, also no GUI update in your thread.

    Maybe code like this,

    import time
    import _thread
    import schedule
    import PySimpleGUI as sg
    
    def func(window):
        global i
        window.write_event_value('Update', i)
        i += 1
    
    def new_thread(window, event, values):
        global running
        schedule.every().second.do(func, window=window)
        running = True
        while running:
            schedule.run_pending()
            time.sleep(0.1)
    
    layout = [
        [sg.Button("New"), sg.Button('Exit')],
        [sg.Text('', size=40, key='STATUS')],
    ]
    
    window = sg.Window("Multithread", layout, finalize=True)
    i = 0
    threads = []
    while True:
    
        event, values = window.read(timeout=100)
    
        if event in (sg.WIN_CLOSED, 'Exit'):
            running = False
            break
        elif event == 'New':
            _thread.start_new_thread(new_thread, (window, event, values))
        elif event == 'Update':
            window['STATUS'].update(f'Index {values[event]}')
    
    window.close()