我正在使用wxPython中的应用程序,它是命令行实用程序的GUI。在GUI中有一个文本控件,它应该显示应用程序的输出。我正在使用子进程启动shell命令,但是在完成之前我没有得到任何输出。
我尝试了几种解决方案,但似乎都没有。下面是我正在使用的代码(更新):
def onOk(self,event):
self.getControl('infotxt').Clear()
try:
thread = threading.Thread(target=self.run)
thread.setDaemon(True)
thread.start()
except Exception:
print 'Error starting thread'
def run(self):
args = dict()
# creating a command to execute...
cmd = ["aplcorr", "-vvfile", args['vvfile'], "-navfile", args['navfile'], "-lev1file", args['lev1file'], "-dem", args['dem'], "-igmfile", args['outfile']]
proc = subprocess.Popen(' '.join(cmd), shell=True, stdout=subprocess.PIPE, stderr.subprocess.PIPE)
print
while True:
line = proc.stdout.readline()
wx.Yield()
if line.strip() == "":
pass
else:
print line.strip()
if not line: break
proc.wait()
class RedirectInfoText:
""" Class to redirect stdout text """
def __init__(self,wxTextCtrl):
self.out=wxTextCtrl
def write(self,string):
self.out.WriteText(string)
class RedirectErrorText:
""" Class to redirect stderr text """
def __init__(self,wxTextCtrl):
self.out.SetDefailtStyle(wx.TextAttr())
self.out=wxTextCtrl
def write(self,string):
self.out.SetDefaultStyle(wx.TextAttr(wx.RED))
self.out.WriteText(string)
特别是我需要实时输出来创建进度条。
编辑:根据Mike Driscoll的建议改变了我的代码。它似乎有时工作,但大多数时候我得到以下错误之一:
(python:7698):Gtk-CRITICAL **:gtk_text_layout_real_invalidate: 断言`layout-> wrap_loop_count == 0'失败
或
(python:7893):Gtk-WARNING **:无效的文本缓冲区迭代器:要么 迭代器是未初始化的,或者是字符/ pixbufs / widgets 自迭代器创建以来,缓冲区已被修改。你必须 使用标记,字符数或行号来保留位置 跨缓冲区修改。您可以应用标签和插入标记 不会使迭代器失效,但会影响任何突变 'indexable'缓冲区内容(可以引用的内容) 字符偏移量)将使所有未完成的迭代器无效 分段错误(核心转储)
任何线索?
答案 0 :(得分:2)
问题是因为您正在尝试wx.Yield并从运行该进程的线程的上下文更新输出窗口小部件,而不是从GUI线程进行更新。
由于您从一个线程运行该进程,因此不需要调用wx.Yield,因为您没有阻止GUI线程,因此任何挂起的UI事件都应该正常处理。
查看wx.PyOnDemandOutputWindow类,了解如何处理源自非GUI线程的打印件或其他输出的示例。
答案 1 :(得分:1)
这可能有点棘手,但我找到了一种方法,我在这里写到:http://www.blog.pythonlibrary.org/2010/06/05/python-running-ping-traceroute-and-more/
设置文本的重定向后,您只需要执行以下操作:
def pingIP(self, ip):
proc = subprocess.Popen("ping %s" % ip, shell=True,
stdout=subprocess.PIPE)
print
while True:
line = proc.stdout.readline()
wx.Yield()
if line.strip() == "":
pass
else:
print line.strip()
if not line: break
proc.wait()
本文介绍了如何重定向文本。希望这会有所帮助!