un-buffered text output

Hello,

I'm new to wxPython, so I apologize if my question is ill formed of do
not make much sense.

I'm writing a GUI for for another python program that print messages to
stdout and stderr. O would like them to appear in a text box. After some
googling I found the following snippet that show the text:

···

------------------------------------------------------------------------
class RedirectText(object):
    def __init__(self, aWxTextCtrl):
        self.out = aWxTextCtrl

    def write(self, string):
        self.out.WriteText(string)

log = wx.TextCtrl(panel, wx.ID_ANY, size=(400,400), pos=(150,0),
style=wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)

# redirect text here
redir=RedirectText(log)
sys.stdout=redir
------------------------------------------------------------------------

However, the lines are buffered and the text does not show as expected,
they appear only after the program is finished. Is there a way to show
them as they appear?

I tried to call the flush method in the stdout, but that raises an error
for the Redirect class above.

Thanks, Filipe.

Try the attached demo.

Ray Pasco

LOGGING_TO_A_WX_TEXTCTRL.py (2.98 KB)

···

On Sun, Jul 3, 2011 at 10:11 AM, Filipe ocefpaf@gmail.com wrote:

Hello,

I’m new to wxPython, so I apologize if my question is ill formed of do

not make much sense.

I’m writing a GUI for for another python program that print messages to

stdout and stderr. O would like them to appear in a text box.

Thanks, I actually came across this example while googling for a
solution, but I could not understand it for my case.

I have a "run" button that call a third party python script. This
script uses print statements to inform the users of what is going on.
I would like to show those messages in a wxTextCtrl box, but the
messages only appears after the script is done. That gives the users a
different experience then running the script from the command line.

I'm attaching a stand alone example of what I'm saying.

Thanks again, Filipe.

run.py (1.99 KB)

third_party_script.py (204 Bytes)

···

On Sun, Jul 3, 2011 at 19:30, Ray Pasco <pascor22234@gmail.com> wrote:

On Sun, Jul 3, 2011 at 10:11 AM, Filipe <ocefpaf@gmail.com> wrote:

Hello,

I'm new to wxPython, so I apologize if my question is ill formed of do
not make much sense.

I'm writing a GUI for for another python program that print messages to
stdout and stderr. O would like them to appear in a text box.

Try the attached demo.

Ray Pasco

My guess is that the "other python program" is actually running in the same process as your GUI and that you are running it in the GUI thread, so while it is running it is blocking the main event loop from being able to process events, such as the paint events that your log window needs to process in order to draw the new text.

Take a look at these links. Basically you need to find a way to prevent your long running task from blocking the event loop, such as breaking it up into smaller tasks, running it in a separate thread or a separate process, etc.

http://wiki.wxpython.org/LongRunningTasks
http://wiki.wxpython.org/Non-Blocking_Gui
http://wiki.wxpython.org/CallAfter

···

On 7/3/11 7:11 AM, Filipe wrote:

Hello,

I'm new to wxPython, so I apologize if my question is ill formed of do
not make much sense.

I'm writing a GUI for for another python program that print messages to
stdout and stderr. O would like them to appear in a text box. After some
googling I found the following snippet that show the text:

------------------------------------------------------------------------
class RedirectText(object):
     def __init__(self, aWxTextCtrl):
         self.out = aWxTextCtrl

     def write(self, string):
         self.out.WriteText(string)

log = wx.TextCtrl(panel, wx.ID_ANY, size=(400,400), pos=(150,0),
style=wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)

# redirect text here
redir=RedirectText(log)
sys.stdout=redir
------------------------------------------------------------------------

However, the lines are buffered and the text does not show as expected,
they appear only after the program is finished. Is there a way to show
them as they appear?

--
Robin Dunn
Software Craftsman

Thanks, all those links were relevant to my project. For now I used
wx.Yield(), until I understand better threading.

Thanks again, Filipe.

···

On Mon, Jul 4, 2011 at 13:29, Robin Dunn <robin@alldunn.com> wrote:

On 7/3/11 7:11 AM, Filipe wrote:

Hello,

I'm new to wxPython, so I apologize if my question is ill formed of do
not make much sense.

I'm writing a GUI for for another python program that print messages to
stdout and stderr. O would like them to appear in a text box. After some
googling I found the following snippet that show the text:

------------------------------------------------------------------------
class RedirectText(object):
def __init__(self, aWxTextCtrl):
self.out = aWxTextCtrl

def write\(self, string\):
    self\.out\.WriteText\(string\)

log = wx.TextCtrl(panel, wx.ID_ANY, size=(400,400), pos=(150,0),
style=wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)

# redirect text here
redir=RedirectText(log)
sys.stdout=redir
------------------------------------------------------------------------

However, the lines are buffered and the text does not show as expected,
they appear only after the program is finished. Is there a way to show
them as they appear?

My guess is that the "other python program" is actually running in the same
process as your GUI and that you are running it in the GUI thread, so while
it is running it is blocking the main event loop from being able to process
events, such as the paint events that your log window needs to process in
order to draw the new text.

Take a look at these links. Basically you need to find a way to prevent
your long running task from blocking the event loop, such as breaking it up
into smaller tasks, running it in a separate thread or a separate process,
etc.

LongRunningTasks - wxPyWiki
http://wiki.wxpython.org/Non-Blocking_Gui
CallAfter - wxPyWiki

--
Robin Dunn
Software Craftsman
http://wxPython.org