Reputation: 13
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
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:
Upvotes: 2