一个wxpython输出到TextCtrl的小优化

在界面上,有个查看执行结果的文本框,叫result,类型是TextCtrl,每次要把操作结果输出到result上边,需要调用:

1
result.AppendText(your_str+'\n')

而且,因为我把事件的绑定方法分离到另外的Py模块,调用过程是这样的:

1
2
3
def test_func(evt):
evt.GetEventObject().GetParent().result.AppendText("hello world\n")
# do something

需要手动换行,而且这样代码量挺多。
所以想了一个办法,定义了一个output方法:

1
2
3
4
5
6
def output(evt, astr, newline=True):
result = evt.GetEventObject().GetParent().result
if newline:
result.AppendText(astr+"\n")
else:
result.AppendText(astr)

所以上边的调用就简化为:

1
2
3
def test_func(evt):
output(evt, "hello world")
# do something

一开始用着挺好,后来发现一个新的问题,因为在do something的时候,大量使用了之前封装好的函数,原来的函数里边,都是使用print来打印执行过程中的一些调试信息和中间数据,运行的时候,并不会输出到result上边去。
对于之前的函数,也不能去碰里边的print语句,别的地方还用着呢。

想来想去,一个新的方式,重定向 sys.stdout,把所有print的内容,统统输出到result上边去。

修改定义result的ADKit类,新增一个write方法:

1
2
3
class ADKit(wx.Panel):
def write(self,astr):
self.result.AppendText(astr)

在初始化ADKit之后,重定向sys.stdout:

1
2
adkit = ADKit(None)
sys.stdout = adkit

删除output函数。
现在之前的调用更加简化了:

def test_func(evt):
    print "hello world"
    # do something