The sampled code below is for the GUI I am currently making. I have two problems. The first problem is when I redirect the python output using the RedirectText class, the output is printed on the TextCtrl box (‘tc2’) only when the loop is finished, for that particular iteration. How do I get the text to print as it goes through the loop and not when its finished?
My second problem is i’m using a compiled fortran file EHSS_updated_atoms.out the output from this file prints to the terminal and not to the text control box. How do I get the the output from the compiled fortran file to the text control box? as it is printed to the terminal.
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'])
When dealing with graphical interfaces, have into account that the program is basically running into a loop (the “main loop”), which among other things triggers events, etc. That’s the main thread of the program. If you do anything inside that thread (like calling
EHSS_updated_atoms.out) that blocks the main loop for a while, there will be no changes on your interface until that is finished.You can make this work by, for example, running the
progfunction in a separate thread. Check this forum post for a small example piece of code on how to do it. Note the hint to usewx.Yield()orwx.SafeYield()to make the interface more responsive.Edit: forgot about the redirection.
You don’t need to redirect the whole
sys.stdoutandsys.stderr.subprocess.calladmits two arguments just for that, so if you passredirto theprogfunction, you can do:call(.........., stdout = redir, stderr = redir)Edit:
For the redirection, try this instead: