I am trying to embed an interactive Python shell in a C# Windows Forms application, using Python.NET.
I was able to embed the interpreter in my C# application and access Python modules from .NET. I am now trying to redirect the output and errors from the Python interpreter to a .NET text box. While, I am able to redirect the standard output to a file, I am having trouble with routing the output to a text box.
This is what I have tried so far: The idea was to assign Python's sys.stdout to a .NET object that implements the same interface as a python stream (write(), writelines()...):
.NET class to mimic Python stream:
public class TextBoxStream : PyObject // To assign to sys.stdout. Is this correct?
{
private TextBox _output = null;
public TextBoxStream() {}
public TextBoxStream(TextBox output)
{
_output = output;
}
void write(object value)
{
_output.AppendText(value.ToString());
}
void writelines(object value)
{
}
}
In Form1.cs:
private void button1_Click(object sender, EventArgs e)
{
using (Py.GIL())
{
// Redirect stdout to text box
dynamic sys = PythonEngine.ImportModule("sys");
TextBoxStream textBoxStream = new TextBoxStream(textBox1);
sys.stdout = textBoxStream;
//sys.SetAttr("stdout", textBoxStream); // This did not work either
string code =
"import sys\n" +
"print 'Message 1'\n" +
"sys.stdout.write('Message 2')\n" +
"sys.stdout.flush()";
PyObject redirectPyObj = PythonEngine.RunString(code); // NULL
sys.stdout.write("Message 3");
// Exception thrown: 'Python.Runtime.PyObject' does not contain a definition for 'stdout'
}
}
This does not work either: redirectPyObj is NULL. I tried using the old as well as the new Python.NET API (with dynamic). Neither the sys.stdout.write nor the print statements write to the text box.
Any ideas on how to approach this would be very helpful.