wxpython:将文本动态重定向到文本控件框

时间:2012-01-03 12:41:47

标签: python wxpython fortran

以下采样代码适用于我目前正在制作的GUI。我有两个问题。第一个问题是当我使用RedirectText类重定向python输出时,仅当循环结束时,输出才会打印在TextCtrl框('tc2')上,用于该特定迭代。如何在循环中打印文本而不是在完成时打印?

我的第二个问题是我正在使用编译的fortran文件EHSS_updated_atoms.out此文件的输出打印到终端而不是文本控制框。如何将编译的fortran文件的输出到文本控制框?因为它被打印到终端。

import wx
class RedirectText(object):
    def __init__(self,aWxTextCtrl):
        self.out=aWxTextCtrl

    def write(self,string):
        self.out.WriteText(string)



def __init__(self, *args, **kwargs):
    super(Example, self).__init__(*args, **kwargs) 

    self.InitUI()
    self.Centre()
    self.Show() 
    self.SetSize((800, 600))
    self.SetTitle('Hello')

def InitUI(self):
    import sys

    vbox = wx.BoxSizer(wx.VERTICAL)
    hbox5 = wx.BoxSizer(wx.HORIZONTAL)
    btn1 = wx.Button(panel, label='Run prog')
    hbox5.Add(btn1)
    btn2 = wx.Button(panel, label='Stop prog')
    hbox5.Add(btn2, flag=wx.LEFT|wx.BOTTOM, border=5)
    vbox.Add(hbox5, flag=wx.ALIGN_CENTER|wx.RIGHT, border=10)
    self.Bind(wx.EVT_BUTTON, self.prog, btn1)
    #self.Bind(wx.EVT_BUTTON, self.cancel_prog, btn2)


    hbox3 = wx.BoxSizer(wx.HORIZONTAL)
    tc2 = wx.TextCtrl(panel, style=(wx.TE_MULTILINE|wx.TE_READONLY))
    hbox3.Add(tc2, proportion=1, flag=wx.EXPAND)
    vbox.Add(hbox3, proportion=1, flag=wx.LEFT|wx.RIGHT|wx.EXPAND,border=10)
    redir=RedirectText(tc2)
    sys.stdout=redir
    sys.stderr=redir


    panel.SetSizer(vbox)

def prog(self, evt):
    import os
    import shutil
    import subprocess
    from mobcal_prep import mobcal

    extension = '.pdb'
    list_of_files = [file for file in os.listdir('%s' % _selectedDir) if file.lower().endswith(extension)]

    prep = mobcal()

    for pdb in list_of_files:
        print '### Running PDB: %s ###' % pdb
        prep.new_mobcal_format(pdb)
        subprocess.call(['./EHSS_updated_atoms.out', pdb[:-4]+'_new_mobcal.mfj',pdb[:-4]+'_new_mobcal.out'])
        prep.caluclate_average('%s_new_mobcal.out' % pdb[:-4], pdb)
        subprocess.call(['rm', pdb[:-4]+'_new_mobcal.out'])

1 个答案:

答案 0 :(得分:2)

在处理图形界面时,要考虑到程序基本上是在循环中运行("主循环"),其中包括触发事件等等。这是主要的程序的线程。如果你在那个阻塞主循环一段时间的线程内做任何事情(比如调用EHSS_updated_atoms.out),那么在完成之前你的界面就不会有任何变化。

例如,您可以通过在单独的线程中运行prog函数来完成此工作。请查看this forum post以获取有关如何操作的一小段代码示例。请注意提示使用wx.Yield()wx.SafeYield()来提高界面响应能力。

编辑:忘了重定向。

您不需要重定向整个sys.stdoutsys.stderr subprocess.call只承认两个参数,因此如果您将redir传递给prog函数,则可以执行以下操作:

<击> call(.........., stdout = redir, stderr = redir)

编辑:

对于重定向,请尝试改为:

p subprocess.Popen(['./EHSS_updated_atoms.out', pdb[:-4]+'_new_mobcal.mfj',pdb[:-4]+'_new_mobcal.out'],
                   stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout:
    redir.write(line)
p.wait()