2009-12-12 12 views
0

我有一个Tk python程序,它在当前目录中创建一个python文件列表,并为它们中的每一个生成一个按钮。当你点击一个按钮时,相应的python程序将通过子进程在新的gnome终端中启动。在子进程在新终端上完成执行后,我想将按钮的颜色切换为红色。不幸的是,该按钮几乎立即改变颜色。在子进程完成后为按钮着色

from Tkinter import * 
import os, subprocess 

root = Tk() 
buttonsD = {} 

def launch(ourfile): 
    p=subprocess.Popen(["gnome-terminal","-e","python " + ourfile], shell=False) 
    buttonsD[ourfile].configure(bg='red') 

dirlist=os.listdir(os.getcwd()) 
for fname in dirlist: 
    if fname.endswith('py') and fname != 'gui2.py': 
     buttonsD[fname] = Button(root,text=fname,command=lambda i=fname: launch(i)) 
     buttonsD[fname].pack(side=TOP,expand=YES,fill=BOTH) 

root.mainloop() 

几乎就意味着我可以等待p.poll ==无,看到它花费的gnome-terminal要创建的时刻。但是一旦终端被创建,按钮就会变红,即使一个进程仍在新终端中运行。我无法创建一个新的gnome终端,然后传递我想要运行的进程。看起来gnome-terminal只是创建一个bash的新实例,然后返回完成,所以如果我尝试与其stdin进行通信,那么会出现管道错误。

回答

1

我相信GNOME终端正在做一个双叉,为了从它的父进程组中脱离出来 - 所以实际上你的子进程几乎立即终止,正如你观察到的,一切都在进一步的后代中发生你无法直接访问。

不幸的是,我不相信GNOME终端提供了任何方式来禁用这种双叉行为;因此,要了解“进一步后裔”何时完成,您必须定期识别该过程并对其进行监控。直接与它交互也是一个相当高的命令 - 与与您无关的任何“随机”过程进行交互相比,这并不容易:-(。

1

这里有两个问题:用于在gnome-terminal中启动Python程序的命令行,以及如何在Tkinter应用程序中使用subprocess。我只知道后者。

subprocess.Popen立即返回,这就是为什么按钮立即变红。我想你可能需要列出哪些程序正在运行。然后编写一个函数poll_processes,该函数在每个正在运行的进程上调用poll(),当结果不是None时,将其从列表中移除并将该按钮变为红色。

然后,所有你需要做的就是安排的Tkinter定期调用该函数,你可以通过调用frame.after(msec, poll_processes)第一个呼叫安排到poll_processes,然后有poll_processes做安排下一次调用同样的事情做。