wxPython,实时捕获子进程的输出
我正在开发 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)
特别是,我需要实时输出来创建进度条。
编辑:我根据迈克·德里斯科尔的建议更改了我的代码。它有时似乎有效,但大多数时候我都会遇到以下错误之一:
(python:7698):Gtk-CRITICAL **:gtk_text_layout_real_invalidate: 断言“layout->wrap_loop_count == 0”失败
或
(python:7893):Gtk-警告 **:无效的文本缓冲区迭代器:要么 迭代器未初始化,或者字符/pixbufs/小部件 自创建迭代器以来,缓冲区已被修改。你必须 使用标记、字符号或行号来保留位置 跨缓冲区修改。您可以应用标签并插入标记 不会使你的迭代器无效,但任何影响的突变 “可索引”缓冲区内容(可以通过 字符偏移量)将使所有未完成的迭代器无效 分段错误(核心转储)
有任何线索吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题是因为您正在尝试 wx.Yield 并从运行进程的线程的上下文中更新输出小部件,而不是从 GUI 线程进行更新。
The problem is because you are trying to wx.Yield and to update the output widgets from the context of the thread running the process, instead of doing the update from the GUI thread.
Since you are running the process from a thread there should be no need to call wx.Yield, because you are not blocking the GUI thread, and so any pending UI events should be processed normally anyway.
Take a look at the wx.PyOnDemandOutputWindow class for an example of how to handle prints or other output that originate from a non-GUI thread.
这可能有点棘手,但我找到了一种方法来做到这一点,我在这里写过: http://www.blog.pythonlibrary.org/2010/06/05/python-running-ping-traceroute-and-more/
设置文本重定向后,您只需要执行以下操作:
本文也展示了如何重定向文本。希望这会有所帮助!
This can be a little tricky, but I figured out one way to do it which I wrote about here: http://www.blog.pythonlibrary.org/2010/06/05/python-running-ping-traceroute-and-more/
After you have set up the redirection of the text, you just need to do something like this:
The article shows how to redirect the text too. Hopefully that will help!