user3772160
user3772160

Reputation: 13

How to show console output when running a python script from another python file

I am making a simple IDE with a text box and a run button. This asks the user to enter the filename, writes the code written to a file and runs that file. I want to show whatever is outputted from the console, such as a print, input, etc.. like IDE's do. Is this possible?

Here is my code:

from Tkinter import *
import tkFileDialog
import ScrolledText
import subprocess
filepath=""
def run():
    global filepath
    print "<<<<<<=====-------------Restart-------------=====>>>>>>"
    py=code.get(1.0,END)
    if filepath=="":
        filepath=tkFileDialog.asksaveasfilename()
        if ".py" not in filepath:
            filepath=filepath+".py"
    script=open(filepath, "w")
    script.write(py)
    script.close()
    p = subprocess.Popen(['python', filepath],
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT,
                         )
    for line in iter(p.stdout.readline, ''):
        print line
    print "<<<<<<=====-------------EXECUTION FINISHED-------------=====>>>>>>"
root = Tk()
code=ScrolledText.ScrolledText(root)
code.pack()
run=Button(root,text="Run", command=run)
run.pack()
root.mainloop()

Upvotes: 1

Views: 11264

Answers (1)

Jamie Cockburn
Jamie Cockburn

Reputation: 7555

Yes, just use the subprocess module.

Getting output in one go

import subprocess

output = subprocess.check_output(['python', filepath])

If you want to capture the standard error out of the called process as well as standard out use this instead:

output = subprocess.check_output(['python', filepath], stderr=subprocess.STDOUT)

Or if you want to capture them separately:

p = subprocess.Popen(['python', filepath],
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE,
                     )
out, err = p.communicate()

Getting the output as it's produced

This gives you the combined stdout and strerr output, line by line:

p = subprocess.Popen(['python', filepath],
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT,
                     )

for line in iter(p.stdout.readline, ''):
    # process the line

Keeping the UI responsive

If you run the above code on the same thread as your GUI, you are essentially blocking the Tk's event loop from running while you are waiting for each line. This means that though you are getting each line in real-time, and writing it to your GUI, it won't update the display until the event loop gets to run again, and process all your calls to Tk.

You need to run the subprocess code on a new thread, and in your GUI thread, periodically check for new input.

I've done an example based on yours for you, you can find it here:

http://pastebin.com/FRFpaeJ2

Upvotes: 2

Related Questions