有很多与此非常相似的问题,但我找不到专门适用于我正在尝试做的事情的问题。
我有一个模拟(用 SimPy 编写),我正在为其编写 GUI,模拟的主要输出是文本 - 从“打印”语句到控制台。现在,我认为最简单的方法是创建一个单独的模块 GUI.py,并将我的模拟程序导入其中:
import osi_model
我希望所有的打印语句都被 GUI 捕获并出现在 Textctrl 中,这里有无数的例子,沿着这些行:
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
<general frame initialisation stuff..>
redir=RedirectText(self.txtCtrl_1)
sys.stdout=redir
class RedirectText:
def __init__(self,aWxTextCtrl):
self.out=aWxTextCtrl
def write(self,string):
self.out.WriteText(string)
我也从“开始”按钮开始我的模拟:
def go_btn_click(self, event):
print 'GO'
self.RT = threading.Thread(target=osi_model.RunThis())
self.RT.start()
一切正常,模拟模块的输出由 TextCtrl 捕获,除了 GUI 锁定并变得无响应 - 我仍然需要它可以访问(至少有一个“停止”按钮) .我不确定这是否是我在这里创建新线程的拙劣尝试,但我假设在此过程的某个阶段将需要一个新线程。
人们建议使用 wx.CallAfter,但考虑到导入的模块不知道 wx,我不确定如何去做,而且我也不能现实地遍历整个模拟架构并更改所有打印wx.CallAfter 语句,任何从导入的模拟程序内部捕获 shell 的尝试都会导致程序崩溃。
有人对我如何才能最好地实现这一目标有任何想法吗?所以我真正需要的是让 TextCtrl 捕获所有控制台文本,同时 GUI 保持响应,并且所有文本仅来自导入的模块。
(另外,关于“停止”按钮的次要问题 - 仅终止模拟线程是否是一种不好的形式?)。
谢谢,
邓肯
请您参考如下方法:
我建议查看此 WX wiki article about long running tasks .
它专门解决了您正在使用“开始”按钮处理长时间运行的过程的情况。使用线程和空闲处理程序等不同技术给出了几个不同的示例。
