My program freezes until the CMD command finishes ( Python 3 )

Question:

when I run my program and press a button, the function it has to do is performed, but the problem is that I cannot use the program until the function of the button I press has finished, it stays in "program does not respond", once the function of the pressed button is finished I can use the program normally

import os 
from time import sleep
import PySimpleGUI as sg 
import subprocess
sg.theme('DarkAmber')
button_size = (16, 1)
layout = [[sg.Text("RECUERDE EJECUTAR EL PROGRAMA COMO ADMINISTRADOR",key="-WINNER-")], [sg.Button("HERRAMIENTA SFC", key="SFC", size=(button_size)), sg.Button("HERRAMIENTA DISM", key="-DISM-"), sg.Button("VER LICENCIA ", key="-KEY-",size=(button_size))],
          [sg.Text("", key="-AVISO-")],
          [sg.Button("Cerrar Programa", key="-OK-")]]

window = sg.Window("PROGRAMA CORREGIR SISTEMA OPERATIVO", layout) 

def main(window):
    while True:
        event, values = window.read()  
        if event == sg.WIN_CLOSED or event == "-OK-":
            break 

        # Acá estan las herramientas que solucionen problemas del SISTEMA OPERATIVO
        if event == "SFC":
            sg.popup("Se ejecutará la herramienta DISM El proceso seguirá aunque el programa parezca congelado") 
            window.Element("-AVISO-").Update("Se ejecutará la herramienta SFC /scannow El proceso seguirá aunque el programa parezca congelado")
            os.system("sfc /scannow") 
            window.Element("-AVISO-").Update("Ha finalizado...")  

        if event == "-DISM-":
            sg.popup("Se ejecutará la herramienta DISM El proceso seguirá aunque el programa parezca congelado") 
            window.Element("-AVISO-").Update("Se ejecutará la herramienta DISM El proceso seguirá aunque el programa parezca congelado")
            os.system("DISM /Online /Cleanup-Image /CheckHealth")
            sg.popup_auto_close('ETAPA 1/3 FINALIZADO, el programa parecerá congelado pero el proceso seguirá.')
            os.system(" DISM /Online /Cleanup-Image /ScanHealth")
            sg.popup_auto_close('ETAPA 2/3 FINALIZADO, el programa parecerá congelado pero el proceso seguirá.')
            os.system("DISM /Online /Cleanup-Image /RestoreHealth") 
            window.Element("-AVISO-").Update("Etapa 3/3 finalizada, recomendamos usar SFC SCANNOW y/o reiniciar la PC") 

        if event == "-KEY-":
            sg.popup("A continuación WINDOWS verificará el estado de tu licencia")
            subprocess.call("slmgr/dli", shell=True)
            sg.popup("Proceso finalizado")

        if __name__ == "__main__":
            main(window)
Asked By: elmaxiRT

||

Answers:

Almost all GUI frameworks are based on an event loop; that would be the while True and event, values = window.read() in your code. Nothing in the GUI will respond unless that loop is running in a timely fashion. Anything that blocks the loop, such as os.system or subprocess.call will make the GUI hang for a while.

Answered By: Mark Ransom

Check following function/method/library, they may help you.

  • Function execute_command_subprocess

Runs the specified command as a subprocess.
By default the call is non-blocking.
The function will immediately return without waiting for the process to complete running. You can use the returned Popen object to communicate with the subprocess and get the results.
Returns a subprocess Popen object.

  • Method perform_long_operation of Window

Call your function that will take a long time to execute. When it’s complete, send an event specified by the end_key.

Starts a thread on your behalf.

This is a way for you to "ease into" threading without learning the details of threading.
Your function will run, and when it returns 2 things will happen:

  1. The value you provide for end_key will be returned to you when you call window.read()
  2. If your function returns a value, then the value returned will also be included in your windows.read call in the values dictionary

IMPORTANT – This method uses THREADS… this means you CANNOT make any PySimpleGUI calls from the function you provide with the exception of one function, Window.write_event_value.

  • Use threading library

Remember not to update GUI not in main thread, call method write_event_value of Window to generate an event in your thread and handle it in your event loop to update the GUI.

Answered By: Jason Yang
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.