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 == None,并看到创建 gnome-terminal 需要一些时间。但是一旦创建了终端,按钮就会变成红色,即使一个进程仍在新终端中运行。我无法创建一个新的 gnome 终端,然后传达我想要运行的进程。似乎 gnome-terminal 只是创建了一个新的 bash 实例,然后返回完成,所以如果我尝试与其标准输入通信,则会出现管道错误。

4

2 回答 2

1

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

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

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

于 2009-12-12T17:08:24.163 回答
1

我相信 gnome 终端正在做一个双重分叉,以便将自己与其父进程组分离 - 所以实际上你的子进程几乎立即终止,正如你所观察到的那样,一切都发生在你没有直接的后代中进入。

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

于 2009-12-12T17:20:51.917 回答