将sys.stdout从ping结果重定向到wx.TextCtrl小部件

时间:2017-11-13 03:22:16

标签: python python-3.x wxpython

我正在尝试将sys.stdout流重定向到wx.TextCtrl小部件。在这段代码中,我使用了ping,但是如何将结果重定向到wx.textctrl或statictext小部件。我可以将输入中的变量发送到wx.statictext但不能从ping结果中获取stdout。希望有人可以提供帮助。

我正在使用python 3.6.0和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()

2 个答案:

答案 0 :(得分:0)

import os替换为from subprocess import call, Popen, PIPE, STDOUT 然后替换

self.p = os.system("ping -n 1 "+put)
self.term.SetLabel(put)
self.p.AppendText('>>> ')
self.p.AppendText(event)

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()

这将读取ping命令的输出,输出它然后调用Yield以允许wx.App()mainloop从for循环中更新屏幕

您可能希望在某些时候在其中设置停止机制。

编辑: 要创建一组滚动结果,我会将self.termStaticText更改为TextCtrl

self.term = wx.TextCtrl(panelThree, -1, '',size=(400,200),style=wx.TE_MULTILINE)

然后在ping例程中将SetLabel更改为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()

答案 1 :(得分:0)

@Rolf of Saxony,我已经更新了代码感谢您的帮助。

def ping(self, event):
        a = []
        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
            a.append(str(i))
            self.term.SetLabelText("start pinging......")
        self.term.SetLabelText("\n".join(a))
        wx.Yield()