2015-04-27 132 views
1

我想在python中将我的stdout打印到GUI。我正在使用Tkinter。 这是我为我工作在Python中逐行输出到GUI

def get_likes_button(): 
    output = subprocess.Popen(['python', "getLikes.py"], stdout=subprocess.PIPE) 
    s1 = output.stdout.read() 
    text.delete("1.0",END) 
    text.insert(INSERT,s1) 

但是,我得到了整个一次输出。 我想要的是GUI应该反复打印输出,就像它在终端上打印一样。

所以,我想这一点,但它给了我一个错误上点击按钮

def get_likes_button(): 
    text.delete("1.0",END) 
    with subprocess.Popen(['python', "getLikes.py"], stdout=subprocess.PIPE) as output: 
     s1 = output.stdout.read() 
     text.insert(INSERT,s1) 

的错误是

Exception in Tkinter callback 
Traceback (most recent call last): 
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__ 
return self.func(*args) 
File "gui.py", line 88, in get_likes_button 
with subprocess.Popen(['python', "getLikes.py"], stdout=subprocess.PIPE) as output: 
AttributeError: __exit__ 

能否请你建议我该怎么办?

+0

查看[这个问题](http://stackoverflow.com/q/14883648/4203871)了解如何使用线程将'stdout'重定向到窗口小部件的示例。 – chdorr

回答

2

Popen不支持上下文管理器(即with),因此错误。但是请注意,这两个版本的代码没有实际区别。

你可以改为由线读线:

def get_likes_button(): 
    child = subprocess.Popen(['python', 'getLikes.py'], stdout=subprocess.PIPE) 
    text.delete("1.0",END) 
    for line in iter(child.stdout.readline, ''): 
     text.insert(INSERT, line) 
    child.stdout.close() 
    child.wait() 

线for line in iter(child.stdout.readline, ''):用于解决如果循环已经for line in child.stdout:,将要经历的缓冲。


更新

尝试修改代码如下:

def get_likes_button(): 
    child = subprocess.Popen(['python', '-u', 'getLikes.py'], stdout=subprocess.PIPE) 
    text.delete("1.0",END) 
    for line in iter(child.stdout.readline, ''): 
     text.insert(INSERT, line) 
     text.see(END) 
     text.update_idletasks() 
    child.stdout.close() 
    child.wait() 

的变化是:

  1. 用在孩子无缓冲输出-u蟒蛇选项,
  2. 呼叫text.see(END) 每次插入后滚动文本窗口的底部,
  3. 呼叫​​给Tkinter的机会更新 文本构件。

这可能有助于避免使用线程,但其中一个缺点是在执行回调时GUI的其余部分将无响应。如果你的子进程很短,这可能是可以接受的,也许如果孩子长时间运行则可能不会 - 这取决于你的应用程序。

+0

最后2行中的'p'是什么? – ronilp

+0

@ronilp:感谢您注意,它当然应该是“孩子”。固定。 – mhawke

+0

我把getLikes.py作为'for i in range(500000): \t print i'我试着在终端和GUI上运行它。我得到了延迟输出的GUI和终端上的瞬时输出 – ronilp

1

我不认为subprocess.Popen可用于with条款。我想check_output是你所需要的:

output = subprocess.check_output(['python', 'getLikes.py']) 
+0

所以你的意思是我应该用subprocess.check_output(['python',“getLikes.py”,stdout = subprocess.PIPE)作为输出:''? – ronilp

+0

当我试图得到这个错误:stdout参数不允许,它将被覆盖。 – ronilp

+0

不可以不可以'带'条款。只是这个。 – skyline75489