I’m using a similar method for redirecting Python output to a .NET textBox:
#----------------------------------------------------------
public static void redirectPythonOutput(TextWriter writer)
{
Output output = new Output(writer);
using (Py.GIL())
{
dynamic sys = Py.Import("sys");
sys.stdout = output;
sys.stderr = output;
}
}
#----------------------------------------------------------
where ‘Output’ is my own .NET class that implements the method expected of a
Python file object:
#----------------------------------------------------------
public class Output
{
private TextWriter myWriter = null;
// ctor
public Output(TextWriter writer)
{
myWriter = writer;
}
public void write(String str)
{
str = str.Replace("\n", Environment.NewLine);
if (myWriter != null)
{
myWriter.Write(str);
}
else
{
Console.Write(str);
}
}
public void writelines(String[] str)
{
foreach (String line in str)
{
if (myWriter != null)
{
myWriter.Write(str);
}
else
{
Console.Write(str);
}
}
}
public void flush()
{
if (myWriter != null)
{
myWriter.Flush();
}
}
public void close()
{
if (myWriter != null)
{
myWriter.Close();
}
}
}
#----------------------------------------------------------
and I pass an instance of my TextBoxStreamWriter class to the constructor of
Output:
#----------------------------------------------------------
public class TextBoxStreamWriter : TextWriter
{
TextBox myTextBox = null;
// ctor
public TextBoxStreamWriter(TextBox textBox)
{
myTextBox = textBox;
}
// TODO: isn't this inefficient? Should we supply a method to write
a string?
public override void Write(char value)
{
base.Write(value);
MethodInvoker action = delegate
{
myTextBox.AppendText(value.ToString());
};
myTextBox.BeginInvoke(action);
}
public override System.Text.Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}
#----------------------------------------------------------
On May 27, 2016, at 5:40 PM, Saparya K <[email protected]> wrote:
> Just in case someone stumbles on this post looking for an answer:
>
> A solution that worked for me was redirecting the Python stdout/stderr to a
> stream in Python. I was then able to route this stream into the .NET text box.
>
> private void button1_Click(object sender, EventArgs e)
> {
> using
> (Py.GIL())
> {
> // Redirect stdout to text box
> dynamic sys = PythonEngine.ImportModule("sys");
>
> string codeToRedirectOutput =
> "import sys\n" +
> "from io import StringIO\n" +
> "sys.stdout = mystdout = StringIO()\n" +
> "sys.stdout.flush()\n" +
> "sys.stderr = mystderr = StringIO()\n" +
> "sys.stderr.flush()\n";
>
> PythonEngine.RunString(codeToRedirectOutput);
>
>
> // Run Python code
> string pyCode = "print(1 + 2)";
> PyObject result = PythonEngine.RunString(pyCode); // null in case of error
> if (result != null)
> {
> string pyStdout = sys.stdout.getvalue(); // Get stdout
> pyStdout
> = pyStdout.Replace("\n", "\r\n"); // To support newline for textbox
> textBox1
> .Text = pyStdout;
> }
> else
> {
> PythonEngine.PrintError(); // Make Python engine print errors
> string pyStderr = sys.stderr.getvalue(); // Get stderr
> pyStderr = pyStderr.Replace("\n", "\r\n"); // To support newline
> for textbox
>
> textBox1.Text = pyStderr;
> }
> }
> }
> With this code, I was able to redirect the stdout (and stderr in the case of
> an error) from the Python engine to a .NET text box.
>
>
> On Wed, May 18, 2016 at 12:02 AM, Saparya K <[email protected]> wrote:
> Hi Denis,
> Thanks for pointing me to the new API. I am now able to embed Python in my C#
> code and access Python classes and methods from C#!
>
> Hi Nils,
> Your application looks very interesting and some of the features (e.g.
> matplotlib integration) are on the lines of what I have been thinking about.
> I am far from there though and will need to learn more before I can follow
> all the code in your wrapper!
>
> -----
>
> As of now, I am trying to redirect the output from the Python interpreter to
> a .NET text box. While I am able to redirect the output to a file, I am
> having trouble with routing the output to a text box.
>
> I first tried to redirect the console output to a custom TextWriter using
> Console.SetOut in C#:
>
> private void Form1_Load(object sender, EventArgs e)
> {
> _writer = new TextBoxWriter(this.textBox1);
> Console.SetOut(_writer); // Redirect stdout to custom TextWriter that
> writes to the text box
> }
>
> This did not work: while output from C# is routed to the text box, output
> from Python is not.
>
> -----
>
> I then thought that maybe I need to redirect the Python stdout instead of the
> C# standard output. 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());
>
> }
>
> }
> 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; // This is probably not theright way?
>
>
> //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); // returns 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.
>
> Thanks,
> Saparya
>
>
> On Tue, May 17, 2016 at 3:33 AM, Nils Becker <[email protected]> wrote:
> Hey,
>
> a while ago I wrote something like a light wrapper around Python.NET to embed
> CPython with numpy/scipy in a .NET GUI. It manages local/global dictionaries,
> automatically converts simple data types and numpy arrrays<->C# arrays and
> provides a plotting widget in C# that shows matplotlib plots. It also has
> some other convenience functions.
>
> The code is by no means complete, fully tested or even nice. However, for me
> it works.
>
> I uploaded it to github: https://github.com/Lodomir/PythonInterface
> As it demonstrates some not-well documented use of Python.NET, I thought it
> maybe nice to share the code.
>
> You will need to add the references to Python.NET to build the main project
> (PythonInterface) and additionally to the PythonInterface-DLL to build the
> examples.
>
> Cheers
> Nils
>
> 2016-05-13 22:04 GMT+02:00 Denis Akhiyarov <[email protected]>:
> for embedding look at c# embedding unit tests and also here:
>
> 1. Old API:
>
> http://pythonnet.github.io/readme.html
>
> 2. New simplified API using dynamic:
>
> https://github.com/pythonnet/pythonnet/blob/master/README.md
>
>
>
> On Thu, May 12, 2016 at 4:16 PM, Saparya K <[email protected]> wrote:
> Thanks for your response, Denis.
>
> I had not come across Sho earlier. It looks very interesting. (If only Python
> 3.x support was available, though it does look like they have added support
> for their own math and visualization libraries).
>
> I am going over the demos and the unit tests and I was able to write a simple
> console application to access .NET objects from Python. This is very
> encouraging!
> I am still figuring out how to embed Python code in my C# WinForms
> application (instead of a console application).
>
> I will continue my experiments, but in the meantime if you or anyone else has
> any ideas on how to redirect the result from the Python interpreter (say, to
> a rich text box), I would love to hear them. That is one part of the puzzle
> that is unclear to me.
>
> Thanks,
> Saparya
>
> On Wed, May 11, 2016 at 4:01 PM, Denis Akhiyarov <[email protected]>
> wrote:
> This is definitely possible with WinForms or WPF. See the demo folder in
> pythonnet repo. One of the demo's is still in pull request.
>
> You should probably just try running previous IronPython attempts using
> pythonnet and report issues if any. Have a look at Sho from Microsoft.
>
> There is someone trying to embed ipython REPL using pythonnet/Excel-DNA or
> COM in Excel with Custom Task Pane (CTP) written in WinForms:
>
> https://groups.google.com/forum/#!topic/jupyter/CVht4orvQtc
>
>
>
>
>
> On Wed, May 11, 2016 at 4:44 PM, Saparya K <[email protected]> wrote:
> Hello PythonNet,
>
> I am looking to embed a Python interactive (REPL) shell in a .NET WinForms
> application.
> This C# application displays a graphical visualization of some data. Methods
> to manipulate the data in the C# application would be exposed via a Python
> API.
> The idea is to be able to interact with the data from the Python shell via
> the API, and thereby updating the graphical view.
>
> Ideally, the shell should support any valid Python syntax that is required to
> use the API. This would involve:
> • Querying a collection of data from the application via the Python API
> • Then manipulating this collection in the Python shell
> • Making API calls with the modified collection as an argument
> I came across a few examples where an interactive shell was developed using
> IronPython. A limitation with this approach is the absence of Python 3.x
> support (and other C-compiled libraries) in IronPython. For this reason, I
> would prefer to use Python.NET if it is possible.
>
> Has anyone here tried something like this with Python.NET before? Does it
> looks like what I am trying to achieve is feasible?
>
> Any direction would be very helpful!
>
> _________________________________________________
> Python.NET mailing list - [email protected]
> https://mail.python.org/mailman/listinfo/pythondotnet
>
>
> _________________________________________________
> Python.NET mailing list - [email protected]
> https://mail.python.org/mailman/listinfo/pythondotnet
>
>
> _________________________________________________
> Python.NET mailing list - [email protected]
> https://mail.python.org/mailman/listinfo/pythondotnet
>
>
> _________________________________________________
> Python.NET mailing list - [email protected]
> https://mail.python.org/mailman/listinfo/pythondotnet
>
>
> _________________________________________________
> Python.NET mailing list - [email protected]
> https://mail.python.org/mailman/listinfo/pythondotnet
>
>
> _________________________________________________
> Python.NET mailing list - [email protected]
> https://mail.python.org/mailman/listinfo/pythondotnet
… Cameron
_________________________________________________
Python.NET mailing list - [email protected]
https://mail.python.org/mailman/listinfo/pythondotnet