使用子进程关闭图像

Close Image with subprocess

我正在尝试使用子进程打开图像以便用户可见,然后关闭图像使其消失。

以前有人问过这个问题,但我找到的答案对我没有用。这是我检查过的内容:

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()

一切都在告诉我终止 () 和 kill(),但仍然没有关闭图像。

这不需要使用预览,我也愿意听取其他选项。

编辑:我另外尝试了下面的代码,仍然没有成功

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

OS X 的 open 命令是异步的 - 它生成一个预览进程(或它启动的任何应用程序)并立即退出。因此,当您的 Python 代码开始调用 terminate()kill() 时,open 过程已完成。它不再存在。

您可以强制同步行为,即让 open 保持 运行 直到预览退出后,通过传递 -W 选项,

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

这样,当您的代码到达 运行 terminatekill 时,open 仍将是 运行。 (我建议还传递 -n 选项以确保 Preview 启动一个新实例,以防您之前有另一个 Preview 实例。)当 open 进程结束时,希望它会也结束底层的预览过程。您可以使用 pspgrep.

等流程查看器检查这是否真的发生了

如果终止或终止 open 不会终止预览,您将需要更改配置,以便在您调用 [=12= 时将信号传送到 open 的所有子进程] 或 kill(),对此 this question or this one 可能 有帮助,否则您必须找到一种方法来获取 Preview 的进程 ID 并向其发送信号直接,这将需要您超越 Popen。我不确定这样做的最佳方法,但也许其他人可以提供一个答案,向您展示如何做。

我敢肯定这是执行此操作的最 hackiest 方法,但是见鬼,它确实有效。如果有人偶然发现了这个并且知道更好的方法,请告诉我。

问题 正如 David Z 所述,我没有针对正确的过程。所以我必须弄清楚正确的进程 ID 是什么才能正确关闭它。

我首先打开终端并输入命令 ps -A。这将显示所有当前打开的进程及其 ID。然后我就搜索Preview,发现有两个打开的进程。

之前,我关闭了列表中的第一个预览 pid,我们称它为 11329,但列表中的第二个 pid 仍处于打开状态。第二个预览过程 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

这个答案看起来很脆弱,但对我有用。我才刚刚开始学习 pids,所以如果有人能提供一些知识,我将不胜感激。