I'm trying to redirect the sys.stdout stream to a wx.TextCtrl widget. In this code, i used ping but how to redirect results to wx.textctrl or statictext widgets. I can send variable from my input to wx.statictext but not able to get the stdout from ping results. hope someone here can help.
I'm using python 3.6.0 with wx 2.8.12.1
import wx
import os
class RandomPanel(wx.Panel):
def __init__(self, parent, color):
wx.Panel.__init__(self, parent)
self.SetBackgroundColour(color)
class MainPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
topSplitter = wx.SplitterWindow(self)
vSplitter = wx.SplitterWindow(topSplitter)
panelOne = RandomPanel(vSplitter, "white")
self.txt = wx.TextCtrl(panelOne,
style=wx.TE_PROCESS_ENTER,
pos=(7, 8), size=(330, 30))
self.txt.SetFocus()
self.txt.Bind(wx.EVT_TEXT_ENTER, self.ping)
panelTwo = RandomPanel(vSplitter, "white")
vSplitter.SplitVertically(panelOne, panelTwo)
vSplitter.SetSashGravity(0.5)
panelThree = RandomPanel(topSplitter, "black")
topSplitter.SplitHorizontally(vSplitter, panelThree)
topSplitter.SetSashGravity(0.5)
self.term = wx.StaticText(panelThree, -1, '', pos=(6, 100))
self.term.SetForegroundColour((255, 255, 255)) #set font color
self.term.SetBackgroundColour((0, 0, 0)) #set background color
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(topSplitter, 1, wx.EXPAND)
self.SetSizer(sizer)
def ping(self, event):
put = self.txt.GetValue()
self.p = os.system("ping -n 1 "+put)
self.term.SetLabel(put)
self.p.AppendText('>>> ')
self.p.AppendText(event)
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="ping tool",
size=(800, 600))
panel = MainPanel(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = MainFrame()
app.MainLoop()
Replace import os
with from subprocess import call, Popen, PIPE, STDOUT
Then replace
self.p = os.system("ping -n 1 "+put)
self.term.SetLabel(put)
self.p.AppendText('>>> ')
self.p.AppendText(event)
with
comm = Popen(['ping',put],stdout=PIPE,stderr=STDOUT,universal_newlines=True)
for i in iter(comm.stdout.readline, b''):
if i != '': pass
else: break
self.term.SetLabel(str(i))
wx.Yield()
This will read the output from the ping command, output it and then call Yield
to allow the wx.App() mainloop to update the screen from within the for
loop
You will probably want to put a stop mechanism in there at some point.
Edit:
To create a set of rolling results, I would change self.term
from a StaticText
to a TextCtrl
self.term = wx.TextCtrl(panelThree, -1, '',size=(400,200),style=wx.TE_MULTILINE)
and then in the ping
routine change SetLabel
to AppendText
def ping(self, event):
put = self.txt.GetValue()
comm = Popen(['ping',put],stdout=PIPE,stderr=STDOUT,universal_newlines=True)
for i in iter(comm.stdout.readline, b''):
if i != '': pass
else: break
self.term.AppendText(str(i))
wx.Yield()