2009-12-12 52 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做安排下一次調用同樣的事情做。