3

Is there any way to use subprocess.call() or subprocess.Popen() and interact with the stdin via Tkinter's Entry widget, and output the stdout to a Text widget?

Im not really sure how to approach something like this, as i am new to using the subprocess module.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
IT Ninja
  • 6,174
  • 10
  • 42
  • 65
  • wow haha, first time one of my questions went on without even a comment for a day ;P – IT Ninja Jun 05 '12 at 12:10
  • 1
    There are plenty of answers on SO and elsewhere (e.g. http://stackoverflow.com/questions/665566/python-tkinter-shell-to-gui) for redirecting stdout to Tkinter widgets. However, I also would like to know how to pass stdin to the subprocess from a GUI widget if anyone happens to know! – Jdog Jun 05 '12 at 12:54
  • Yeah, i wanna know how to get the STDIN to work (That would be awsome! xD) but ty for the link :) – IT Ninja Jun 05 '12 at 13:25

1 Answers1

2

Think I've got the basics of using an Entry as stdin to subprocess. You may have to jiggle it about for your own needs (re: output to Text widget).

This example calls a test script:

# test.py:

#!/usr/bin/env python
a = raw_input('Type something!: \n') #the '\n' flushes the prompt
print a

that simply requires some input (from sys.stdin) and prints it.

Calling this and interacting with it via a GUI is done with:

from Tkinter import *
import subprocess

root = Tk() 

e = Entry(root)
e.grid()

b = Button(root,text='QUIT',command=root.quit)
b.grid()

def entryreturn(event):
    proc.stdin.write(e.get()+'\n') # the '\n' is important to flush stdin
    e.delete(0,END)

# when you press Return in Entry, use this as stdin 
# and remove it
e.bind("<Return>", entryreturn)

proc = subprocess.Popen('./test.py',stdin=subprocess.PIPE)

root.mainloop()

Now whatever is typed into Entry e (followed by the Return key), is then passed via stdin to proc.

Hope this helps.


Also check this for ideas about stdout of subprocess question. You'll need to write a new stdout to redirect stdout to the textwidget, something like:

class MyStdout(object):
    def __init__(self,textwidget):
        self.textwidget = textwidget
    def write(self,txt):
        self.textwidget.insert(END,txt)

sys.stdout = MyStdout(mytextwidget)

but I would recommend reading other examples where people have achieved this.

Community
  • 1
  • 1
Jdog
  • 10,071
  • 4
  • 25
  • 42
  • replacing `sys.stdout` with Python object won't affect `subprocess`' stdout, see [this answer](http://stackoverflow.com/a/22434262/4279). To display subprocess' stdout in a GUI widget, see [this answer](http://stackoverflow.com/a/32682520/4279) – jfs Sep 20 '15 at 18:30