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 <spry...@gmail.com> 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 <spry...@gmail.com> 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 <nilsc.bec...@gmail.com> 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 <denis.akhiya...@gmail.com>:
> 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 <spry...@gmail.com> 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 <denis.akhiya...@gmail.com> 
> 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 <spry...@gmail.com> 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 - PythonDotNet@python.org
> https://mail.python.org/mailman/listinfo/pythondotnet
> 
> 
> _________________________________________________
> Python.NET mailing list - PythonDotNet@python.org
> https://mail.python.org/mailman/listinfo/pythondotnet
> 
> 
> _________________________________________________
> Python.NET mailing list - PythonDotNet@python.org
> https://mail.python.org/mailman/listinfo/pythondotnet
> 
> 
> _________________________________________________
> Python.NET mailing list - PythonDotNet@python.org
> https://mail.python.org/mailman/listinfo/pythondotnet
> 
> 
> _________________________________________________
> Python.NET mailing list - PythonDotNet@python.org
> https://mail.python.org/mailman/listinfo/pythondotnet
> 
> 
> _________________________________________________
> Python.NET mailing list - PythonDotNet@python.org
> https://mail.python.org/mailman/listinfo/pythondotnet

… Cameron



_________________________________________________
Python.NET mailing list - PythonDotNet@python.org
https://mail.python.org/mailman/listinfo/pythondotnet

Reply via email to