Im using PySimpleGui to make a simple file format conversion program, but the little window of my program keeps telling me (not responding) like if it was crushing while in reality it's working and its writing the new file.
The issue is the cycle, if i remove it everything works but the user doesnt have any response on the progression of the conversion. I reed some documentation on python threading and i think that everything should work, any tips? here's the code: `
def main():
sg.theme('DarkGrey3')
layout1 = [[sg.Text('File converter (.csv to sdf)')],
[sg.Frame('Input Filename',
[[sg.Input(key='-IN-'), sg.FileBrowse(), ],])],
[sg.Frame('Output Path',
[[sg.Input(key='-OUT-'), sg.FolderBrowse(), ],])],
[sg.Button('Convert'), sg.Button('Exit')], [sg.Text('', key='-c-')]]
window=sg.Window(title='.csv to .sdf file converter', layout=layout1, margins=(50, 25))
window.read()
while True:
event, values = window.read()
if event=='Exit' or event==None:
break
if event=='Convert':
csvfilepath=values['-IN-']
outpath=values['-OUT-']
x=threading.Thread(target=Converter, args=[csvfilepath, outpath])
x.start()
time.sleep(1)
while x.is_alive():
window['-c-'].Update('Conversion')
time.sleep(1)
window['-c-'].Update('Conversion.')
time.sleep(1)
window['-c-'].Update('Conversion..')
time.sleep(1)
window['-c-'].Update('Conversion...')
time.sleep(1)
`
CodePudding user response:
Your code is working as expected. The window is unresponsive because you have a while loop that is blocking the main thread. The main thread is responsible for handling events and updating the window.
There are a few ways to fix this. One is to move the while loop into a separate thread. Another is to use PySimpleGUI's built-in progress bar feature.
Here is an example of how to use a progress bar:
import PySimpleGUI as sg
layout = [[sg.Text('Progress Bar')],
[sg.ProgressBar(1000, orientation='h', size=(20, 20), key='progress')],
[sg.Cancel()]]
window = sg.Window('Window Title', layout)
progress_bar = window['progress']
for i in range(1000):
# update progress bar with loop value 1 so that bar reaches the end
event, values = window.read(timeout=0)
if event == 'Cancel' or event == sg.WIN_CLOSED:
break
progress_bar.UpdateBar(i 1)
window.close()
CodePudding user response:
Following code demo how to update GUI by timeout event and threading.
import time
import threading
import PySimpleGUI as sg
def convert_func(window):
for i in range(10): # Simuate the conversion
window.write_event_value('Conversion Step', i)
time.sleep(1)
window.write_event_value('Conversion Done', None)
layout = [
[sg.Button('Convert'), sg.Text('', expand_x=True, key='Step')],
[sg.StatusBar('', size=20, key='Status')],
]
window = sg.Window('Title', layout, finalize=True)
status, step = window['Status'], window['Step']
running, index, m = False, 0, 10
msg = ['Conversion' '.'*i for i in range(m)]
while True:
event, values = window.read(timeout=200)
if event == sg.WIN_CLOSED:
break
elif event == 'Convert':
threading.Thread(target=convert_func, args=(window,), daemon=True).start()
running = True
elif event == sg.TIMEOUT_EVENT and running:
status.update(msg[index])
index = (index 1) % m
elif event == 'Conversion Step':
print(event)
i = values[event]
step.update(f'Step {values[event]}')
elif event == 'Conversion Done':
running = False
step.update('')
status.update(event)
window.close()