2

有很多与此非常相似的问题,但我找不到一个专门适用于我正在尝试做的事情的问题。

我有一个正在为其编写 GUI 的模拟(用 SimPy 编写),模拟的主要输出是文本 - 从“打印”语句到控制台。现在,我认为最简单的方法是创建一个单独的模块 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 保持响应,并且所有文本仅来自导入的模块。

(另外,关于停止按钮的第二个问题 - 只是杀死模拟线程是不好的形式吗?)。

谢谢,

邓肯

4

2 回答 2

0

我建议查看这篇关于长期运行任务的 WX wiki 文章

它专门解决了您使用“开始”按钮处理长时间运行的过程的情况。使用不同的技术(如线程和空闲处理程序)给出了几个不同的示例。

于 2012-11-16T11:23:10.853 回答
-1

我认为您必须将标准输出重定向到日志文件(或简单的 SQLite 数据库?),然后使用您的线程检查日志文件的更新,然后使用 wx.CallAfter 或类似方法将其传递给 GUI。您可能可以使用类似 Python 中构建的套接字服务器:http ://wiki.wxpython.org/AsynchronousSockets 。我认为 wxPython Cookbook 也提到了一些关于使用 RPC 服务器的内容(可能是这个:http ://docs.python.org/library/simplexmlrpcserver.html ),但我不记得细节了。

您还应该尝试在 wxPython 官方邮件列表上提问。他们在那边非常友好。

于 2012-04-17T14:48:59.687 回答