首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要帮助从python项目中的pygtk GUI实时捕获STDOUT

需要帮助从python项目中的pygtk GUI实时捕获STDOUT
EN

Stack Overflow用户
提问于 2011-05-06 15:44:51
回答 3查看 1.4K关注 0票数 1

我正在进行一个项目,在这个项目中,我希望使用来自python的命令行实用工具cdparanoia。我正在使用Glade进行UI开发。我尝试过导入子进程并使用subprocess.Popen。它工作,但它冻结了我的GUI (甚至不允许重新绘制窗口),而进程正在执行。对用户来说不是很好的交互。我怎样才能防止这种行为?我想把一个取消按钮在窗口,但这将工作,因为它“冻结”的程序。最终,我想捕获stderr (如下所示,音频信息通过stdout管道传输到sox ),并将其作为一个gtk.Expander呈现出来,其外观与Synaptic类似,当它安装一个程序时,用户可以实时地看到发生的事情。另外,我想使用进度指示器(如下面所示)的文本来构建一个真正的进度指标小部件。如何让shell实时地将信息传递回python,而不是在进程完成后(当它将所有信息作为一个大的信息转储)?

需要捕获的实时信息:

代码语言:javascript
复制
Working on me - me - DISK 01.flac
cdparanoia III release 10.2 (September 11, 2008)

Ripping from sector       0 (track  1 [0:00.00])
      to sector  325195 (track 15 [1:56.70])

outputting to stdout

 (== PROGRESS == [>                             | 004727 00 ] == :-) O ==)

下面是我到目前为止使用的代码:

代码语言:javascript
复制
        quick = " -Z" if self.quick == True else ""
        command = "cdparanoia -w%s 1- -| sox -t wav - \"%s - %s - DISK %s%s.flac\"" %\
                    (
                        quick,
                        self.book_name.replace(" ", "_"),
                        self.author_name.replace(" ", "_"),
                        "0" if disc < 10 else "", 
                        disc
                    )
        print command
        shell = subprocess.Popen(command, shell=True, executable="/bin/bash",
                                    stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE
                                )
        data, err = shell.communicate(command)

谢谢你,娜妮

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-05-06 15:55:49

我写了一次Python实现,它运行了wget和实际的Python,输出功能齐全。

您需要使用subprocess.Popen并直接写入sys.stdout

代码语言:javascript
复制
process = subprocess.Popen(shlex.split(command), stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
complete = False

while True:
  output = process.stdout.read(1)

  if output == '' and process.poll() != None:
    break

  if output != '':
    sys.stdout.write(output)
    sys.stdout.flush()
票数 2
EN

Stack Overflow用户

发布于 2011-05-06 16:05:14

如果您编写了一个从文件句柄读取的GUI程序,那么有两个程序使用dispatcher将文件描述符事件集成到GUI事件循环中。事件循环的一般描述可以在维基百科上找到。Gtk+的具体描述可以在参考文献中找到。

解决问题的方法:使用函数g_io_add_watch将您的操作集成到主事件循环中。这里是C中的一个例子,Python应该类似。

票数 1
EN

Stack Overflow用户

发布于 2011-05-09 09:33:31

是的,这里有两个问题。首先,您需要指定一个读取超时,以便在子进程完成之前不会阻塞。第二种情况是,可能出现了一些不可取的缓冲现象。

为了解决第一个问题,并异步地从子进程读取,您可以尝试我的subProcess模块,只需超时:http://www.pixelbeat.org/libs/subProcess.py注释--这很简单,但也很老,而且仅限于linux。它被用作新python子流程模块的基础,因此,如果需要可移植性,您最好使用它。

若要了解/控制可能发生的任何附加缓冲,请参见:缓冲/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5913794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档