Search code examples
pythontkinterexecsys

Kill program run with exec(open(file).read()) in python


In my code I am calling a pipeline from a tkinter gui. When the user presses the Run button the entire pipeline starts running. If certain settings are selected a toplevel of the main GUI is called which asks for an aditional file. This all works except when the cancel button or the close window X is pressed. The toplevel closes but the program keeps running. Eventually it will crash because the file is absent. calling sys.exit() isn't the solution because then the entire gui shuts down and I only want the specific toplevel to close and to stop the running file.

How do I kill a file running with exec(open(file).read()) without killing the entire program?


Solution

  • Honestly, you probably shouldn't use exec at all, but assuming you do, exec is still running in the same process and thread as your main program, there's no exiting it without killing the main program.

    You should open it in another process, subprocess or thread. Since your exec seem to be running python code, you could simply use:

    from subprocess import Popen
    p = Popen(['python', filename'])
    

    And then it runs in the background, your normal process continues, and you can kill it at any point with .

    p.kill()
    

    It gets more complicated than that if you want to give that process input or read out its output, but that's a matter for a different question. You can start here to see how to read the output: Store output of subprocess.Popen call in a string

    A small example to get the output would be something like this:

    from subprocess import Popen, PIPE
    p = Popen(['python', filename], stdout=PIPE, stderr=PIPE)
    output, errors = p.communicate()
    

    However this will wait until the process completes its run, so maybe start all that from another thread, or find another way to get the output (perhaps to a log file)

    Notice I used just 'python' in Popen, if the python executable is not in your path or has a different name, you should replace that with the full path to the executable