2016-12-17 73 views
0

我想用子流程打開圖像,以便用戶可見,然後關閉圖像使其消失。關閉具有子流程的圖像

這個問題以前已經問過,但是我發現的答案並沒有爲我工作。以下是我已經檢查:

Killing a process created with Python's subprocess.Popen()

How to terminate a python subprocess launched with shell=True

How can I close an image shown to the user with the Python Imaging Library?

我需要的代碼打開一個圖像(預覽(可選),默認情況下在我的Mac),等一下,然後關閉圖像。

openimg = subprocess.Popen(["open", mypath]) 
time.sleep(1) 
openimg.terminate() 
openimg.kill() 

一切都告訴我要終止()和殺死(),但仍然沒有關閉圖像。

這不一定要使用預覽,我也願意聽取其他選項。

編輯:我已經試過另外下面的代碼,仍然沒有成功

print('openimg\'s pid = ',openimg.pid) 
os.kill(openimg.pid, signal.SIGKILL) 
+0

我沒有一個Mac來檢查,但我似乎記得'open'是異步的 - 它產生了一個預覽過程(或任何它啓動的應用程序)並立即退出。所以等到你的Python代碼暫時休眠了一段時間後,「open」進程就不再存在了。如果是這樣的話,我想你需要找到一些方法將信號發送到進程「open」啓動。作爲一個測試,如果你將'-W'選項傳遞給'open'(可能還有'-n'),那麼它是否工作? –

+0

感謝@DavidZ的幫助,我有點新,我不知道如何在代碼中包含'-W'或'-n'。我一直收到無效語法或文件未找到錯誤。你能給我一個它的樣子嗎? – Drake491

+0

讓我只寫一個答案。 –

回答

1

我敢肯定,這是做到這一點的最詭異的方式,但地獄,它的工作原理。如果有人絆倒在這,並知道更好的方式,請讓我知道。

問題 由於David Z描述,我沒有針對正確的過程。所以我必須弄清楚正確的進程ID是爲了正確關閉它。

我開始打開我的終端並輸入命令ps -A。這將顯示所有當前打開的進程及其ID。然後我只搜索了Preview,發現兩個打開的進程。

之前,我正在關閉列表中的第一個Preview pid,我們稱之爲11329,但列表中的第二個仍然打開。第二個預覽過程11330始終比第一個過程高出1位數。第二個是我需要關閉預覽的pid。

答案

openimg = subprocess.Popen(["open", mypath]) ##Opens the image to view 
newpid = openimg.pid + 1 ##Gets the pid 1 digit higher than the openimg pid. 
os.kill(newpid, signal.SIGKILL) ##Kills the pid and closes Preview 

這個答案似乎很脆弱,但它爲我工作。我只是剛開始學習pid,所以如果有人能提供一些知識,我會很感激。

1

OS X的open命令是異步 - 它產生一個預覽進程(或者它啓動任何應用程序),並立即退出。因此,當您的Python代碼開始調用terminate()kill()時,open過程完成。它不再存在。

您可以強制同步行爲,即讓open繼續運行,直到預覽退出後,通過傳遞-W選項,

subprocess.Popen(["open", "-W", mypath]) 

這樣,open依然會當你的代碼都繞運行terminate運行, kill。 (我建議同時傳遞-n選項以確保預覽啓動一個新實例,以防止另一個預覽實例從前開始)。當open過程結束時,希望它也會結束基礎預覽過程。您可以使用進程查看器(如pspgrep)檢查是否實際發生這種情況。

如果終止或殺死open不殺預覽,您需要更改配置,以便將信號傳送到的open所有的子進程,當你調用terminate()kill(),爲此this questionthis one可能是有用的,或者你必須找到一種方法來獲得預覽的進程ID並直接發送信號,這將需要你超越Popen。我不確定這樣做的最佳方法,但也許別人可以提供一個答案,告訴你如何做到這一點。