如何使用python脚本打开和关闭另一个应用程序?

时间:2018-04-09 21:32:29

标签: macos python-2.7 subprocess

我想在预览中打开一个现有的pdf,在TextEdit中打开一个文本文件(可以编辑或不编辑),等待一些输入,然后关闭两个窗口(让流程重复)。

在Mac OS上执行此操作的最佳方法是什么? subprocess.call(['open', '-a', 'TextEdit', filename])工作正常,但我不确定如何终止用户输入的过程。

编辑:我正在打开这个过程:

txt=subprocess.Popen(['open','-a','/Applications/TextEdit.app/','path_filename'])
user_input = raw_input("Continue? Enter 'quit' to exit")
txt.kill()  # nothing happens
if user_input.lower() == 'quit':
    break

2 个答案:

答案 0 :(得分:1)

更新了答案

从您的评论中,似乎Python应用程序实际上并不需要知道用户检查PDF的结果,只需知道他何时完成检查。

AFAIK,最简单的方法是使用TextEdit的脚本功能,每隔一秒左右向它询问一个打开文档的列表。然后你可以等到用户关闭你为他打开的文档,它将从列表中消失。

脚本看起来像这样,名为GetTextEditDocumentList

#!/bin/bash
osascript -e 'tell app "TextEdit" to get documents'

它将在stdout上打印一个打开文档列表,您可以使用Python读取它。或者你可以传递一个文件名作为参数,它可以循环,比如在中间延迟1秒,直到该文件/文件不再打开。

您可以在使用TextEdit打开和关闭一些文档时在终端中尝试它,看看它是如何工作的。

原始答案

当文本输入对话框可能更合适时,您似乎正在尝试使用TextEdit获取有关预览中可见的PDF的文本(可能是注释)。

虽然您可以安装并强制任何用户安装TkinterwxPython,但您实际上可以非常简单地使用已经内置到macOS中的Applescript而无需安装任何内容。

因此,将以下内容保存为dialog

#!/bin/bash
input=$(osascript <<EOF
tell application "System Events" 
   display dialog "Enter something:" default answer "Some default answer" with title "Gimme da thing" buttons {"Okey dokey"}
end tell
EOF
)
echo $input

使用以下内容使其可执行:

chmod +x dialog

然后会弹出如下对话框:

enter image description here

输出是:

./dialog 
button returned:Okey dokey, text returned:No, I refuse

然后你可以使用:

从Python中调用它
subprocess.Popen(['dialog'],stdout=subprocess.PIPE)

当然,如果您需要比我制作的静态标题更灵活,您可以参数化标题,提示和默认文本并将其传递给脚本。

答案 1 :(得分:0)

据我所知,你想要实现的目标是不可能的。这是除非您能找到一种方法来捕获外部程序中的角色事件。

我建议您在Python中创建自己的GUI(图形用户界面),例如通过wxPython,然后在其中嵌入wx.TextCtrl,这样您就可以获得更多控制权(例如,很容易捕获多种类型的KeyEvents)。

但是,要在您的示例中关闭应用程序,我会执行以下操作:

retrieve_pid_1 = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
retrieve_pid_2 = subprocess.Popen(['grep', '-m1', 'TextEdit'], stdin=retrieve_pid_1.stdout, stdout=subprocess.PIPE)
retrieve_pid_3 = subprocess.Popen(['awk', '{print $1}'], stdin=retrieve_pid_2.stdout, stdout=subprocess.PIPE)
process_number = retrieve_pid_3.communicate()[0].decode('ASCII').rstrip()
kill_process = subprocess.Popen(['kill', process_number])