2016-12-17 41 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。我不确定这样做的最佳方法,但也许别人可以提供一个答案,告诉你如何做到这一点。